import { useEffect, useId, useMemo, useState } from 'react'
import { useNavigate } from '@tanstack/react-router'
import { Search } from 'lucide-react'

import { Button } from '@evobgp/ui/components/button'
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
} from '@evobgp/ui/components/dialog'
import { Input } from '@evobgp/ui/components/input'
import { Kbd } from '@evobgp/ui/components/kbd'
import {
  SidebarGroup,
  SidebarGroupContent,
} from '@evobgp/ui/components/sidebar'

export type CommandPaletteItem = {
  id: string
  label: string
  description?: string
  to: string
  search?: Record<string, string>
  keywords?: string[]
}

interface CommandPaletteProps {
  items: CommandPaletteItem[]
  className?: string
  /** Hotkey-only: no sidebar search trigger (chrome parity with CFDM). */
  hotkeyOnly?: boolean
}

export function CommandPalette({ items, hotkeyOnly = false }: CommandPaletteProps) {
  const [open, setOpen] = useState(false)
  const [query, setQuery] = useState('')
  const searchInputId = useId()
  const navigate = useNavigate()

  useEffect(() => {
    function onKeyDown(event: KeyboardEvent) {
      if (event.key.toLowerCase() === 'k' && (event.metaKey || event.ctrlKey)) {
        event.preventDefault()
        setOpen(true)
      }
    }
    window.addEventListener('keydown', onKeyDown)
    return () => window.removeEventListener('keydown', onKeyDown)
  }, [])

  const filtered = useMemo(() => {
    const q = query.trim().toLowerCase()
    if (!q) return items
    return items.filter((item) => {
      const haystack = [item.label, item.description, ...(item.keywords ?? [])]
        .filter(Boolean)
        .join(' ')
        .toLowerCase()
      return haystack.includes(q)
    })
  }, [items, query])

  function go(item: CommandPaletteItem) {
    setOpen(false)
    setQuery('')
    void navigate({ to: item.to, search: item.search })
  }

  return (
    <>
      {!hotkeyOnly ? (
        <SidebarGroup className="p-0">
          <SidebarGroupContent className="relative">
            <Button
              type="button"
              variant="outline"
              className="hover:bg-background h-8 w-full justify-start pl-7 font-normal transition-[width] duration-200 ease-linear in-data-[state=collapsed]:w-8! in-data-[state=collapsed]:pl-4! in-data-[state=collapsed]:text-transparent"
              onClick={() => setOpen(true)}
            >
              Поиск…
            </Button>
            <Search
              aria-hidden
              className="pointer-events-none absolute top-1/2 left-2 size-3.5 -translate-y-1/2 opacity-50 select-none"
            />
            <Kbd className="absolute top-1/2 right-2 -translate-y-1/2 in-data-[state=collapsed]:hidden">
              ⌘K
            </Kbd>
          </SidebarGroupContent>
        </SidebarGroup>
      ) : null}

      <Dialog
        open={open}
        onOpenChange={(next) => {
          setOpen(next)
          if (!next) setQuery('')
        }}
      >
        <DialogHeader className="sr-only">
          <DialogTitle>Быстрый переход</DialogTitle>
          <DialogDescription>Навигация по разделам EvoBGP</DialogDescription>
        </DialogHeader>
        <DialogContent className="max-w-md gap-0 px-0 py-0 **:data-[slot=dialog-close]:top-3 **:data-[slot=dialog-close]:right-3">
          <div className="flex items-center gap-3 border-b px-4 py-3">
            <Search aria-hidden className="size-4 shrink-0 opacity-60" />
            <Input
              id={searchInputId}
              className="h-9 border-none p-0 shadow-none outline-none focus-visible:ring-0"
              autoFocus
              placeholder="Раздел или действие…"
              aria-label="Поиск разделов"
              value={query}
              onChange={(e) => setQuery(e.target.value)}
              onKeyDown={(e) => {
                if (e.key === 'Enter' && filtered[0]) go(filtered[0])
              }}
            />
          </div>
          <ul className="max-h-72 overflow-y-auto p-2" role="listbox">
            {filtered.length === 0 ? (
              <li className="text-muted-foreground px-2 py-6 text-center text-sm">Ничего не найдено</li>
            ) : (
              filtered.map((item) => (
                <li key={item.id}>
                  <button
                    type="button"
                    role="option"
                    className="hover:bg-accent flex w-full flex-col items-start gap-0.5 rounded-md px-3 py-2 text-left text-sm transition-colors"
                    onClick={() => go(item)}
                  >
                    <span className="font-medium">{item.label}</span>
                    {item.description ? (
                      <span className="text-muted-foreground text-xs">{item.description}</span>
                    ) : null}
                  </button>
                </li>
              ))
            )}
          </ul>
        </DialogContent>
      </Dialog>
    </>
  )
}
