'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,
  CommandSeparator,
} from '@/components/ui/command';
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
import { cn } from '@/lib/utils';
import { formatTimezoneLabel, listAllTimezones, timezonesForCountry } from '@/lib/i18n/timezones';
import type { CountryCode } from '@/lib/i18n/countries';

interface TimezoneComboboxProps {
  value: string | null | undefined;
  onChange: (iana: string | null) => void;
  /** When set, the dropdown surfaces matching zones first under a "Suggested" group. */
  countryHint?: CountryCode;
  placeholder?: string;
  disabled?: boolean;
  className?: string;
  clearable?: boolean;
  id?: string;
  'data-testid'?: string;
  /** Open the dropdown on first render. Used by inline-edit wrappers. */
  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 TimezoneCombobox({
  value,
  onChange,
  countryHint,
  placeholder = 'Select timezone…',
  disabled,
  className,
  clearable = true,
  id,
  'data-testid': testId,
  defaultOpen = false,
  onOpenChange,
}: TimezoneComboboxProps) {
  const [open, setOpen] = useState(defaultOpen);
  const handleOpenChange = (next: boolean) => {
    setOpen(next);
    onOpenChange?.(next);
  };

  const allOptions = useMemo(() => {
    return listAllTimezones().map((tz) => ({
      tz,
      label: formatTimezoneLabel(tz),
    }));
  }, []);

  const suggested = useMemo(() => {
    if (!countryHint) return [];
    const set = new Set(timezonesForCountry(countryHint));
    return allOptions.filter((o) => set.has(o.tz));
  }, [allOptions, countryHint]);

  const rest = useMemo(() => {
    if (!suggested.length) return allOptions;
    const suggestedSet = new Set(suggested.map((s) => s.tz));
    return allOptions.filter((o) => !suggestedSet.has(o.tz));
  }, [allOptions, suggested]);

  const selectedLabel = value ? formatTimezoneLabel(value) : placeholder;

  return (
    <Popover open={open} onOpenChange={handleOpenChange}>
      <PopoverTrigger asChild>
        <Button
          id={id}
          variant="outline"
          role="combobox"
          aria-expanded={open}
          disabled={disabled}
          className={cn('w-full justify-between', !value && 'text-muted-foreground', className)}
          data-testid={testId}
        >
          <span className="truncate text-sm">{selectedLabel}</span>
          <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
        </Button>
      </PopoverTrigger>
      <PopoverContent
        className="w-[var(--radix-popper-anchor-width)] min-w-[360px] p-0"
        align="start"
      >
        <Command>
          <CommandInput placeholder="Search timezones…" />
          <CommandList>
            <CommandEmpty>No timezone found.</CommandEmpty>
            {clearable && value ? (
              <CommandGroup>
                <CommandItem
                  value="__clear__"
                  onSelect={() => {
                    onChange(null);
                    setOpen(false);
                  }}
                  className="text-muted-foreground"
                >
                  Clear selection
                </CommandItem>
              </CommandGroup>
            ) : null}
            {suggested.length > 0 ? (
              <>
                <CommandGroup heading="Suggested">
                  {suggested.map((opt) => (
                    <CommandItem
                      key={opt.tz}
                      value={opt.tz}
                      onSelect={() => {
                        onChange(opt.tz);
                        setOpen(false);
                      }}
                    >
                      <Check
                        className={cn(
                          'mr-2 h-4 w-4',
                          value === opt.tz ? 'opacity-100' : 'opacity-0',
                        )}
                      />
                      <span className="truncate text-sm">{opt.label}</span>
                    </CommandItem>
                  ))}
                </CommandGroup>
                <CommandSeparator />
              </>
            ) : null}
            <CommandGroup heading={suggested.length > 0 ? 'All zones' : undefined}>
              {rest.map((opt) => (
                <CommandItem
                  key={opt.tz}
                  value={opt.tz}
                  onSelect={() => {
                    onChange(opt.tz);
                    setOpen(false);
                  }}
                >
                  <Check
                    className={cn('mr-2 h-4 w-4', value === opt.tz ? 'opacity-100' : 'opacity-0')}
                  />
                  <span className="truncate text-sm">{opt.label}</span>
                </CommandItem>
              ))}
            </CommandGroup>
          </CommandList>
        </Command>
      </PopoverContent>
    </Popover>
  );
}
