"use client"

import { Search as SearchIcon, X } from "lucide-react"
import { usePathname, useRouter, useSearchParams } from "next/navigation"
import { useEffect, useRef, useState } from "react"
import { useDebouncedCallback } from "use-debounce"

import { Input } from "../ui/input"

interface SearchProps {
  paramKey?: string
  placeholder?: string
  [x: string]: any
}

export default function Search({
  paramKey = "search",
  placeholder = "Search...",
  ...props
}: SearchProps) {
  const pathname = usePathname()
  const searchParams = useSearchParams()
  const { replace } = useRouter()
  const inputRef = useRef<HTMLInputElement>(null)

  const initialValue = searchParams.get(paramKey) || ""
  const [search, setSearch] = useState(initialValue)

  useEffect(() => {
    setSearch(initialValue)
  }, [initialValue])

  const updateSearchURL = useDebouncedCallback((value: string) => {
    const params = new URLSearchParams(searchParams)
    if (value) {
      params.delete("page")
      params.set(paramKey, value)
    } else {
      params.delete(paramKey)
    }

    const query = params.toString()
    replace(query ? `${pathname}?${query}` : pathname)
  }, 300)

  const clearSearch = () => {
    setSearch("")
    const params = new URLSearchParams(searchParams)
    params.delete(paramKey)
    const query = params.toString()
    replace(query ? `${pathname}?${query}` : pathname)
  }

  useEffect(() => {
    const handler = (e: KeyboardEvent) => {
      if (e.key === "/" && document.activeElement !== inputRef.current) {
        e.preventDefault()
        inputRef.current?.focus()
      }
    }
    window.addEventListener("keydown", handler)
    return () => window.removeEventListener("keydown", handler)
  }, [])

  return (
    <div className="relative max-w-sm md:w-full" {...props}>
      <SearchIcon
        className="text-muted-foreground pointer-events-none absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2"
        aria-hidden="true"
      />

      <Input
        ref={inputRef}
        type="text"
        role="searchbox"
        aria-label="Buscar"
        placeholder={placeholder}
        value={search}
        onChange={(e) => {
          setSearch(e.target.value)
          updateSearchURL(e.target.value)
        }}
        className="pr-9 pl-9"
      />

      {search && (
        <button
          type="button"
          aria-label="Limpiar búsqueda"
          className="text-muted-foreground hover:text-foreground absolute top-1/2 right-3 -translate-y-1/2"
          onClick={clearSearch}
        >
          <X className="h-4 w-4" />
        </button>
      )}
    </div>
  )
}
