import {
  Button,
  Description,
  Input,
  Label,
  Modal,
  Separator,
  Switch,
} from "@heroui/react";
import { useEffect, useState } from "react";
import { normalizeTld } from "@/lib/tld-pricing";
import { ADMIN_SELECT } from "./styles";

const CATEGORY_CHOICES = [
  { value: "generic", label: "Generic (gTLD)" },
  { value: "country", label: "Country code (ccTLD)" },
  { value: "sponsored", label: "Sponsored" },
  { value: "brand", label: "Brand" },
];

const OFFERS = [
  {
    key: "registration",
    title: "Cheapest registration",
    hint: "The first-year price shown in the Registration column.",
  },
  {
    key: "renewal",
    title: "Cheapest renewal",
    hint: "The yearly renewal price after the first term.",
  },
  {
    key: "transfer",
    title: "Cheapest transfer",
    hint: "The price to move an existing domain to this registrar.",
  },
];

const FEATURES = [
  { key: "dnssec", label: "DNSSEC" },
  { key: "idn", label: "IDN" },
  { key: "trustee", label: "Trustee" },
  { key: "privacy", label: "Privacy" },
];

const emptyOffer = () => ({
  registrar: "",
  price: "",
  listPrice: "",
  coupon: "",
  url: "",
});

const emptyRow = () => ({
  tld: "",
  unicode: "",
  category: "generic",
  enabled: true,
  featured: false,
  popularity: 0,
  currency: "USD",
  note: "",
  registration: emptyOffer(),
  renewal: emptyOffer(),
  transfer: emptyOffer(),
  bestValue: { registrar: "", registration: "", renewal: "", url: "" },
  features: { dnssec: false, idn: false, trustee: false, privacy: false },
});

// Numbers come back from the API as null; the inputs want "".
const toInput = (value) =>
  value === null || value === undefined ? "" : String(value);

function toForm(row) {
  if (!row) return emptyRow();
  const base = emptyRow();
  const offer = (key) => ({
    registrar: row[key]?.registrar || "",
    price: toInput(row[key]?.price),
    listPrice: toInput(row[key]?.listPrice),
    coupon: row[key]?.coupon || "",
    url: row[key]?.url || "",
  });

  return {
    ...base,
    ...row,
    tld: row.tld || "",
    unicode: row.unicode || "",
    category: row.category || "generic",
    enabled: row.enabled !== false,
    featured: row.featured === true,
    popularity: toInput(row.popularity ?? 0),
    currency: row.currency || "USD",
    note: row.note || "",
    registration: offer("registration"),
    renewal: offer("renewal"),
    transfer: offer("transfer"),
    bestValue: {
      registrar: row.bestValue?.registrar || "",
      registration: toInput(row.bestValue?.registration),
      renewal: toInput(row.bestValue?.renewal),
      url: row.bestValue?.url || "",
    },
    features: { ...base.features, ...(row.features || {}) },
  };
}

const selectClass = ADMIN_SELECT;

export default function EditModal({
  isOpen,
  onOpenChange,
  row,
  registrars,
  onSave,
  loading,
}) {
  const isNew = !row;
  const [form, setForm] = useState(emptyRow);

  // Re-seed the form every time the modal is opened for a different TLD.
  useEffect(() => {
    if (isOpen) setForm(toForm(row));
  }, [isOpen, row]);

  const set = (field, value) => setForm((p) => ({ ...p, [field]: value }));

  const setOffer = (group, field, value) =>
    setForm((p) => ({ ...p, [group]: { ...p[group], [field]: value } }));

  const setFeature = (key, value) =>
    setForm((p) => ({ ...p, features: { ...p.features, [key]: value } }));

  const handleSave = () => onSave({ ...form, tld: normalizeTld(form.tld) });

  const registrarOptions = Object.values(registrars || {});

  const registrarSelect = (value, onChange) => (
    <select
      value={value}
      onChange={(e) => onChange(e.target.value)}
      className={selectClass}
    >
      <option value="">— none —</option>
      {registrarOptions.map((r) => (
        <option key={r.key} value={r.key}>
          {r.name}
        </option>
      ))}
    </select>
  );

  return (
    <Modal>
      <Modal.Backdrop isOpen={isOpen} onOpenChange={onOpenChange} isDismissable>
        <Modal.Container>
          <Modal.Dialog className="max-w-3xl">
            <Modal.Header>
              <Modal.Heading>
                {isNew ? "Add TLD" : `Edit .${row?.tld}`}
              </Modal.Heading>
            </Modal.Header>
            <Modal.CloseTrigger />
            <Separator />

            <Modal.Body className="max-h-[65vh] overflow-y-auto">
              <div className="flex flex-col gap-6">
                {/* Identity */}
                <section className="grid grid-cols-1 gap-4 md:grid-cols-2">
                  <div className="flex flex-col gap-1">
                    <Label>TLD</Label>
                    <Input
                      variant="secondary"
                      type="text"
                      value={form.tld}
                      onChange={(e) => set("tld", e.target.value)}
                      isDisabled={!isNew}
                      placeholder="com"
                    />
                    <Description>
                      Without the dot. Cannot be changed after it is created.
                    </Description>
                  </div>

                  <div className="flex flex-col gap-1">
                    <Label>Display label</Label>
                    <Input
                      variant="secondary"
                      type="text"
                      value={form.unicode}
                      onChange={(e) => set("unicode", e.target.value)}
                      placeholder="Leave empty for non-IDN extensions"
                    />
                    <Description>
                      Unicode form shown in the table, e.g. 中国 for xn--fiqs8s.
                    </Description>
                  </div>

                  <div className="flex flex-col gap-1">
                    <Label>Category</Label>
                    <select
                      value={form.category}
                      onChange={(e) => set("category", e.target.value)}
                      className={selectClass}
                    >
                      {CATEGORY_CHOICES.map((c) => (
                        <option key={c.value} value={c.value}>
                          {c.label}
                        </option>
                      ))}
                    </select>
                  </div>

                  <div className="flex flex-col gap-1">
                    <Label>Popularity</Label>
                    <Input
                      variant="secondary"
                      type="number"
                      min="0"
                      max="5"
                      value={form.popularity}
                      onChange={(e) => set("popularity", e.target.value)}
                    />
                    <Description>
                      0–5. Drives the default ordering of the public table.
                    </Description>
                  </div>
                </section>

                <Separator />

                {/* Prices */}
                {OFFERS.map((offer) => (
                  <section key={offer.key} className="flex flex-col gap-3">
                    <div>
                      <h5 className="text-sm font-semibold tracking-wide text-gray-700 uppercase">
                        {offer.title}
                      </h5>
                      <p className="text-xs text-gray-500">{offer.hint}</p>
                    </div>

                    <div className="grid grid-cols-1 gap-4 md:grid-cols-4">
                      <div className="flex flex-col gap-1">
                        <Label>Registrar</Label>
                        {registrarSelect(form[offer.key].registrar, (v) =>
                          setOffer(offer.key, "registrar", v),
                        )}
                      </div>

                      <div className="flex flex-col gap-1">
                        <Label>Price</Label>
                        <Input
                          variant="secondary"
                          type="number"
                          step="0.01"
                          min="0"
                          value={form[offer.key].price}
                          onChange={(e) =>
                            setOffer(offer.key, "price", e.target.value)
                          }
                          placeholder="9.98"
                        />
                      </div>

                      <div className="flex flex-col gap-1">
                        <Label>Regular price</Label>
                        <Input
                          variant="secondary"
                          type="number"
                          step="0.01"
                          min="0"
                          value={form[offer.key].listPrice}
                          onChange={(e) =>
                            setOffer(offer.key, "listPrice", e.target.value)
                          }
                          placeholder="Struck through"
                        />
                      </div>

                      <div className="flex flex-col gap-1">
                        <Label>Coupon</Label>
                        <Input
                          variant="secondary"
                          type="text"
                          value={form[offer.key].coupon}
                          onChange={(e) =>
                            setOffer(offer.key, "coupon", e.target.value)
                          }
                          placeholder="SAVE10"
                        />
                      </div>
                    </div>

                    <div className="flex flex-col gap-1">
                      <Label>Affiliate link override</Label>
                      <Input
                        variant="secondary"
                        type="text"
                        value={form[offer.key].url}
                        onChange={(e) =>
                          setOffer(offer.key, "url", e.target.value)
                        }
                        placeholder="Leave empty to use the registrar's default link"
                      />
                    </div>
                  </section>
                ))}

                <Separator />

                {/* Best value */}
                <section className="flex flex-col gap-3">
                  <div>
                    <h5 className="text-sm font-semibold tracking-wide text-gray-700 uppercase">
                      Best long-term value
                    </h5>
                    <p className="text-xs text-gray-500">
                      The registrar that works out cheapest once you count the
                      renewals, shown in the last column.
                    </p>
                  </div>

                  <div className="grid grid-cols-1 gap-4 md:grid-cols-3">
                    <div className="flex flex-col gap-1">
                      <Label>Registrar</Label>
                      {registrarSelect(form.bestValue.registrar, (v) =>
                        setOffer("bestValue", "registrar", v),
                      )}
                    </div>
                    <div className="flex flex-col gap-1">
                      <Label>Registration</Label>
                      <Input
                        variant="secondary"
                        type="number"
                        step="0.01"
                        min="0"
                        value={form.bestValue.registration}
                        onChange={(e) =>
                          setOffer("bestValue", "registration", e.target.value)
                        }
                      />
                    </div>
                    <div className="flex flex-col gap-1">
                      <Label>Renewal</Label>
                      <Input
                        variant="secondary"
                        type="number"
                        step="0.01"
                        min="0"
                        value={form.bestValue.renewal}
                        onChange={(e) =>
                          setOffer("bestValue", "renewal", e.target.value)
                        }
                      />
                    </div>
                  </div>

                  <div className="flex flex-col gap-1">
                    <Label>Affiliate link override</Label>
                    <Input
                      variant="secondary"
                      type="text"
                      value={form.bestValue.url}
                      onChange={(e) =>
                        setOffer("bestValue", "url", e.target.value)
                      }
                      placeholder="Leave empty to use the registrar's default link"
                    />
                  </div>
                </section>

                <Separator />

                {/* Registry features */}
                <section className="flex flex-col gap-3">
                  <h5 className="text-sm font-semibold tracking-wide text-gray-700 uppercase">
                    Registry features
                  </h5>
                  <div className="flex flex-wrap gap-6">
                    {FEATURES.map((f) => (
                      <div key={f.key} className="flex items-center gap-3">
                        <Switch
                          isSelected={form.features[f.key] === true}
                          onChange={(v) => setFeature(f.key, v)}
                        >
                          <Switch.Content>
                            <Switch.Control
                              className={`h-[26px] w-[44px] ${form.features[f.key] ? "bg-cyan-500" : "bg-gray-300"}`}
                            >
                              <Switch.Thumb
                                className={`size-[22px] bg-white shadow-sm ${form.features[f.key] ? "ms-[18px]" : ""}`}
                              />
                            </Switch.Control>
                          </Switch.Content>
                        </Switch>
                        <Label>{f.label}</Label>
                      </div>
                    ))}
                  </div>
                </section>

                <Separator />

                {/* Visibility */}
                <section className="flex flex-col gap-4">
                  <div className="grid grid-cols-1 gap-4 md:grid-cols-2">
                    <div className="flex flex-col gap-1">
                      <Label>Currency code</Label>
                      <Input
                        variant="secondary"
                        type="text"
                        value={form.currency}
                        onChange={(e) => set("currency", e.target.value)}
                        placeholder="USD"
                      />
                    </div>
                    <div className="flex flex-col gap-1">
                      <Label>Note</Label>
                      <Input
                        variant="secondary"
                        type="text"
                        value={form.note}
                        onChange={(e) => set("note", e.target.value)}
                        placeholder="Internal note, e.g. registry restrictions"
                      />
                    </div>
                  </div>

                  <div className="flex flex-wrap gap-8">
                    <div className="flex items-center gap-3">
                      <Switch
                        isSelected={form.enabled === true}
                        onChange={(v) => set("enabled", v)}
                      >
                        <Switch.Content>
                          <Switch.Control
                            className={`h-[26px] w-[44px] ${form.enabled ? "bg-cyan-500" : "bg-gray-300"}`}
                          >
                            <Switch.Thumb
                              className={`size-[22px] bg-white shadow-sm ${form.enabled ? "ms-[18px]" : ""}`}
                            />
                          </Switch.Control>
                        </Switch.Content>
                      </Switch>
                      <div className="flex flex-col">
                        <Label>Show on the public table</Label>
                        <Description>
                          Turn off to hide this extension from visitors.
                        </Description>
                      </div>
                    </div>

                    <div className="flex items-center gap-3">
                      <Switch
                        isSelected={form.featured === true}
                        onChange={(v) => set("featured", v)}
                      >
                        <Switch.Content>
                          <Switch.Control
                            className={`h-[26px] w-[44px] ${form.featured ? "bg-cyan-500" : "bg-gray-300"}`}
                          >
                            <Switch.Thumb
                              className={`size-[22px] bg-white shadow-sm ${form.featured ? "ms-[18px]" : ""}`}
                            />
                          </Switch.Control>
                        </Switch.Content>
                      </Switch>
                      <div className="flex flex-col">
                        <Label>Featured</Label>
                        <Description>Highlight this extension.</Description>
                      </div>
                    </div>
                  </div>
                </section>
              </div>
            </Modal.Body>

            <Separator />
            <Modal.Footer>
              <Button
                onPress={handleSave}
                isPending={loading}
                isDisabled={!normalizeTld(form.tld)}
              >
                Save
              </Button>
              <Button slot="close" variant="tertiary">
                Cancel
              </Button>
            </Modal.Footer>
          </Modal.Dialog>
        </Modal.Container>
      </Modal.Backdrop>
    </Modal>
  );
}
