import { useState, useRef, useEffect, useMemo } from 'react'

interface SearchSelectOption {
  value: string
  label: string
}

interface SearchSelectProps {
  value: string
  onChange: (value: string) => void
  options: (string | SearchSelectOption)[]
  placeholder?: string
  emptyLabel?: string
  className?: string
  searchThreshold?: number
  size?: 'sm' | 'md'
}

export function SearchSelect({
  value,
  onChange,
  options,
  placeholder = '搜索...',
  emptyLabel = '全部',
  className = '',
  searchThreshold = 8,
  size = 'sm',
}: SearchSelectProps) {
  const [open, setOpen] = useState(false)
  const [search, setSearch] = useState('')
  const ref = useRef<HTMLDivElement>(null)

  const normalizedOptions = useMemo<SearchSelectOption[]>(() => {
    return options.map(o => typeof o === 'string' ? { value: o, label: o } : o)
  }, [options])

  const selectedLabel = normalizedOptions.find(o => o.value === value)?.label || emptyLabel

  const filtered = useMemo(() => {
    if (!search) return normalizedOptions
    return normalizedOptions.filter(o => o.label.toLowerCase().includes(search.toLowerCase()))
  }, [normalizedOptions, search])

  useEffect(() => {
    function handleClickOutside(e: MouseEvent) {
      if (ref.current && !ref.current.contains(e.target as Node)) {
        setOpen(false)
        setSearch('')
      }
    }
    document.addEventListener('mousedown', handleClickOutside)
    return () => document.removeEventListener('mousedown', handleClickOutside)
  }, [])

  const showSearch = normalizedOptions.length > searchThreshold
  const sizeClass = size === 'md' ? 'px-3 py-1.5' : 'px-2 py-1'

  return (
    <div ref={ref} className={`relative ${className}`}>
      <button
        type="button"
        onClick={() => setOpen(!open)}
        className={`flex w-full items-center justify-between rounded border bg-card ${sizeClass} text-sm hover:bg-muted/30`}
      >
        <span className={value ? '' : 'text-muted-foreground'}>{selectedLabel}</span>
        <svg className={`ml-1 h-4 w-4 shrink-0 text-muted-foreground transition-transform ${open ? 'rotate-180' : ''}`} fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
        </svg>
      </button>
      {open && (
        <div className="absolute z-50 mt-1 w-full min-w-[180px] rounded border bg-card shadow-lg">
          {showSearch && (
          <div className="p-2">
            <input
              type="text"
              autoFocus
              placeholder={placeholder}
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              className="w-full rounded border px-2 py-1 text-sm focus:outline-none focus:ring-1 focus:ring-primary"
            />
          </div>
          )}
          <div className="max-h-60 overflow-y-auto">
            <button
              type="button"
              onClick={() => { onChange(''); setOpen(false); setSearch('') }}
              className={`flex w-full items-center px-3 py-1.5 text-left text-sm hover:bg-muted/50 ${!value ? 'bg-muted/30 font-medium' : ''}`}
            >
              {emptyLabel}
            </button>
            {filtered.map(o => (
              <button
                key={o.value}
                type="button"
                onClick={() => { onChange(o.value); setOpen(false); setSearch('') }}
                className={`flex w-full items-center px-3 py-1.5 text-left text-sm hover:bg-muted/50 ${value === o.value ? 'bg-muted/30 font-medium' : ''}`}
              >
                {o.label}
              </button>
            ))}
            {filtered.length === 0 && (
              <div className="px-3 py-2 text-center text-xs text-muted-foreground">无匹配结果</div>
            )}
          </div>
        </div>
      )}
    </div>
  )
}
