"use client"

import { useState, useRef, useEffect } from "react"
import { CheckIcon, ChevronDownIcon, Loader2Icon, PlusIcon } from "lucide-react"
import { toast } from "sonner"

import { useFetchCategoriesQuery, useCreateCategoryMutation } from "@/src/state/menu"
import type { MenuCategory } from "@/src/state/menu"
import { extractErrorMessage } from "./utils"

type Props = {
  value: string
  onChange: (id: string) => void
  disabled?: boolean
}

export function CategoryCombobox({ value, onChange, disabled }: Props) {
  const { data, isLoading } = useFetchCategoriesQuery({ limit: 100 })
  const [createCategory, { isLoading: isCreating }] = useCreateCategoryMutation()

  const [open, setOpen] = useState(false)
  const [search, setSearch] = useState("")
  const containerRef = useRef<HTMLDivElement>(null)

  const categories = data?.data?.categories ?? []
  const selected = categories.find((c) => c.id === value)

  const filtered = categories.filter((c) =>
    c.name.toLowerCase().includes(search.toLowerCase())
  )

  const canCreate =
    search.trim().length >= 2 &&
    !categories.some((c) => c.name.toLowerCase() === search.trim().toLowerCase())

  useEffect(() => {
    const handleClickOutside = (e: MouseEvent) => {
      if (containerRef.current && !containerRef.current.contains(e.target as Node)) {
        setOpen(false)
        setSearch("")
      }
    }
    document.addEventListener("mousedown", handleClickOutside)
    return () => document.removeEventListener("mousedown", handleClickOutside)
  }, [])

  const handleSelect = (category: MenuCategory) => {
    onChange(category.id)
    setOpen(false)
    setSearch("")
  }

  const handleCreate = async () => {
    const name = search.trim()
    try {
      const res = await createCategory({ name }).unwrap()
      onChange(res.data.id)
      setOpen(false)
      setSearch("")
      toast.success("Catégorie créée")
    } catch (err) {
      toast.error(extractErrorMessage(err, "Erreur lors de la création"))
    }
  }

  return (
    <div ref={containerRef} className="relative">
      <button
        type="button"
        disabled={disabled || isLoading}
        onClick={() => setOpen((o) => !o)}
        className="flex h-10 w-full items-center justify-between rounded-lg border border-input bg-transparent px-3 py-2 text-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50"
      >
        <span className={selected ? "text-foreground" : "text-muted-foreground"}>
          {isLoading ? "Chargement…" : selected ? selected.name : "Sélectionner une catégorie"}
        </span>
        <ChevronDownIcon className="size-4 text-muted-foreground shrink-0" />
      </button>

      {open && (
        <div className="absolute z-50 mt-1 w-full rounded-lg border bg-white shadow-md">
          <div className="p-2">
            <input
              autoFocus
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              placeholder="Rechercher ou créer…"
              className="w-full rounded-md border border-input px-3 py-1.5 text-sm outline-none focus:ring-2 focus:ring-ring"
            />
          </div>

          <ul className="max-h-52 overflow-y-auto pb-1">
            {filtered.length === 0 && !canCreate && (
              <li className="px-3 py-2 text-sm text-muted-foreground">Aucune catégorie trouvée</li>
            )}

            {filtered.map((cat) => (
              <li key={cat.id}>
                <button
                  type="button"
                  onClick={() => handleSelect(cat)}
                  className="flex w-full items-center gap-2 px-3 py-2 text-sm hover:bg-muted/60 transition-colors"
                >
                  <CheckIcon
                    className={`size-4 shrink-0 ${cat.id === value ? "text-primary opacity-100" : "opacity-0"}`}
                  />
                  {cat.name}
                </button>
              </li>
            ))}

            {canCreate && (
              <li>
                <button
                  type="button"
                  disabled={isCreating}
                  onClick={handleCreate}
                  className="flex w-full items-center gap-2 px-3 py-2 text-sm text-primary hover:bg-muted/60 transition-colors"
                >
                  {isCreating ? (
                    <Loader2Icon className="size-4 animate-spin shrink-0" />
                  ) : (
                    <PlusIcon className="size-4 shrink-0" />
                  )}
                  Créer &quot;{search.trim()}&quot;
                </button>
              </li>
            )}
          </ul>
        </div>
      )}
    </div>
  )
}
