import { useMemo, useRef, useState } from 'react';
import { Check } from 'lucide-react';
import { cn } from '@/lib/utils';
import { Input } from '@/components/ui/input';
import { Popover, PopoverContent, PopoverAnchor } from '@/components/ui/popover';
import { searchFieldClassName } from './searchFieldStyles';

export interface BatchIdComboboxOption {
  value: string;
  label?: string;
  searchText?: string;
}

type BatchIdComboboxInputOption = string | BatchIdComboboxOption;

interface BatchIdComboboxProps {
  value: string;
  onChange: (value: string) => void;
  options: BatchIdComboboxInputOption[];
  placeholder?: string;
  closedPlaceholder?: string;
  allLabel?: string | null;
  emptyText?: string;
  className?: string;
}

export function BatchIdCombobox({
  value,
  onChange,
  options,
  placeholder = '请输入批次ID',
  closedPlaceholder,
  allLabel = '全部批次',
  emptyText = '无匹配批次',
  className,
}: BatchIdComboboxProps) {
  const [open, setOpen] = useState(false);
  const [inputValue, setInputValue] = useState('');
  const inputRef = useRef<HTMLInputElement>(null);

  const normalizedOptions = useMemo(() => {
    return options.map(option => {
      if (typeof option === 'string') {
        return {
          value: option,
          label: option,
          searchText: option.toLowerCase(),
        };
      }

      const label = option.label ?? option.value;
      return {
        value: option.value,
        label,
        searchText: [option.value, label, option.searchText]
          .filter(Boolean)
          .join(' ')
          .toLowerCase(),
      };
    });
  }, [options]);

  const selectedOption = useMemo(
    () => normalizedOptions.find(option => option.value === value),
    [normalizedOptions, value],
  );

  const filtered = inputValue
    ? normalizedOptions.filter(option => option.searchText.includes(inputValue.trim().toLowerCase()))
    : normalizedOptions;

  const displayValue = open ? inputValue : (selectedOption?.label ?? value);

  function handleSelect(selected: string) {
    onChange(selected);
    setInputValue('');
    setOpen(false);
    inputRef.current?.blur();
  }

  function handleFocus() {
    setInputValue('');
    setOpen(true);
  }

  function handleBlur() {
    // 延迟关闭，确保 item 点击事件先触发
    setTimeout(() => setOpen(false), 150);
  }

  function handleInputChange(e: React.ChangeEvent<HTMLInputElement>) {
    setInputValue(e.target.value);
    if (!open) setOpen(true);
  }

  return (
    <Popover open={open}>
      <PopoverAnchor asChild>
        <Input
          ref={inputRef}
          value={displayValue}
          placeholder={open ? placeholder : (value ? undefined : (closedPlaceholder ?? allLabel ?? placeholder))}
          onChange={handleInputChange}
          onFocus={handleFocus}
          onBlur={handleBlur}
          className={cn(searchFieldClassName, 'w-48 cursor-pointer', className)}
          autoComplete="off"
        />
      </PopoverAnchor>
      <PopoverContent
        className="border-[hsl(220_13%_91%)] bg-white p-1 text-[hsl(222_47%_11%)]"
        style={{ width: 'var(--radix-popover-trigger-width)' }}
        align="start"
        onOpenAutoFocus={e => e.preventDefault()}
      >
        <ul className="max-h-60 overflow-auto">
          {allLabel !== null ? (
            <li
              className={cn(
                'flex cursor-pointer select-none items-center rounded px-2 py-1.5 text-sm hover:bg-[hsl(221_83%_95%)] hover:text-[hsl(221_83%_40%)]',
                value === '' && 'font-medium',
              )}
              onMouseDown={e => { e.preventDefault(); handleSelect(''); }}
            >
              <Check className={cn('mr-2 h-4 w-4 shrink-0', value === '' ? 'opacity-100' : 'opacity-0')} />
              {allLabel}
            </li>
          ) : null}
          {filtered.length === 0 ? (
            <li className="px-2 py-1.5 text-sm text-[hsl(215_16%_47%)]">{emptyText}</li>
          ) : (
            filtered.map(option => (
              <li
                key={option.value}
                className={cn(
                  'flex cursor-pointer select-none items-center rounded px-2 py-1.5 text-sm hover:bg-[hsl(221_83%_95%)] hover:text-[hsl(221_83%_40%)]',
                  value === option.value && 'font-medium',
                )}
                onMouseDown={e => { e.preventDefault(); handleSelect(option.value); }}
              >
                <Check className={cn('mr-2 h-4 w-4 shrink-0', value === option.value ? 'opacity-100' : 'opacity-0')} />
                {option.label}
              </li>
            ))
          )}
        </ul>
      </PopoverContent>
    </Popover>
  );
}
