/**
 * MotherShip 登录后一级：地址键入联想下拉（Axel suggest）
 */
"use client";

import { useEffect, useId, useRef, useState } from "react";
import { CaretRight, MagnifyingGlass, X } from "@phosphor-icons/react";
import { hostSuggestMothershipAddress } from "@/lib/frontend/api-client";
import type { MothershipAddressCandidate } from "@/lib/frontend/types";
import { LoadingSpinner } from "@/components/ui/loading-spinner";

const DEBOUNCE_MS = 300;
const MIN_QUERY_LEN = 3;

export interface MothershipAddressSuggestFieldProps {
  label: string;
  required?: boolean;
  placeholder?: string;
  disabled?: boolean;
  /** 必填未满足时高亮边框 */
  invalid?: boolean;
  testId?: string;
  customerId: string;
  apiBaseUrl?: string;
  serviceToken?: string;
  value: string;
  confirmed: MothershipAddressCandidate | null;
  onQueryChange: (query: string) => void;
  onConfirm: (candidate: MothershipAddressCandidate | null) => void;
}

function splitDisplay(label: string): { primary: string; secondary: string } {
  const parts = label.split(",").map((p) => p.trim()).filter(Boolean);
  if (parts.length <= 1) {
    return { primary: label, secondary: "" };
  }
  return {
    primary: parts[0]!,
    secondary: parts.slice(1).join(", "),
  };
}

export function MothershipAddressSuggestField({
  label,
  required,
  placeholder = "按邮编、地址或公司名搜索",
  disabled,
  invalid,
  testId,
  customerId,
  apiBaseUrl = "",
  serviceToken,
  value,
  confirmed,
  onQueryChange,
  onConfirm,
}: MothershipAddressSuggestFieldProps) {
  const listId = useId();
  const wrapRef = useRef<HTMLDivElement>(null);
  const [open, setOpen] = useState(false);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [candidates, setCandidates] = useState<MothershipAddressCandidate[]>(
    [],
  );
  const reqSeq = useRef(0);

  useEffect(() => {
    const onDoc = (e: MouseEvent) => {
      if (!wrapRef.current?.contains(e.target as Node)) {
        setOpen(false);
      }
    };
    document.addEventListener("mousedown", onDoc);
    return () => document.removeEventListener("mousedown", onDoc);
  }, []);

  useEffect(() => {
    const q = value.trim();
    if (q.length < MIN_QUERY_LEN) {
      setCandidates([]);
      setError(null);
      setLoading(false);
      return;
    }

    // 已确认且文案未变：不重复请求
    if (confirmed && confirmed.display_label === value.trim()) {
      return;
    }

    const seq = ++reqSeq.current;
    setLoading(true);
    setError(null);
    const timer = window.setTimeout(() => {
      void (async () => {
        try {
          const res = await hostSuggestMothershipAddress(
            apiBaseUrl,
            serviceToken,
            customerId,
            q,
          );
          if (seq !== reqSeq.current) return;
          if (res.code !== 0 || !res.data) {
            setCandidates([]);
            setError(res.message || "地址联想失败");
            return;
          }
          setCandidates(
            res.data.candidates.filter(
              (c) =>
                c.selectable !== false &&
                Boolean(c.option_id?.trim()) &&
                Boolean(
                  (c.display_label || c.formatted_address || "").trim(),
                ),
            ),
          );
          setOpen(true);
        } catch (err) {
          if (seq !== reqSeq.current) return;
          setCandidates([]);
          setError(err instanceof Error ? err.message : "地址联想失败");
        } finally {
          if (seq === reqSeq.current) {
            setLoading(false);
          }
        }
      })();
    }, DEBOUNCE_MS);

    return () => window.clearTimeout(timer);
  }, [value, apiBaseUrl, serviceToken, customerId, confirmed]);

  const handleInput = (next: string) => {
    onQueryChange(next);
    if (confirmed) {
      onConfirm(null);
    }
    setOpen(true);
  };

  const handleClear = () => {
    onQueryChange("");
    onConfirm(null);
    setCandidates([]);
    setError(null);
    setOpen(false);
  };

  const handlePick = (item: MothershipAddressCandidate) => {
    onQueryChange(item.display_label || item.formatted_address);
    onConfirm(item);
    setOpen(false);
    setError(null);
  };

  return (
    <div ref={wrapRef} className="relative space-y-1.5">
      <label className="block text-sm font-medium text-[#4B5563]">
        {label.trimEnd()}
        {required ? (
          <span className="ml-0.5 text-[#EF4444]" aria-hidden>
            *
          </span>
        ) : null}
      </label>
      <div className="relative">
        <MagnifyingGlass
          size={18}
          className="pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-text-disabled"
        />
        <input
          data-testid={testId}
          disabled={disabled}
          value={value}
          onChange={(e) => handleInput(e.target.value)}
          onFocus={() => {
            if (candidates.length > 0 || value.trim().length >= MIN_QUERY_LEN) {
              setOpen(true);
            }
          }}
          placeholder={placeholder}
          role="combobox"
          aria-expanded={open}
          aria-controls={listId}
          aria-autocomplete="list"
          aria-invalid={invalid || undefined}
          className={[
            "h-10 w-full rounded-md border bg-surface pl-10 pr-16 text-sm focus:outline-none focus:ring-2 disabled:opacity-60",
            invalid
              ? "border-[#EF4444] focus:border-[#EF4444] focus:ring-[#EF4444]/20"
              : "border-border focus:border-[#1890FF] focus:ring-[#1890FF]/20",
          ].join(" ")}
        />
        <div className="absolute right-2 top-1/2 flex -translate-y-1/2 items-center gap-1">
          {loading && (
            <LoadingSpinner size={16} className="text-text-secondary" />
          )}
          {value && !disabled && (
            <button
              type="button"
              aria-label="清空地址"
              onClick={handleClear}
              className="rounded p-1 text-text-secondary hover:bg-bg hover:text-text-primary"
            >
              <X size={14} weight="bold" />
            </button>
          )}
        </div>
      </div>

      {confirmed && (
        <p className="text-xs text-success">
          已选择 MotherShip 地址：{confirmed.display_label}
        </p>
      )}
      {error && <p className="text-xs text-error">{error}</p>}

      {open && !disabled && value.trim().length >= MIN_QUERY_LEN && (
        <div
          id={listId}
          role="listbox"
          className="absolute z-30 mt-1 max-h-72 w-full overflow-auto rounded-md border border-border bg-surface shadow-modal"
        >
          <button
            type="button"
            role="option"
            disabled
            title="请从搜索结果中选择经 MotherShip 校验的地址"
            className="flex w-full cursor-not-allowed items-start gap-2 border-b border-border bg-bg/80 px-3 py-2.5 text-left opacity-70"
          >
            <MagnifyingGlass
              size={16}
              className="mt-0.5 shrink-0 text-text-disabled"
            />
            <span>
              <span className="block text-sm text-text-secondary">
                使用我输入的地址
              </span>
              <span className="block text-xs text-text-disabled">{value}</span>
              <span className="mt-0.5 block text-[11px] text-warning">
                须从下方搜索结果点选，方可继续
              </span>
            </span>
          </button>

          <p className="px-3 py-1.5 text-[11px] font-medium uppercase tracking-wide text-text-disabled">
            搜索结果
          </p>

          {loading && candidates.length === 0 && (
            <p className="px-3 py-3 text-sm text-text-secondary">正在搜索…</p>
          )}
          {!loading && candidates.length === 0 && !error && (
            <p className="px-3 py-3 text-sm text-text-secondary">
              未找到匹配地址，请调整关键词
            </p>
          )}

          {candidates.map((item) => {
            const { primary, secondary } = splitDisplay(
              item.display_label || item.formatted_address,
            );
            return (
              <button
                key={item.option_id}
                type="button"
                role="option"
                onClick={() => handlePick(item)}
                className="flex w-full items-center gap-2 px-3 py-2.5 text-left hover:bg-bg"
              >
                <MagnifyingGlass
                  size={16}
                  className="shrink-0 text-text-disabled"
                />
                <span className="min-w-0 flex-1">
                  <span className="block truncate text-sm text-text-primary">
                    {primary}
                  </span>
                  {secondary ? (
                    <span className="block truncate text-xs text-text-secondary">
                      {secondary}
                    </span>
                  ) : null}
                </span>
                <CaretRight size={14} className="shrink-0 text-text-disabled" />
              </button>
            );
          })}
        </div>
      )}
    </div>
  );
}
