'use client';

import { useMemo, useState } from 'react';
import { Check, ChevronsUpDown } from 'lucide-react';

import { Button } from '@/components/ui/button';
import {
  Command,
  CommandEmpty,
  CommandGroup,
  CommandInput,
  CommandItem,
  CommandList,
} from '@/components/ui/command';
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
import { CountryFlag } from '@/components/shared/country-flag';
import { cn } from '@/lib/utils';
import { ALL_COUNTRY_CODES, getCountryName, type CountryCode } from '@/lib/i18n/countries';

interface CountryComboboxProps {
  value: string | null | undefined;
  onChange: (iso: CountryCode | null) => void;
  /** Display locale; defaults to navigator.language so country names follow the user. */
  locale?: string;
  /** When true, renders just the flag/code (compact 24×24 trigger). */
  compact?: boolean;
  placeholder?: string;
  disabled?: boolean;
  className?: string;
  /** Allow clearing the selection. */
  clearable?: boolean;
  id?: string;
  'data-testid'?: string;
  /** Open the dropdown on first render. Used by inline-edit wrappers so the
   *  user lands directly in the picker after clicking the edit affordance. */
  defaultOpen?: boolean;
  /** Notified whenever the dropdown opens/closes. Inline-edit wrappers use
   *  this to auto-exit edit mode when the user dismisses without picking. */
  onOpenChange?: (open: boolean) => void;
}

export function CountryCombobox({
  value,
  onChange,
  locale,
  compact = false,
  placeholder = 'Select country…',
  disabled,
  className,
  clearable = true,
  id,
  'data-testid': testId,
  defaultOpen = false,
  onOpenChange,
}: CountryComboboxProps) {
  const [open, setOpen] = useState(defaultOpen);
  const handleOpenChange = (next: boolean) => {
    setOpen(next);
    onOpenChange?.(next);
  };
  const effectiveLocale = locale ?? (typeof navigator !== 'undefined' ? navigator.language : 'en');

  // Pre-build the options list once per locale change so the cmdk filter
  // can search by both code + localized name without re-allocating.
  const options = useMemo(() => {
    return ALL_COUNTRY_CODES.map((code) => ({
      code,
      name: getCountryName(code, effectiveLocale),
    })).sort((a, b) => a.name.localeCompare(b.name, effectiveLocale));
  }, [effectiveLocale]);

  const selected = value ? options.find((o) => o.code === value) : undefined;

  return (
    // modal: required when this combobox is nested inside a Sheet
    // (Radix Dialog). Without it, the parent Dialog's pointer-events
    // handling swallows the trigger's tap on iOS Safari - same fix
    // pattern as TimezoneCombobox.
    <Popover modal open={open} onOpenChange={handleOpenChange}>
      <PopoverTrigger asChild>
        <Button
          id={id}
          variant="outline"
          role="combobox"
          aria-expanded={open}
          disabled={disabled}
          className={cn(
            'justify-between',
            // `shrink-0` keeps the country trigger from collapsing below its
            // natural width when the parent flex row gets squeezed, which
            // was causing "🇺🇸 US +1" to wrap vertically inside PhoneInput.
            compact ? 'w-24 shrink-0 px-2' : 'w-full',
            !selected && 'text-muted-foreground',
            className,
          )}
          data-testid={testId}
        >
          {selected ? (
            <span className="flex min-w-0 items-center gap-2">
              <CountryFlag code={selected.code} className="h-3 w-4" decorative />
              {!compact ? (
                <span className="truncate text-sm">{selected.name}</span>
              ) : (
                <span className="text-xs font-medium">{selected.code}</span>
              )}
            </span>
          ) : (
            <span className="truncate">{placeholder}</span>
          )}
          <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" aria-hidden />
        </Button>
      </PopoverTrigger>
      <PopoverContent className="w-(--radix-popper-anchor-width) min-w-[280px] p-0" align="start">
        <Command>
          <CommandInput placeholder="Search country or code…" />
          <CommandList>
            <CommandEmpty>No country found.</CommandEmpty>
            {clearable && value ? (
              <CommandGroup>
                <CommandItem
                  value="__clear__"
                  onSelect={() => {
                    onChange(null);
                    setOpen(false);
                  }}
                  className="text-muted-foreground"
                >
                  Clear selection
                </CommandItem>
              </CommandGroup>
            ) : null}
            <CommandGroup>
              {options.map((opt) => (
                <CommandItem
                  key={opt.code}
                  // cmdk filters by `value` - include both code + name.
                  value={`${opt.name} ${opt.code}`}
                  onSelect={() => {
                    onChange(opt.code);
                    setOpen(false);
                  }}
                >
                  <Check
                    className={cn('mr-2 h-4 w-4', value === opt.code ? 'opacity-100' : 'opacity-0')}
                  />
                  <CountryFlag code={opt.code} className="mr-2 h-3 w-4" decorative />
                  <span className="flex-1 truncate text-sm">{opt.name}</span>
                  <span className="text-xs text-muted-foreground">{opt.code}</span>
                </CommandItem>
              ))}
            </CommandGroup>
          </CommandList>
        </Command>
      </PopoverContent>
    </Popover>
  );
}
