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

function normalizeSearchText(value) {
  return String(value || '')
    .normalize('NFD')
    .replace(/[\u0300-\u036f]/g, '')
    .toLowerCase()
    .trim()
}

function normalizeOption(option) {
  if (typeof option === 'string') {
    const text = String(option || '').trim()
    return text ? { value: text, label: text, secondary: '' } : null
  }
  if (!option || typeof option !== 'object') return null
  const rawValue = option.value ?? option.id ?? option.key ?? ''
  const value = String(rawValue || '').trim()
  if (!value) return null
  const label = String(option.label ?? option.nome_modelo ?? option.arquivo ?? value).trim() || value
  const secondary = String(option.secondary ?? option.arquivo ?? '').trim()
  return { value, label, secondary }
}

export default function SinglePillAutocomplete({
  value,
  onChange,
  options = [],
  placeholder = 'Selecione um item',
  panelTitle = '',
  emptyMessage = 'Nenhuma sugestao encontrada.',
  loading = false,
  disabled = false,
  onOpenChange = null,
}) {
  const rootRef = useRef(null)
  const inputRef = useRef(null)
  const [query, setQuery] = useState('')
  const [open, setOpen] = useState(false)
  const [activeIndex, setActiveIndex] = useState(-1)

  const selectedValue = String(value || '')
  const normalizedOptions = useMemo(() => {
    const unique = []
    const seen = new Set()
    ;(options || []).forEach((item) => {
      const normalized = normalizeOption(item)
      if (!normalized) return
      if (seen.has(normalized.value)) return
      seen.add(normalized.value)
      unique.push(normalized)
    })
    return unique
  }, [options])

  const selectedOption = useMemo(
    () => normalizedOptions.find((item) => item.value === selectedValue) || null,
    [normalizedOptions, selectedValue],
  )

  const queryNormalized = normalizeSearchText(query)
  const filteredOptions = useMemo(() => {
    if (loading) return []
    if (!queryNormalized) return normalizedOptions.slice(0, 160)
    return normalizedOptions
      .filter((item) => (
        normalizeSearchText(item.label).includes(queryNormalized)
        || normalizeSearchText(item.secondary).includes(queryNormalized)
      ))
      .slice(0, 160)
  }, [loading, normalizedOptions, queryNormalized])

  useEffect(() => {
    if (!open) return undefined
    function onDocumentMouseDown(event) {
      if (!rootRef.current) return
      if (!rootRef.current.contains(event.target)) setOpen(false)
    }
    document.addEventListener('mousedown', onDocumentMouseDown)
    return () => document.removeEventListener('mousedown', onDocumentMouseDown)
  }, [open])

  useEffect(() => {
    if (typeof onOpenChange !== 'function') return
    onOpenChange(Boolean(open && !disabled))
  }, [open, disabled, onOpenChange])

  useEffect(() => () => {
    if (typeof onOpenChange === 'function') onOpenChange(false)
  }, [onOpenChange])

  useEffect(() => {
    if (!open || filteredOptions.length === 0) {
      setActiveIndex(-1)
      return
    }
    if (activeIndex >= filteredOptions.length) setActiveIndex(filteredOptions.length - 1)
  }, [activeIndex, filteredOptions, open])

  function emitChange(nextValue) {
    if (typeof onChange === 'function') onChange(String(nextValue || ''))
  }

  function selectOption(option) {
    if (!option) return
    emitChange(option.value)
    setQuery('')
    setOpen(false)
    setActiveIndex(-1)
  }

  function clearSelection(event) {
    event.preventDefault()
    event.stopPropagation()
    emitChange('')
    setQuery('')
    setOpen(true)
    setActiveIndex(-1)
    window.requestAnimationFrame(() => inputRef.current?.focus())
  }

  function onInputChange(event) {
    if (disabled) return
    setQuery(event.target.value)
    setOpen(true)
    setActiveIndex(-1)
  }

  function onInputFocus() {
    if (disabled) return
    setOpen(true)
    setActiveIndex(-1)
  }

  function onInputKeyDown(event) {
    if (disabled) return

    if (event.key === 'Escape') {
      setOpen(false)
      return
    }

    if (event.key === 'Backspace' && !query && selectedOption) {
      emitChange('')
      setOpen(true)
      return
    }

    if (!filteredOptions.length) return

    if (event.key === 'ArrowDown') {
      event.preventDefault()
      setOpen(true)
      setActiveIndex((prev) => (prev < 0 ? 0 : (prev + 1) % filteredOptions.length))
      return
    }

    if (event.key === 'ArrowUp') {
      event.preventDefault()
      setOpen(true)
      setActiveIndex((prev) => {
        if (prev < 0) return filteredOptions.length - 1
        return (prev - 1 + filteredOptions.length) % filteredOptions.length
      })
      return
    }

    if (event.key === 'Enter') {
      event.preventDefault()
      if (activeIndex >= 0 && activeIndex < filteredOptions.length) {
        selectOption(filteredOptions[activeIndex])
        return
      }
      if (filteredOptions.length === 1) {
        selectOption(filteredOptions[0])
      }
    }
  }

  return (
    <div className={`chip-autocomplete chip-autocomplete-single${open ? ' is-open' : ''}${disabled ? ' is-disabled' : ''}`} ref={rootRef}>
      <div className={`chip-autocomplete-single-control${disabled ? ' is-disabled' : ''}`}>
        {selectedOption ? (
          <span className="chip-autocomplete-selected chip-autocomplete-selected-inline">
            <span>{selectedOption.label}</span>
            {!disabled ? (
              <button
                type="button"
                className="chip-autocomplete-selected-remove"
                onMouseDown={clearSelection}
                onClick={(event) => {
                  event.preventDefault()
                  event.stopPropagation()
                }}
                aria-label={`Remover ${selectedOption.label}`}
              >
                ×
              </button>
            ) : null}
          </span>
        ) : null}
        <input
          ref={inputRef}
          type="text"
          className="chip-autocomplete-single-input"
          value={query}
          onChange={onInputChange}
          onFocus={onInputFocus}
          onKeyDown={onInputKeyDown}
          placeholder={selectedOption ? '' : placeholder}
          autoComplete="off"
          autoCorrect="off"
          autoCapitalize="none"
          spellCheck={false}
          disabled={disabled}
        />
      </div>

      {open && !disabled ? (
        <div className="chip-autocomplete-panel" role="listbox">
          {panelTitle ? <div className="chip-autocomplete-panel-head">{panelTitle}</div> : null}
          {loading ? (
            <div className="chip-autocomplete-empty">Carregando lista...</div>
          ) : filteredOptions.length ? (
            <div className="chip-autocomplete-chip-wrap">
              {filteredOptions.map((item, idx) => (
                <button
                  type="button"
                  key={`single-chip-${item.value}-${idx}`}
                  className={`chip-autocomplete-chip${idx === activeIndex ? ' is-active' : ''}`}
                  onMouseDown={(event) => {
                    event.preventDefault()
                    event.stopPropagation()
                    selectOption(item)
                  }}
                  title={item.secondary ? `${item.label} | ${item.secondary}` : item.label}
                >
                  {item.label}
                </button>
              ))}
            </div>
          ) : (
            <div className="chip-autocomplete-empty">
              {emptyMessage}
            </div>
          )}
        </div>
      ) : null}
    </div>
  )
}
