import { useEffect, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { Check, ChevronDown, Globe } from "lucide-react";
import { LANGUAGES } from "@/i18n";
import {
  FocusableButton,
  FocusableSection,
  setFocus,
} from "@/components/focusable";
import { useFocusRestore } from "@/hooks/useFocusRestore";

/**
 * Language picker — trigger + dropdown menu.
 *
 * Spatial navigation (v1.4.4 fix):
 *   • Trigger is a FocusableButton (`lang-select`).
 *   • When the panel opens, focus is auto-routed to the active
 *     language item via FocusableSection autoFocus.
 *   • The panel is a `trap` focus section — arrow keys can't leave
 *     until the user picks an item or presses Esc / OK on the
 *     trigger again to close.
 *   • When the panel closes, focus is restored to the trigger
 *     button via setFocus("lang-select").
 */
const LanguageSelect = ({
  align = "right",
}: {
  align?: "left" | "right";
}) => {
  const { i18n } = useTranslation();
  const [open, setOpen] = useState(false);
  const ref = useRef<HTMLDivElement>(null);

  // Close on outside click (touch / mouse). Spatial-nav close paths
  // already restore focus to the trigger themselves.
  useEffect(() => {
    const onDoc = (e: MouseEvent) => {
      if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false);
    };
    document.addEventListener("mousedown", onDoc);
    return () => document.removeEventListener("mousedown", onDoc);
  }, []);

  // Restore focus to whichever element was focused before the
  // dropdown opened. Without this, dismissing on a page where
  // `lang-select` isn't rendered (e.g. inside the player overlay)
  // leaves focus dead.
  useFocusRestore(open, ["lang-select", "tv-back-button"]);

  const closeAndRestore = () => {
    // Simply flip `open` off — the useFocusRestore hook handles the
    // setFocus side-effect for us.
    setOpen(false);
  };

  const current = LANGUAGES.find((l) => l.code === i18n.language) ?? LANGUAGES[0];

  // When the panel opens, jump focus to the ACTIVE language item so
  // the user immediately knows where they are in the list and can
  // arrow up/down to pick a neighbour.
  useEffect(() => {
    if (!open) return;
    const tryFocus = () => {
      try {
        setFocus(`lang-option-${current.code}`);
      } catch {
        /* spatial-nav not ready */
      }
    };
    const t1 = window.setTimeout(tryFocus, 80);
    const t2 = window.setTimeout(tryFocus, 220);
    return () => {
      window.clearTimeout(t1);
      window.clearTimeout(t2);
    };
  }, [open, current.code]);

  // Close the panel on Escape / Back key. We listen at the
  // document level (with `capture: true`) because norigin's virtual
  // focus model means no DOM node inside the panel actually has
  // browser focus — so the panel's own `onKeyDown` never fires.
  useEffect(() => {
    if (!open) return;
    const handler = (e: KeyboardEvent) => {
      if (
        e.key === "Escape" ||
        e.key === "Backspace" ||
        e.key === "GoBack" ||
        e.keyCode === 10009 /* Tizen Return */ ||
        e.keyCode === 461 /* WebOS Back */
      ) {
        e.preventDefault();
        e.stopPropagation();
        closeAndRestore();
      }
    };
    document.addEventListener("keydown", handler, true);
    return () => document.removeEventListener("keydown", handler, true);
  }, [open]);

  return (
    <div ref={ref} className="relative">
      <FocusableButton
        focusKey="lang-select"
        data-testid="lang-select-btn"
        onEnter={() => setOpen((v) => !v)}
        onClick={() => setOpen((v) => !v)}
        className="flex items-center gap-2 px-3 sm:px-4 h-10 rounded-full glass text-foreground/90 hover:border-primary/40 transition-colors text-sm"
        focusClassName="ring-2 ring-primary border-primary/60"
      >
        <Globe className="w-4 h-4 text-primary shrink-0" />
        <span className="text-lg leading-none">{current.flag}</span>
        <span className="hidden sm:inline text-xs tracking-wider">{current.label}</span>
        <ChevronDown
          className={`w-3.5 h-3.5 text-muted-foreground transition-transform ${
            open ? "rotate-180" : ""
          }`}
        />
      </FocusableButton>
      {open && (
        <FocusableSection
          focusKey="lang-select-panel"
          autoFocus
          trap
          data-testid="lang-select-menu"
          className={`absolute top-12 ${align === "right" ? "right-0" : "left-0"} z-50 glass-card rounded-xl p-1 w-48 max-h-72 overflow-y-auto`}
          onKeyDown={(e) => {
            // Escape / Back closes the panel and returns focus to the
            // trigger button. Without this, the trap would never
            // release on a TV remote that uses the Back key.
            if (
              e.key === "Escape" ||
              e.key === "Backspace" ||
              e.key === "GoBack" ||
              e.keyCode === 10009 /* Tizen Return */ ||
              e.keyCode === 461 /* WebOS Back */
            ) {
              e.preventDefault();
              e.stopPropagation();
              closeAndRestore();
            }
          }}
        >
          {LANGUAGES.map((l) => {
            const active = l.code === current.code;
            return (
              <FocusableButton
                key={l.code}
                focusKey={`lang-option-${l.code}`}
                data-testid={`lang-option-${l.code}`}
                onEnter={() => {
                  void i18n.changeLanguage(l.code);
                  closeAndRestore();
                }}
                onClick={() => {
                  void i18n.changeLanguage(l.code);
                  closeAndRestore();
                }}
                className={`w-full flex items-center gap-3 px-3 py-2 rounded-lg text-sm transition-colors ${
                  active
                    ? "bg-primary/15 text-primary"
                    : "text-foreground/80 hover:bg-primary/10 hover:text-foreground"
                }`}
                focusClassName="ring-2 ring-primary/70 bg-primary/10"
              >
                <span className="text-lg leading-none">{l.flag}</span>
                <span className="flex-1 text-start">{l.label}</span>
                {active && <Check className="w-4 h-4" />}
              </FocusableButton>
            );
          })}
        </FocusableSection>
      )}
    </div>
  );
};

export default LanguageSelect;
