'use client';

import { Check, ChevronDown, Search } from 'lucide-react';
import { useEffect, useMemo, useRef, useState } from 'react';

export interface Country {
  code: string; // ISO-3166 alpha-2
  name: string;
  dial: string; // E.164 dial prefix incl. leading '+'
}

/** Compute the regional-indicator-symbol flag emoji from an ISO-3166 alpha-2
 *  code. 🇨🇭 from "CH", 🇺🇸 from "US" etc. — no asset files needed. */
function flagFor(code: string): string {
  if (code.length !== 2) return '';
  const A = 0x1f1e6 - 65;
  return String.fromCodePoint(
    ...code
      .toUpperCase()
      .split('')
      .map((c) => A + c.charCodeAt(0)),
  );
}

/**
 * Custom country picker — opens DOWNWARD always (native <select> defers the
 * direction to the browser and frequently opens upward on mobile, hiding
 * countries behind the keyboard). Built-in search filter so a 150-entry list
 * stays usable.
 */
export function CountryPicker({
  countries,
  value,
  onChange,
}: {
  countries: Country[];
  value: string;
  onChange: (code: string) => void;
}) {
  const [open, setOpen] = useState(false);
  const [query, setQuery] = useState('');
  const wrap = useRef<HTMLDivElement>(null);
  const searchRef = useRef<HTMLInputElement>(null);

  const selected = countries.find((c) => c.code === value);

  const filtered = useMemo(() => {
    const q = query.trim().toLowerCase();
    if (!q) return countries;
    return countries.filter(
      (c) =>
        c.name.toLowerCase().includes(q) ||
        c.code.toLowerCase().includes(q) ||
        c.dial.replace('+', '').includes(q.replace('+', '')),
    );
  }, [countries, query]);

  // Outside-click + Escape close
  useEffect(() => {
    if (!open) return;
    function onDocMouseDown(e: MouseEvent) {
      if (!wrap.current?.contains(e.target as Node)) setOpen(false);
    }
    function onKey(e: KeyboardEvent) {
      if (e.key === 'Escape') setOpen(false);
    }
    document.addEventListener('mousedown', onDocMouseDown);
    document.addEventListener('keydown', onKey);
    return () => {
      document.removeEventListener('mousedown', onDocMouseDown);
      document.removeEventListener('keydown', onKey);
    };
  }, [open]);

  // Autofocus the search input when the dropdown opens.
  useEffect(() => {
    if (open) {
      const t = setTimeout(() => searchRef.current?.focus(), 0);
      return () => clearTimeout(t);
    }
  }, [open]);

  function select(code: string) {
    onChange(code);
    setOpen(false);
    setQuery('');
  }

  return (
    <div ref={wrap} className="relative">
      <button
        type="button"
        aria-haspopup="listbox"
        aria-expanded={open}
        onClick={() => setOpen((v) => !v)}
        className="flex h-8 w-full items-center justify-between gap-2 rounded-md border border-[--color-border] bg-[--color-bg-subtle] px-2.5 text-[13px] text-[--color-fg] transition-colors duration-200 hover:border-[--color-border-strong] focus:border-[--color-accent] focus:outline-none focus:ring-1 focus:ring-[--color-accent]"
      >
        <span className="flex min-w-0 items-center gap-2">
          {selected && (
            <span aria-hidden className="text-[14px] leading-none">
              {flagFor(selected.code)}
            </span>
          )}
          <span className="truncate">
            {selected ? `${selected.name} (${selected.dial})` : 'Select country'}
          </span>
        </span>
        <ChevronDown size={13} className="shrink-0 text-[--color-fg-subtle]" />
      </button>

      {open && (
        <div
          role="listbox"
          // Background + border via inline style for the same reason as UserMenu:
          // Tailwind v4's `bg-[--color-X]` bracket syntax produces invalid CSS,
          // so the dropdown was rendering transparent. Frosted glass via
          // backdrop-blur + 88% elevated-panel fill.
          className="absolute left-0 right-0 top-full z-50 mt-1 overflow-hidden rounded-md border shadow-lg shadow-black/40 backdrop-blur-md"
          style={{
            backgroundColor: 'color-mix(in oklab, var(--color-bg-elevated) 88%, transparent)',
            borderColor: 'var(--color-border)',
          }}
        >
          <div className="flex items-center gap-2 border-b border-[--color-border] px-2.5">
            <Search size={13} className="text-[--color-fg-subtle]" />
            <input
              ref={searchRef}
              value={query}
              onChange={(e) => setQuery(e.target.value)}
              placeholder="Search country or code…"
              className="h-9 w-full bg-transparent text-[13px] text-[--color-fg] placeholder:text-[--color-fg-subtle] focus:outline-none"
              onKeyDown={(e) => {
                if (e.key === 'Enter' && filtered.length > 0) {
                  e.preventDefault();
                  select(filtered[0]!.code);
                }
              }}
            />
          </div>
          <ul className="max-h-60 overflow-y-auto py-1">
            {filtered.length === 0 && (
              <li className="px-3 py-2 text-[12px] text-[--color-fg-subtle]">No match.</li>
            )}
            {filtered.map((c) => {
              const isSelected = c.code === value;
              return (
                <li key={c.code}>
                  <button
                    type="button"
                    role="option"
                    aria-selected={isSelected}
                    onClick={() => select(c.code)}
                    className={`flex w-full items-center gap-2.5 px-2.5 py-1.5 text-left text-[12.5px] transition-colors ${
                      isSelected
                        ? 'bg-[--color-bg-subtle] text-[--color-fg]'
                        : 'text-[--color-fg-muted] hover:bg-[--color-bg-subtle] hover:text-[--color-fg]'
                    }`}
                  >
                    <span aria-hidden className="text-[14px] leading-none">
                      {flagFor(c.code)}
                    </span>
                    <span className="flex-1 truncate">{c.name}</span>
                    <span className="mono text-[11px] text-[--color-fg-subtle]">{c.dial}</span>
                    {isSelected && (
                      <Check size={12} className="text-[--color-accent]" />
                    )}
                  </button>
                </li>
              );
            })}
          </ul>
        </div>
      )}
    </div>
  );
}
