'use client'
import { useState, useEffect, useRef, type CSSProperties, type ReactNode } from 'react'

type GeoData = Record<string, Record<string, string[]>>

interface BarrioAutocompleteFieldProps {
  name: string
  label: ReactNode
  value: string
  required: boolean
  departamento?: string | null
  ciudad?: string | null
  onChange: (value: string) => void
  error?: string
}

export function BarrioAutocompleteField({
  name,
  label,
  value,
  required,
  departamento,
  ciudad,
  onChange,
  error,
}: BarrioAutocompleteFieldProps) {
  const [geoData, setGeoData] = useState<GeoData | null>(null)
  const [open, setOpen] = useState(false)
  const [activeIdx, setActiveIdx] = useState(-1)
  const [dropdownStyle, setDropdownStyle] = useState<CSSProperties>({})
  const inputRef = useRef<HTMLInputElement>(null)

  useEffect(() => {
    fetch('/data/geo_paraguay_full.json')
      .then((r) => r.json())
      .then(setGeoData)
      .catch(() => {})
  }, [])

  // Close dropdown on scroll so the fixed-position list doesn't drift from the input
  useEffect(() => {
    if (!open) return
    const close = () => setOpen(false)
    window.addEventListener('scroll', close, { passive: true, capture: true })
    return () => window.removeEventListener('scroll', close, { capture: true })
  }, [open])

  function computeDropdownStyle() {
    if (!inputRef.current) return
    const rect = inputRef.current.getBoundingClientRect()
    setDropdownStyle({
      top: rect.bottom + 4,
      left: rect.left,
      width: rect.width,
    })
  }

  const barrios: string[] = (() => {
    if (!geoData) return []
    if (departamento && ciudad) {
      return geoData[departamento]?.[ciudad] ?? []
    }
    if (departamento) {
      return Object.values(geoData[departamento] ?? {}).flat()
    }
    return Object.values(geoData).flatMap((d) => Object.values(d).flat())
  })()

  const query = value.trim().toLowerCase()
  const suggestions =
    query.length >= 2
      ? barrios.filter((b) => b.toLowerCase().includes(query)).slice(0, 10)
      : []

  function handleInput(v: string) {
    onChange(v)
    computeDropdownStyle()
    setOpen(true)
    setActiveIdx(-1)
  }

  function select(barrio: string) {
    onChange(barrio)
    setOpen(false)
    setActiveIdx(-1)
  }

  function handleKeyDown(e: React.KeyboardEvent) {
    if (!open || suggestions.length === 0) return
    if (e.key === 'ArrowDown') {
      e.preventDefault()
      setActiveIdx((i) => Math.min(i + 1, suggestions.length - 1))
    } else if (e.key === 'ArrowUp') {
      e.preventDefault()
      setActiveIdx((i) => Math.max(i - 1, -1))
    } else if (e.key === 'Enter' && activeIdx >= 0) {
      e.preventDefault()
      select(suggestions[activeIdx])
    } else if (e.key === 'Escape') {
      setOpen(false)
    }
  }

  const listId = `${name}-suggestions`

  return (
    <div className="question-fieldset">
      <label className="question-legend" htmlFor={name}>
        {label}
        {required && <span className="required-mark" aria-hidden="true"> *</span>}
        {required && <span className="sr-only"> (obligatorio)</span>}
      </label>
      <div className="barrio-autocomplete-wrapper">
        <input
          type="text"
          id={name}
          name={name}
          value={value}
          required={required}
          aria-required={required}
          aria-describedby={error ? `${name}-error` : undefined}
          aria-invalid={!!error}
          aria-autocomplete="list"
          aria-controls={open && suggestions.length > 0 ? listId : undefined}
          aria-activedescendant={activeIdx >= 0 ? `${name}-opt-${activeIdx}` : undefined}
          autoComplete="off"
          className="text-short-input"
          ref={inputRef}
          onChange={(e) => handleInput(e.target.value)}
          onKeyDown={handleKeyDown}
          onFocus={() => { if (suggestions.length > 0) { computeDropdownStyle(); setOpen(true) } }}
          onBlur={() => setTimeout(() => setOpen(false), 150)}
        />
        {open && suggestions.length > 0 && (
          <ul
            id={listId}
            role="listbox"
            className="barrio-autocomplete-list"
            aria-label="Sugerencias de barrios"
            style={dropdownStyle}
          >
            {suggestions.map((barrio, i) => (
              <li
                key={barrio}
                id={`${name}-opt-${i}`}
                role="option"
                aria-selected={i === activeIdx}
                className={`barrio-autocomplete-item${i === activeIdx ? ' barrio-autocomplete-item--active' : ''}`}
                onMouseDown={() => select(barrio)}
                onTouchEnd={(e) => { e.preventDefault(); select(barrio) }}
              >
                {barrio}
              </li>
            ))}
          </ul>
        )}
      </div>
      {error && (
        <p role="alert" className="field-error" id={`${name}-error`}>
          {error}
        </p>
      )}
    </div>
  )
}
