import { useEffect, useState, type ReactNode } from "react";
import type { DnsRecord } from "../types";
import { RECORD_TYPES } from "../constants";
import { useDomainflare } from "../context/DomainflareContext";

type Props = {
  open: boolean;
  mode: "create" | "edit";
  record: DnsRecord | null;
  zoneId: string | null;
  onClose: () => void;
  onSaved: () => Promise<void>;
};

/** 右侧抽屉：新建 / 编辑 DNS 记录（沿用原版表单逻辑） */
export function DnsRecordDrawer({
  open,
  mode,
  record,
  zoneId,
  onClose,
  onSaved,
}: Props) {
  const { cf, toast } = useDomainflare();

  const [recType, setRecType] = useState("A");
  const [name, setName] = useState("");
  const [ttl, setTtl] = useState("1");
  const [comment, setComment] = useState("");
  const [proxWrap, setProxWrap] = useState(false);
  const [proxied, setProxied] = useState(false);
  const [content, setContent] = useState("");
  const [mxTarget, setMxTarget] = useState("");
  const [mxPrio, setMxPrio] = useState("10");
  const [srvPrio, setSrvPrio] = useState("10");
  const [srvWeight, setSrvWeight] = useState("10");
  const [srvPort, setSrvPort] = useState("443");
  const [srvTarget, setSrvTarget] = useState("");
  const [caaFlags, setCaaFlags] = useState("0");
  const [caaTag, setCaaTag] = useState("issue");
  const [caaValue, setCaaValue] = useState("");
  const [advJson, setAdvJson] = useState("");
  const [advOpen, setAdvOpen] = useState(false);

  useEffect(() => {
    if (!open) return;
    if (mode === "edit" && record) {
      const rt = record.type;
      setRecType(rt);
      setName(record.name || "");
      setTtl(record.ttl === 1 ? "1" : String(record.ttl));
      setComment(record.comment || "");
      setContent("");
      setMxTarget("");
      setMxPrio("10");
      setSrvPrio("10");
      setSrvWeight("10");
      setSrvPort("443");
      setSrvTarget("");
      setCaaFlags("0");
      setCaaTag("issue");
      setCaaValue("");
      setAdvJson("");
      setAdvOpen(false);

      if (["A", "AAAA", "CNAME", "TXT", "NS", "PTR"].includes(rt)) {
        setContent(record.content || "");
      }
      if (rt === "MX") {
        setMxTarget(record.content || "");
        setMxPrio(String(record.priority ?? 10));
      }
      if (rt === "SRV" && record.data) {
        const d = record.data as Record<string, unknown>;
        setSrvPrio(String(d.priority ?? 10));
        setSrvWeight(String(d.weight ?? 10));
        setSrvPort(String(d.port ?? 443));
        setSrvTarget(String(d.target ?? ""));
      }
      if (rt === "CAA" && record.data) {
        const d = record.data as Record<string, unknown>;
        setCaaFlags(String(d.flags ?? 0));
        setCaaTag(String(d.tag ?? "issue"));
        setCaaValue(String(d.value ?? ""));
      }
      if (record.proxiable) {
        setProxWrap(true);
        setProxied(!!record.proxied);
      } else {
        setProxWrap(false);
        setProxied(false);
      }
      if (record.data && !["SRV", "CAA"].includes(rt)) {
        setAdvOpen(true);
        setAdvJson(JSON.stringify({ data: record.data }, null, 2));
      }
      return;
    }
    setRecType("A");
    setName("");
    setTtl("1");
    setComment("");
    setProxWrap(false);
    setProxied(false);
    setContent("");
    setMxTarget("");
    setMxPrio("10");
    setSrvPrio("10");
    setSrvWeight("10");
    setSrvPort("443");
    setSrvTarget("");
    setCaaFlags("0");
    setCaaTag("issue");
    setCaaValue("");
    setAdvJson("");
    setAdvOpen(false);
  }, [open, mode, record]);

  useEffect(() => {
    if (!["A", "AAAA", "CNAME"].includes(recType)) {
      setProxied(false);
    }
  }, [recType]);

  const showProxBox = proxWrap && ["A", "AAAA", "CNAME"].includes(recType);

  function buildPayload(): Record<string, unknown> {
    const ttlRaw = ttl.trim();
    const ttlNum = ttlRaw === "auto" || ttlRaw === "" ? 1 : parseInt(ttlRaw, 10);
    const payload: Record<string, unknown> = {
      type: recType,
      name: name.trim(),
      ttl: Number.isFinite(ttlNum) ? ttlNum : 1,
    };
    if (comment.trim()) payload.comment = comment.trim();

    if (["A", "AAAA", "CNAME", "TXT", "NS", "PTR"].includes(recType)) {
      payload.content = content.trim();
    } else if (recType === "MX") {
      payload.content = mxTarget.trim();
      payload.priority = parseInt(mxPrio || "10", 10) || 10;
    } else if (recType === "SRV") {
      payload.data = {
        priority: parseInt(srvPrio || "10", 10) || 10,
        weight: parseInt(srvWeight || "10", 10) || 10,
        port: parseInt(srvPort || "443", 10) || 443,
        target: srvTarget.trim(),
      };
    } else if (recType === "CAA") {
      payload.data = {
        flags: parseInt(caaFlags || "0", 10) || 0,
        tag: (caaTag || "issue").trim(),
        value: caaValue.trim().replace(/^"|"$/g, ""),
      };
    }

    if (showProxBox) {
      payload.proxied = proxied;
    }

    return payload;
  }

  async function save() {
    if (!zoneId) return;
    try {
      const payload = buildPayload();
      const advText = advJson.trim();
      if (advText) {
        const extra = JSON.parse(advText) as Record<string, unknown>;
        if (extra && typeof extra === "object") Object.assign(payload, extra);
      }
      const nameVal = String(payload.name ?? "").trim();
      if (!nameVal) {
        toast("名称不能为空", true);
        return;
      }
      payload.name = nameVal;
      const hasContent = payload.content !== undefined && String(payload.content).length > 0;
      const hasData = payload.data !== undefined && payload.data !== null;
      if (!hasContent && !hasData && !advText) {
        toast("请填写内容、结构化 data，或使用高级 JSON", true);
        return;
      }
      if (payload.type === "SRV" && payload.data && typeof payload.data === "object") {
        const d = payload.data as { target?: string };
        if (!String(d.target || "").trim()) {
          toast("SRV 记录请填写 target", true);
          return;
        }
      }
      if (payload.type === "CAA" && payload.data && typeof payload.data === "object") {
        const d = payload.data as { value?: string };
        if (!String(d.value || "").trim()) {
          toast("CAA 请填写 value", true);
          return;
        }
      }

      if (mode === "edit" && record) {
        const patch: Record<string, unknown> = {
          type: payload.type,
          name: payload.name,
          ttl: payload.ttl,
          comment: payload.comment,
        };
        if (payload.content != null) patch.content = payload.content;
        if (payload.priority != null) patch.priority = payload.priority;
        if (payload.data != null) patch.data = payload.data;
        if (["A", "AAAA", "CNAME"].includes(String(payload.type))) {
          patch.proxied = !!payload.proxied;
        }
        await cf(`/zones/${zoneId}/dns_records/${record.id}`, {
          method: "PATCH",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(patch),
        });
        toast("已更新");
      } else {
        await cf(`/zones/${zoneId}/dns_records`, {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(payload),
        });
        toast("已创建");
      }
      onClose();
      await onSaved();
    } catch (e) {
      toast(e instanceof Error ? e.message : String(e), true);
    }
  }

  let simpleBlock: ReactNode;
  if (["A", "AAAA", "CNAME", "TXT", "NS", "PTR"].includes(recType)) {
    simpleBlock = (
      <label className="field">
        <span>内容 content</span>
        <textarea id="f-content" rows={3} value={content} onChange={(e) => setContent(e.target.value)} />
      </label>
    );
  } else if (recType === "MX") {
    simpleBlock = (
      <>
        <label className="field">
          <span>邮件服务器</span>
          <input id="f-mx-target" type="text" value={mxTarget} onChange={(e) => setMxTarget(e.target.value)} />
        </label>
        <label className="field">
          <span>优先级</span>
          <input
            id="f-mx-prio"
            type="number"
            value={mxPrio}
            onChange={(e) => setMxPrio(e.target.value)}
          />
        </label>
      </>
    );
  } else if (recType === "SRV") {
    simpleBlock = (
      <>
        <p className="muted small">
          名称需含服务名，如 <code>_sip._tcp</code> 加主机名。
        </p>
        <label className="field">
          <span>优先级 priority</span>
          <input id="f-srv-prio" type="number" value={srvPrio} onChange={(e) => setSrvPrio(e.target.value)} />
        </label>
        <label className="field">
          <span>权重 weight</span>
          <input
            id="f-srv-weight"
            type="number"
            value={srvWeight}
            onChange={(e) => setSrvWeight(e.target.value)}
          />
        </label>
        <label className="field">
          <span>端口 port</span>
          <input id="f-srv-port" type="number" value={srvPort} onChange={(e) => setSrvPort(e.target.value)} />
        </label>
        <label className="field">
          <span>目标 target</span>
          <input id="f-srv-target" type="text" value={srvTarget} onChange={(e) => setSrvTarget(e.target.value)} />
        </label>
      </>
    );
  } else if (recType === "CAA") {
    simpleBlock = (
      <>
        <label className="field">
          <span>flags</span>
          <input id="f-caa-flags" type="number" value={caaFlags} onChange={(e) => setCaaFlags(e.target.value)} />
        </label>
        <label className="field">
          <span>tag（issue / issuewild / iodef）</span>
          <input id="f-caa-tag" type="text" value={caaTag} onChange={(e) => setCaaTag(e.target.value)} />
        </label>
        <label className="field">
          <span>value（不含引号也可）</span>
          <input
            id="f-caa-value"
            type="text"
            placeholder="letsencrypt.org"
            value={caaValue}
            onChange={(e) => setCaaValue(e.target.value)}
          />
        </label>
      </>
    );
  } else {
    simpleBlock = (
      <p className="muted small">
        该类型请使用下方「高级 JSON」提供 <code>content</code> 或 <code>data</code> 字段。
      </p>
    );
  }

  return (
    <div
      id="drawer"
      className={`drawer${open ? "" : " hidden"}`}
      role="dialog"
      aria-modal="true"
      aria-labelledby="drawer-title"
      onClick={(ev) => {
        if ((ev.target as HTMLElement).id === "drawer") onClose();
      }}
    >
      <div className="drawer-panel">
        <div className="drawer-head">
          <h2 id="drawer-title">{mode === "edit" ? "编辑解析" : "新建解析"}</h2>
          <button type="button" id="drawer-close" className="btn ghost small" onClick={onClose}>
            关闭
          </button>
        </div>
        <div className="drawer-body" id="drawer-body">
          <label className="field">
            <span>记录类型</span>
            <select id="f-type" value={recType} onChange={(e) => setRecType(e.target.value)}>
              {RECORD_TYPES.map((t) => (
                <option key={t} value={t}>
                  {t}
                </option>
              ))}
            </select>
          </label>
          <label className="field">
            <span>名称（可使用相对名称，如 www 或 @）</span>
            <input
              id="f-name"
              type="text"
              autoComplete="off"
              placeholder="例如 www 或 @ "
              value={name}
              onChange={(e) => setName(e.target.value)}
            />
          </label>
          <label className="field">
            <span>TTL（1 = 自动）</span>
            <input id="f-ttl" type="text" inputMode="numeric" value={ttl} onChange={(e) => setTtl(e.target.value)} />
          </label>
          <label className="field">
            <span>备注 comment（可选）</span>
            <input id="f-comment" type="text" value={comment} onChange={(e) => setComment(e.target.value)} />
          </label>
          <div id="f-simple" className="stack">
            {simpleBlock}
          </div>
          <label className="toggle">
            <input
              type="checkbox"
              id="f-prox-wrap"
              checked={proxWrap}
              onChange={(e) => setProxWrap(e.target.checked)}
            />
            <span className="muted small">对 A / AAAA / CNAME 显示「橙色云」代理选项</span>
          </label>
          <div id="f-prox-box" className={showProxBox ? "" : "hidden"}>
            <label className="toggle">
              <input
                type="checkbox"
                id="f-proxied"
                checked={proxied}
                onChange={(e) => setProxied(e.target.checked)}
              />
              <span>经过 Cloudflare 代理（orange cloud）</span>
            </label>
          </div>
          <details className="details" id="f-adv-details" open={advOpen} onToggle={(e) => setAdvOpen(e.currentTarget.open)}>
            <summary>高级：手动 JSON（覆盖简单字段，复杂类型）</summary>
            <p className="muted small">
              会合并到基础字段；可用于 HTTPS/SVCB 等需 <code>data</code> 的对象。
            </p>
            <textarea
              id="f-adv-json"
              className="cell-mono"
              placeholder='例如 { "data": { ... } }'
              value={advJson}
              onChange={(e) => setAdvJson(e.target.value)}
            />
          </details>
          <div className="form-actions">
            <button type="button" id="f-save" className="btn primary" onClick={() => void save()}>
              {mode === "edit" ? "保存修改" : "创建记录"}
            </button>
          </div>
        </div>
      </div>
    </div>
  );
}
