"use client";

import { useEffect, useMemo, useRef, useState } from "react";
import { ChevronDown, Globe } from "lucide-react";
import { cn } from "@/lib/cn";
import {
  COUNTRIES,
  DEFAULT_COUNTRY_ISO,
  getCountry,
} from "@/lib/countries";

/* Real flag image (flagcdn). "Other" gets a globe icon. */
function Flag({ iso, size = "md" }: { iso: string; size?: "md" | "sm" }) {
  if (iso === "ZZ") {
    return (
      <span
        aria-hidden="true"
        className="grid place-items-center rounded-[3px] bg-canvas text-muted"
        style={{ width: size === "md" ? 22 : 18, height: size === "md" ? 16 : 13 }}
      >
        <Globe size={size === "md" ? 12 : 10} />
      </span>
    );
  }
  return (
    <img
      src={`https://flagcdn.com/w40/${iso.toLowerCase()}.png`}
      srcSet={`https://flagcdn.com/w80/${iso.toLowerCase()}.png 2x`}
      alt=""
      aria-hidden="true"
      loading="lazy"
      draggable={false}
      className="rounded-[3px]"
      style={{ width: size === "md" ? 22 : 18, height: "auto" }}
    />
  );
}

type PhoneInputProps = {
  id?: string;
  label?: string;
  required?: boolean;
  error?: string;
  autoComplete?: string;
};

/* Floating-label phone field with searchable country selector.
   Posts E.164 `phone` (+dial+digits) and `phoneCountry` (ISO). */
export default function PhoneInput({
  id = "cb-phone",
  label = "Phone",
  required,
  error,
  autoComplete = "tel",
}: PhoneInputProps) {
  const [iso, setIso] = useState(DEFAULT_COUNTRY_ISO);
  const [digits, setDigits] = useState("");
  const [open, setOpen] = useState(false);
  const [query, setQuery] = useState("");
  const wrapRef = useRef<HTMLDivElement>(null);
  const searchRef = useRef<HTMLInputElement>(null);

  const country = getCountry(iso);
  const maxLen = Math.max(...country.lengths);

  // Close on outside click / Escape
  useEffect(() => {
    if (!open) return;
    const onDown = (e: MouseEvent) => {
      if (wrapRef.current && !wrapRef.current.contains(e.target as Node)) {
        setOpen(false);
      }
    };
    const onKey = (e: KeyboardEvent) => {
      if (e.key === "Escape") setOpen(false);
    };
    document.addEventListener("mousedown", onDown);
    document.addEventListener("keydown", onKey);
    return () => {
      document.removeEventListener("mousedown", onDown);
      document.removeEventListener("keydown", onKey);
    };
  }, [open ]);

  useEffect(() => {
    if (open) searchRef.current?.focus();
  }, [open ]);

  const filtered = useMemo(() => {
    const q = query.trim().toLowerCase();
    if (!q) return COUNTRIES;
    return COUNTRIES.filter(
      (c) =>
        c.name.toLowerCase().includes(q) ||
        c.dial.includes(q) ||
        c.iso.toLowerCase().includes(q)
    );
  }, [query]);

  const pick = (nextIso: string) => {
    setIso(nextIso);
    setDigits(""); // stale digits never validate against the wrong rule
    setOpen(false);
    setQuery("");
  };

  const onDigits = (raw: string) => {
    // Digits only, capped at the country's max length
    let d = raw.replace(/\D/g, "").slice(0, maxLen);
    // Strip Indian trunk prefix
    if (iso === "IN" && d.startsWith("0")) d = d.replace(/^0+/, "").slice(0, maxLen);
    setDigits(d);
  };

  const e164 = digits ? `+${country.dial}${digits}` : "";

  return (
    <div className="min-w-0">
      {/* Real posted values */}
      <input type="hidden" name="phone" value={e164} />
      <input type="hidden" name="phoneCountry" value={iso} />

      <div className="relative flex" ref={wrapRef}>
        {/* Country selector */}
        <button
          type="button"
          aria-haspopup="listbox"
          aria-expanded={open}
          aria-label="Select country code"
          onClick={() => setOpen((o) => !o)}
          className={cn(
            "flex h-12 shrink-0 items-center gap-1 rounded-l-xl border border-r-0 bg-canvas px-2.5 text-sm font-semibold text-ink focus:outline-none",
            error ? "border-red-400" : "border-[#d5dce8]"
          )}
        >
          <Flag iso={country.iso} />
          <span>+{country.dial || "…"}</span>
          <ChevronDown
            size={14}
            aria-hidden="true"
            className={cn("text-muted transition-transform", open && "rotate-180")}
          />
        </button>

        {/* Digits field */}
        <div className="relative min-w-0 flex-1">
          <input
            id={id}
            type="tel"
            inputMode="numeric"
            autoComplete={autoComplete}
            required={required}
            placeholder=" "
            value={digits}
            onChange={(e) => onDigits(e.target.value)}
            onPaste={(e) => {
              e.preventDefault();
              onDigits(e.clipboardData.getData("text"));
            }}
            className={cn(
              "peer block h-12 w-full rounded-r-xl rounded-l-none border bg-white px-3.5 pt-2 text-sm font-normal text-ink placeholder-transparent focus:outline-none focus-visible:outline-none",
              error
                ? "border-red-400 focus:border-red-500"
                : "border-[#d5dce8] focus:border-brand"
            )}
          />
          <label
            htmlFor={id}
            className={cn(
              "pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 bg-white px-1 text-[15px] transition-all",
              "peer-focus:top-0 peer-focus:text-xs peer-focus:font-semibold",
              "peer-[:not(:placeholder-shown)]:top-0 peer-[:not(:placeholder-shown)]:text-xs peer-[:not(:placeholder-shown)]:font-semibold",
              error
                ? "text-red-500"
                : "text-muted peer-focus:text-brand peer-[:not(:placeholder-shown)]:text-brand"
            )}
          >
            {label}
            {required && (
              <span aria-hidden="true" className="ml-0.5 text-red-500">*</span>
            )}
          </label>
        </div>

        {/* Dropdown panel */}
        {open && (
          <div
            role="listbox"
            aria-label="Country codes"
            className="absolute inset-x-0 top-[calc(100%+6px)] z-30 rounded-xl border border-[#d5dce8] bg-white shadow-card"
          >
            <div className="border-b border-line p-2">
              <input
                ref={searchRef}
                type="text"
                value={query}
                onChange={(e) => setQuery(e.target.value)}
                placeholder="Search country or code…"
                aria-label="Search countries"
                className="block h-10 w-full rounded-lg border border-[#d5dce8] bg-white px-3 text-sm text-ink placeholder:text-muted focus:border-brand focus:outline-none"
              />
            </div>
            <ul className="max-h-60 overflow-y-auto p-1.5">
              {filtered.length === 0 && (
                <li className="px-3 py-3 text-[13px] text-muted">
                  No matches — try a name, code or ISO.
                </li>
              )}
              {filtered.map((c) => (
                <li key={c.iso} role="option" aria-selected={c.iso === iso}>
                  <button
                    type="button"
                    onClick={() => pick(c.iso)}
                    className={cn(
                      "flex w-full items-center gap-2.5 rounded-lg px-2.5 py-2 text-left text-[13px] transition-colors",
                      c.iso === iso
                        ? "bg-brand-tint font-semibold text-ink"
                        : "text-body hover:bg-canvas"
                    )}
                  >
                    <Flag iso={c.iso} size="sm" />
                    <span className="min-w-0 flex-1 truncate">{c.name}</span>
                    <span className="shrink-0 font-mono text-muted">
                      {c.dial ? `+${c.dial}` : ""}
                    </span>
                  </button>
                </li>
              ))}
            </ul>
          </div>
        )}
      </div>

      {error && (
        <span className="mt-1 block text-xs font-normal text-red-600">
          {error}
        </span>
      )}
    </div>
  );
}
