"use client";

import type { Brand, CloudflareAccount, Domain, DomainPurpose, Region, RegistrarAccount, ServerAccount } from "@domainops/shared-types";
import { App, Form, Input, Modal, Select } from "antd";
import { useEffect, useState } from "react";
import { listBrands, listRegions, updateDomain } from "@/lib/api/domains";
import { listCloudflareAccounts } from "@/lib/api/cloudflare";
import { listRegistrars } from "@/lib/api/acquire";
import { listServerAccounts } from "@/lib/api/servers";
import { ApiError } from "@/lib/api/client";
import { PURPOSE_OPTIONS } from "@/lib/utils/domainFields";
import { serverAccountLabel } from "@/lib/utils/server";

interface EditDomainFormValues {
  brand_id?: number;
  project_brand_id?: number;
  region_id?: number;
  cf_account_id?: number;
  registrar_account_id?: number;
  server_account_id?: number;
  purpose?: DomainPurpose;
  notes?: string;
}

interface EditOptions {
  brands: Brand[];
  regions: Region[];
  cloudflareAccounts: CloudflareAccount[];
  registrars: RegistrarAccount[];
  serverAccounts: ServerAccount[];
}

const OPTIONS_TTL_MS = 60_000;
let optionsCache: { loadedAt: number; promise: Promise<EditOptions> } | null = null;

/**
 * The five lookup lists load in parallel and are shared across opens for a
 * minute, so reopening the popup on another row is instant instead of
 * re-fetching everything each time.
 */
function loadOptions(): Promise<EditOptions> {
  if (optionsCache && Date.now() - optionsCache.loadedAt < OPTIONS_TTL_MS) return optionsCache.promise;

  const promise = Promise.all([
    listBrands(),
    listRegions(),
    listCloudflareAccounts(),
    listRegistrars(),
    listServerAccounts(),
  ]).then(([brands, regions, cloudflareAccounts, registrars, serverAccounts]) => ({
    brands,
    regions,
    cloudflareAccounts,
    registrars: registrars.accounts,
    serverAccounts,
  }));

  optionsCache = { loadedAt: Date.now(), promise };
  promise.catch(() => {
    optionsCache = null;
  });

  return promise;
}

/**
 * Edit-via-popup for the Domain Inventory list - saves records only (same
 * PATCH /domains/{id} the detail page uses); nothing here provisions or
 * syncs to the server, Cloudflare, or registrar.
 */
export function EditDomainModal({
  open,
  domain,
  onClose,
  onSaved,
}: {
  open: boolean;
  domain: Domain | null;
  onClose: () => void;
  onSaved: (domain: Domain) => void;
}) {
  const { message } = App.useApp();
  const [form] = Form.useForm<EditDomainFormValues>();
  const [options, setOptions] = useState<EditOptions | null>(null);
  const [isSubmitting, setIsSubmitting] = useState(false);

  useEffect(() => {
    if (!open) return;
    let cancelled = false;
    loadOptions()
      .then((loaded) => {
        if (!cancelled) setOptions(loaded);
      })
      .catch(() => message.error("Couldn't load the option lists."));

    return () => {
      cancelled = true;
    };
  }, [open, message]);

  async function handleSubmit(values: EditDomainFormValues) {
    if (!domain) return;
    setIsSubmitting(true);
    try {
      const updated = await updateDomain(domain.id, { ...values, project_brand_id: values.project_brand_id ?? null });
      optionsCache = null;
      message.success(`${domain.fqdn} saved.`);
      onSaved(updated);
    } catch (err) {
      message.error(err instanceof ApiError ? err.message : "Couldn't update that domain.");
    } finally {
      setIsSubmitting(false);
    }
  }

  const isLoadingOptions = options === null;
  const selectedProjectId = Form.useWatch("brand_id", form);

  return (
    <Modal
      title={domain ? `Edit ${domain.fqdn}` : "Edit Domain"}
      open={open}
      onCancel={onClose}
      onOk={() => form.submit()}
      confirmLoading={isSubmitting}
      okText="Save"
      destroyOnHidden
      className="dms_edit_domain_modal"
    >
      <Form<EditDomainFormValues>
        form={form}
        layout="vertical"
        onFinish={handleSubmit}
        initialValues={{
          brand_id: domain?.brand_id ?? undefined,
          project_brand_id: domain?.project_brand_id ?? undefined,
          region_id: domain?.region_id ?? undefined,
          cf_account_id: domain?.cf_account_id ?? undefined,
          registrar_account_id: domain?.registrar_account_id ?? undefined,
          server_account_id: domain?.server_account_id ?? undefined,
          purpose: domain?.purpose ?? undefined,
          notes: domain?.notes ?? undefined,
        }}
        className="dms_edit_domain_form"
      >
        <Form.Item name="brand_id" label="Project" className="dms_edit_domain_brand_field">
          <Select
            allowClear
            showSearch
            optionFilterProp="label"
            loading={isLoadingOptions}
            placeholder="Select a project"
            onChange={() => form.setFieldValue("project_brand_id", undefined)}
            options={(options?.brands ?? []).map((b) => ({ value: b.id, label: b.name }))}
          />
        </Form.Item>
        <Form.Item name="project_brand_id" label="Brand" className="dms_edit_domain_project_brand_field">
          <Select
            allowClear
            showSearch
            optionFilterProp="label"
            loading={isLoadingOptions}
            disabled={!selectedProjectId}
            placeholder={selectedProjectId ? "Select a brand" : "Pick a project first"}
            options={(options?.brands.find((b) => b.id === selectedProjectId)?.project_brands ?? []).map((b) => ({ value: b.id, label: b.name }))}
          />
        </Form.Item>
        <Form.Item name="region_id" label="Region" className="dms_edit_domain_region_field">
          <Select
            allowClear
            loading={isLoadingOptions}
            placeholder="Select a region"
            options={(options?.regions ?? []).map((r) => ({ value: r.id, label: `${r.name} (${r.country_code})` }))}
          />
        </Form.Item>
        <Form.Item name="server_account_id" label="Held At (Server & Account)" className="dms_edit_domain_server_account_field">
          <Select
            allowClear
            showSearch
            optionFilterProp="label"
            loading={isLoadingOptions}
            placeholder="Pick a server account"
            options={(options?.serverAccounts ?? []).map((a) => ({ value: a.id, label: serverAccountLabel(a) }))}
          />
        </Form.Item>
        <Form.Item name="cf_account_id" label="Cloudflare Account" className="dms_edit_domain_cf_account_field">
          <Select
            allowClear
            showSearch
            optionFilterProp="label"
            loading={isLoadingOptions}
            placeholder="Link a Cloudflare account"
            options={(options?.cloudflareAccounts ?? []).map((a) => ({ value: a.id, label: a.label }))}
          />
        </Form.Item>
        <Form.Item name="registrar_account_id" label="Registrar Account" className="dms_edit_domain_registrar_account_field">
          <Select
            allowClear
            showSearch
            optionFilterProp="label"
            loading={isLoadingOptions}
            placeholder="Pick a registrar account"
            options={(options?.registrars ?? []).map((r) => ({ value: r.id, label: r.label }))}
          />
        </Form.Item>
        <Form.Item name="purpose" label="Type" className="dms_edit_domain_purpose_field">
          <Select allowClear placeholder="Select a type" options={PURPOSE_OPTIONS} />
        </Form.Item>
        <Form.Item name="notes" label="Notes" className="dms_edit_domain_notes_field">
          <Input.TextArea rows={2} />
        </Form.Item>
      </Form>
    </Modal>
  );
}
