import { TextInput } from '@mantine/core'
import { useCallback, useEffect, useRef, useState } from 'react'

import { CSS, DEFAULTS } from '../../core/constants'
import { useGriddyStore } from '../../core/GriddyStore'
import styles from '../../styles/griddy.module.css'

export function SearchOverlay() {
  const table = useGriddyStore((s) => s._table)
  const isSearchOpen = useGriddyStore((s) => s.isSearchOpen)
  const setSearchOpen = useGriddyStore((s) => s.setSearchOpen)
  const search = useGriddyStore((s) => s.search)

  const [query, setQuery] = useState('')
  const inputRef = useRef<HTMLInputElement>(null)
  const timerRef = useRef<null | ReturnType<typeof setTimeout>>(null)

  const debounceMs = search?.debounceMs ?? DEFAULTS.searchDebounceMs
  const placeholder = search?.placeholder ?? 'Search...'

  useEffect(() => {
    if (isSearchOpen) {
      inputRef.current?.focus()
    } else {
      setQuery('')
      table?.setGlobalFilter(undefined)
    }
  }, [isSearchOpen, table])

  const handleChange = useCallback((value: string) => {
    setQuery(value)

    if (timerRef.current) clearTimeout(timerRef.current)
    timerRef.current = setTimeout(() => {
      table?.setGlobalFilter(value || undefined)
    }, debounceMs)
  }, [table, debounceMs])

  const handleKeyDown = useCallback((e: React.KeyboardEvent) => {
    if (e.key === 'Escape') {
      e.preventDefault()
      e.stopPropagation()
      setSearchOpen(false)
    }
  }, [setSearchOpen])

  if (!isSearchOpen) return null

  return (
    <div className={styles[CSS.searchOverlay]}>
      <TextInput
        aria-label="Search grid"
        onChange={(e) => handleChange(e.currentTarget.value)}
        onKeyDown={handleKeyDown}
        placeholder={placeholder}
        ref={inputRef}
        size="xs"
        value={query}
      />
    </div>
  )
}
