"use client";

import { useEffect, useId, useRef, useState } from "react";
import {
  filterUsStateOptions,
  formatUsStateOption,
  normalizeUsStateCode,
} from "@/lib/frontend/us-states";

interface StateComboboxFieldProps {
  label: string;
  name: string;
  value: string;
  disabled?: boolean;
  error?: string;
  onChange: (code: string) => void;
  onBlur?: () => void;
}

export function StateComboboxField({
  label,
  name,
  value,
  disabled,
  error,
  onChange,
  onBlur,
}: StateComboboxFieldProps) {
  const listId = useId();
  const rootRef = useRef<HTMLDivElement>(null);
  const [draft, setDraft] = useState(value);
  const [open, setOpen] = useState(false);

  useEffect(() => {
    setDraft(value);
  }, [value]);

  const options = filterUsStateOptions(draft);

  const commitDraft = () => {
    const normalized = normalizeUsStateCode(draft);
    if (normalized) {
      onChange(normalized);
      setDraft(normalized);
    } else {
      onChange(draft.trim().toUpperCase());
    }
    onBlur?.();
  };

  const selectOption = (code: string, labelText: string) => {
    onChange(code);
    setDraft(labelText);
    setOpen(false);
    onBlur?.();
  };

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

  return (
    <div ref={rootRef} className="relative space-y-1">
      <label htmlFor={name} className="block text-sm font-medium text-text-primary">
        {label}
      </label>
      <input
        id={name}
        name={name}
        type="text"
        autoComplete="off"
        role="combobox"
        aria-expanded={open}
        aria-controls={listId}
        aria-autocomplete="list"
        list={listId}
        disabled={disabled}
        value={draft}
        placeholder="输入州码或选择，如 CA"
        onChange={(e) => {
          const next = e.target.value;
          setDraft(next);
          setOpen(true);
          const normalized = normalizeUsStateCode(next);
          if (normalized) onChange(normalized);
        }}
        onFocus={() => setOpen(true)}
        onBlur={() => {
          window.setTimeout(() => {
            if (!rootRef.current?.contains(document.activeElement)) {
              commitDraft();
              setOpen(false);
            }
          }, 120);
        }}
        onKeyDown={(e) => {
          if (e.key === "Escape") {
            setOpen(false);
            return;
          }
          if (e.key === "Enter" && open && options.length > 0) {
            e.preventDefault();
            const first = options[0];
            selectOption(first.code, formatUsStateOption(first));
          }
        }}
        className={`h-10 w-full rounded-sm border px-3 text-sm transition-colors focus:border-primary focus:outline-none focus:ring-2 focus:ring-primary/20 disabled:cursor-not-allowed disabled:bg-bg disabled:opacity-60 ${
          error ? "border-error" : "border-border"
        }`}
      />
      {open && !disabled && options.length > 0 && (
        <ul
          id={listId}
          role="listbox"
          className="absolute z-20 mt-1 max-h-48 w-full overflow-y-auto rounded-md border border-border bg-surface shadow-card"
        >
          {options.map((entry) => {
            const labelText = formatUsStateOption(entry);
            return (
              <li key={entry.code} role="option">
                <button
                  type="button"
                  className="w-full px-3 py-2 text-left text-sm hover:bg-bg"
                  onMouseDown={(e) => e.preventDefault()}
                  onClick={() => selectOption(entry.code, labelText)}
                >
                  {labelText}
                </button>
              </li>
            );
          })}
        </ul>
      )}
      {error && <p className="text-xs text-error">{error}</p>}
    </div>
  );
}
