import { useEffect, useRef, useState } from 'react'
import { searchDbWords, type DbWordSearchResult } from '../api'

interface WordAutocompleteProps {
  value: string
  onChange: (v: string) => void
  onSubmit: () => void
  onPick?: (word: DbWordSearchResult) => void
  token: string | null
  placeholder?: string
  className?: string
  inputStyle?: React.CSSProperties
  minChars?: number
  debounceMs?: number
  excludeTitles?: string[]
}

export default function WordAutocomplete({
  value,
  onChange,
  onSubmit,
  onPick,
  token,
  placeholder,
  className,
  inputStyle,
  minChars = 1,
  debounceMs = 180,
  excludeTitles = [],
}: WordAutocompleteProps) {
  const [results, setResults] = useState<DbWordSearchResult[]>([])
  const [open, setOpen] = useState(false)
  const [loading, setLoading] = useState(false)
  const [highlight, setHighlight] = useState(0)
  const wrapRef = useRef<HTMLDivElement>(null)
  const reqIdRef = useRef(0)
  const excludeSet = new Set(excludeTitles.map(s => s.trim().toLowerCase()))

  // Debounced search
  useEffect(() => {
    if (!token) return
    const trimmed = value.trim()
    if (trimmed.length < minChars) {
      setResults([])
      setOpen(false)
      return
    }
    const myId = ++reqIdRef.current
    setLoading(true)
    const t = setTimeout(() => {
      searchDbWords(trimmed, token, 10)
        .then(r => {
          if (myId !== reqIdRef.current) return
          const filtered = r.filter(x => !excludeSet.has(x.titel_de.trim().toLowerCase()))
          setResults(filtered)
          setOpen(filtered.length > 0)
          setHighlight(0)
        })
        .finally(() => {
          if (myId === reqIdRef.current) setLoading(false)
        })
    }, debounceMs)
    return () => clearTimeout(t)
  }, [value, token, minChars, debounceMs])

  // Close on outside click
  useEffect(() => {
    const onClick = (e: MouseEvent) => {
      if (!wrapRef.current) return
      if (!wrapRef.current.contains(e.target as Node)) setOpen(false)
    }
    document.addEventListener('mousedown', onClick)
    return () => document.removeEventListener('mousedown', onClick)
  }, [])

  const pick = (r: DbWordSearchResult) => {
    onChange(r.titel_de)
    onPick?.(r)
    setOpen(false)
  }

  const onKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
    if (open && results.length > 0) {
      if (e.key === 'ArrowDown') {
        e.preventDefault()
        setHighlight(h => (h + 1) % results.length)
        return
      }
      if (e.key === 'ArrowUp') {
        e.preventDefault()
        setHighlight(h => (h - 1 + results.length) % results.length)
        return
      }
      if (e.key === 'Escape') {
        e.preventDefault()
        setOpen(false)
        return
      }
      if (e.key === 'Tab') {
        e.preventDefault()
        pick(results[highlight])
        return
      }
      if (e.key === 'Enter') {
        // If user has typed something matching a suggestion exactly, prefer submit; else pick.
        const exact = results.find(r => r.titel_de.trim().toLowerCase() === value.trim().toLowerCase())
        if (exact) {
          setOpen(false)
          onSubmit()
        } else {
          e.preventDefault()
          pick(results[highlight])
        }
        return
      }
    }
    if (e.key === 'Enter') {
      onSubmit()
    }
  }

  return (
    <div ref={wrapRef} className={`wac-wrap${className ? ' ' + className : ''}`}>
      <input
        type="text"
        value={value}
        onChange={e => onChange(e.target.value)}
        onKeyDown={onKeyDown}
        onFocus={() => { if (results.length > 0) setOpen(true) }}
        placeholder={placeholder}
        autoComplete="off"
        spellCheck={false}
        style={inputStyle}
      />
      {open && (
        <div className="wac-panel" role="listbox">
          {loading && results.length === 0 && (
            <div className="wac-empty">Suche…</div>
          )}
          {results.map((r, i) => (
            <button
              key={r.id}
              type="button"
              role="option"
              className={`wac-item${i === highlight ? ' wac-item-active' : ''}`}
              onMouseDown={e => { e.preventDefault(); pick(r) }}
              onMouseEnter={() => setHighlight(i)}
            >
              <span className="wac-item-title">{r.titel_de}</span>
              {r.level != null && <span className="wac-item-meta">L{r.level}</span>}
            </button>
          ))}
        </div>
      )}
    </div>
  )
}
