"use client";

import type { Domain } from "@domainops/shared-types";
import { App, Modal, Select, Spin } from "antd";
import { useCallback, useEffect, useRef, useState } from "react";
import { getDomain, listDomains } from "@/lib/api/domains";
import { ApiError } from "@/lib/api/client";
import { RedirectPanel } from "../domains/[id]/RedirectPanel";

interface DomainOption {
  value: number;
  label: string;
  disabled: boolean;
}

function toOptions(domains: Domain[]): DomainOption[] {
  return domains.flatMap((domain) => [domain, ...(domain.subdomains ?? [])]).map((domain) => ({
    value: domain.id,
    label: domain.cf_zone_id ? domain.fqdn : `${domain.fqdn} (no Cloudflare)`,
    disabled: !domain.cf_zone_id,
  }));
}

/**
 * Manage one domain's redirects without leaving the Redirects list. With a
 * domainId it opens straight on that domain; without one it first asks which
 * domain from Domain Inventory (subdomains included) to add a redirect to.
 */
export function RedirectQuickEditModal({
  open,
  domainId,
  onClose,
  onChanged,
}: {
  open: boolean;
  domainId: number | null;
  onClose: () => void;
  onChanged: () => void;
}) {
  const { message } = App.useApp();
  const [pickedId, setPickedId] = useState<number | null>(null);
  const [domain, setDomain] = useState<Domain | null>(null);
  const [options, setOptions] = useState<DomainOption[]>([]);
  const [isSearching, setIsSearching] = useState(false);
  const searchTimer = useRef<ReturnType<typeof setTimeout> | null>(null);
  const effectiveId = domainId ?? pickedId;

  const load = useCallback(
    async (id: number) => {
      try {
        setDomain(await getDomain(id));
      } catch (err) {
        message.error(err instanceof ApiError ? err.message : "Couldn't load that domain.");
      }
    },
    [message],
  );

  const search = useCallback(async (term: string) => {
    setIsSearching(true);
    try {
      const result = await listDomains({ search: term, page: 1 });
      setOptions(toOptions(result.data));
    } finally {
      setIsSearching(false);
    }
  }, []);

  useEffect(() => {
    if (!open) return;
    // eslint-disable-next-line react-hooks/set-state-in-effect
    setPickedId(null);
    setDomain(null);
    if (domainId === null) void search("");
  }, [open, domainId, search]);

  useEffect(() => {
    // eslint-disable-next-line react-hooks/set-state-in-effect
    setDomain(null);
    if (open && effectiveId !== null) void load(effectiveId);
  }, [open, effectiveId, load]);

  function handleSearch(term: string) {
    if (searchTimer.current) clearTimeout(searchTimer.current);
    searchTimer.current = setTimeout(() => void search(term), 300);
  }

  return (
    <Modal
      title={domain ? `Manage redirect - ${domain.fqdn}` : domainId === null ? "Add Redirect" : "Manage redirect"}
      open={open}
      onCancel={onClose}
      footer={null}
      destroyOnHidden
      width={640}
      className="dms_redirect_quick_edit_modal"
    >
      {domainId === null && (
        <Select<number>
          showSearch
          filterOption={false}
          value={pickedId ?? undefined}
          placeholder="Pick a domain or subdomain from Domain Inventory"
          loading={isSearching}
          options={options}
          onSearch={handleSearch}
          onChange={setPickedId}
          style={{ width: "100%", marginBottom: 16 }}
          className="dms_redirect_quick_edit_domain_select"
        />
      )}
      {effectiveId !== null &&
        (domain ? (
          <RedirectPanel
            domain={domain}
            onUpdated={() => {
              void load(domain.id);
              onChanged();
            }}
          />
        ) : (
          <div className="flex justify-center py-8">
            <Spin />
          </div>
        ))}
    </Modal>
  );
}
