import { useEffect, useMemo, useRef, useState } from 'react'
import { ChevronDown, X } from 'lucide-react'
import { cn } from '@/lib/cn'

// S59 — Searchable combobox (UAT 06-11: "nên có lọc để tự đánh chữ" — dropdown
// 70+ mục Hạng mục/Dự án khó dò bằng native <select>). Input gõ-để-lọc theo
// label, match BỎ DẤU tiếng Việt (gõ "be tong" trúng "Bê tông"). Tự render
// listbox absolute — không thêm lib ngoài. Style mirror ui/Input density S55.
// Required-gate: form dùng canSubmit/disabled button (không dựa native required).
export type SearchableOption = { value: string; label: string }

function fold(s: string): string {
  return s.normalize('NFD').replace(/[̀-ͯ]/g, '').replace(/đ/g, 'd').replace(/Đ/g, 'D').toLowerCase()
}

export function SearchableSelect({
  options,
  value,
  onChange,
  placeholder = '— Chọn —',
  disabled,
  className,
}: {
  options: SearchableOption[]
  value: string
  onChange: (value: string) => void
  placeholder?: string
  disabled?: boolean
  className?: string
}) {
  const [open, setOpen] = useState(false)
  const [query, setQuery] = useState('')
  const [hi, setHi] = useState(0)
  const wrapRef = useRef<HTMLDivElement>(null)
  const listRef = useRef<HTMLUListElement>(null)

  const selected = options.find(o => o.value === value) ?? null
  const filtered = useMemo(() => {
    const q = fold(query.trim())
    return q ? options.filter(o => fold(o.label).includes(q)) : options
  }, [options, query])

  // Click ngoài → đóng + reset query (input quay về hiển thị label đã chọn).
  useEffect(() => {
    function onDocMouseDown(e: MouseEvent) {
      if (!wrapRef.current?.contains(e.target as Node)) {
        setOpen(false)
        setQuery('')
      }
    }
    document.addEventListener('mousedown', onDocMouseDown)
    return () => document.removeEventListener('mousedown', onDocMouseDown)
  }, [])

  // Giữ item highlight trong khung nhìn khi điều hướng bàn phím.
  useEffect(() => {
    listRef.current?.children[hi]?.scrollIntoView({ block: 'nearest' })
  }, [hi, open])

  function pick(v: string) {
    onChange(v)
    setOpen(false)
    setQuery('')
  }

  return (
    <div ref={wrapRef} className={cn('relative', className)}>
      <input
        type="text"
        role="combobox"
        aria-expanded={open}
        disabled={disabled}
        value={open ? query : (selected?.label ?? '')}
        placeholder={selected?.label ?? placeholder}
        onFocus={() => { if (!disabled) { setOpen(true); setQuery(''); setHi(0) } }}
        onChange={e => { setQuery(e.target.value); setOpen(true); setHi(0) }}
        onKeyDown={e => {
          if (!open && (e.key === 'ArrowDown' || e.key === 'Enter')) { setOpen(true); return }
          if (e.key === 'ArrowDown') { e.preventDefault(); setHi(h => Math.min(h + 1, filtered.length - 1)) }
          else if (e.key === 'ArrowUp') { e.preventDefault(); setHi(h => Math.max(h - 1, 0)) }
          else if (e.key === 'Enter') { e.preventDefault(); if (filtered[hi]) pick(filtered[hi].value) }
          else if (e.key === 'Escape') { setOpen(false); setQuery('') }
        }}
        className={cn(
          'h-8 w-full rounded-lg border border-slate-300 bg-white px-3 py-1.5 pr-14 text-sm text-slate-900',
          'placeholder:text-slate-400',
          'transition-[border-color,box-shadow] focus-visible:border-brand-400 focus-visible:ring-2 focus-visible:ring-brand-500/15',
          'disabled:cursor-not-allowed disabled:bg-slate-50 disabled:opacity-70',
        )}
      />
      <span className="pointer-events-none absolute inset-y-0 right-2.5 flex items-center">
        <ChevronDown className="h-3.5 w-3.5 text-slate-400" />
      </span>
      {selected && !disabled && !open && (
        <button
          type="button"
          aria-label="Xóa lựa chọn"
          onClick={() => pick('')}
          className="absolute inset-y-0 right-8 flex items-center text-slate-400 hover:text-slate-600"
        >
          <X className="h-3.5 w-3.5" />
        </button>
      )}
      {open && !disabled && (
        <ul
          ref={listRef}
          role="listbox"
          className="absolute z-50 mt-1 max-h-64 w-full overflow-y-auto rounded-lg border border-slate-200 bg-white py-1 shadow-lg"
        >
          {filtered.length === 0 && (
            <li className="px-3 py-2 text-xs text-slate-400">Không tìm thấy mục nào.</li>
          )}
          {filtered.map((o, i) => (
            <li key={o.value}>
              <button
                type="button"
                onMouseDown={e => e.preventDefault()}
                onClick={() => pick(o.value)}
                onMouseEnter={() => setHi(i)}
                className={cn(
                  'block w-full px-3 py-1.5 text-left text-xs',
                  i === hi ? 'bg-brand-50 text-brand-700' : 'text-slate-700',
                  o.value === value && 'font-semibold',
                )}
              >
                {o.label}
              </button>
            </li>
          ))}
        </ul>
      )}
    </div>
  )
}
