import { useEffect } from "react";
import { useQueryStates } from "nuqs";
import { FileText, ListFilter, Moon, Search, Sun, X } from "lucide-react";
import {
  CommandDialog,
  CommandEmpty,
  CommandGroup,
  CommandInput,
  CommandItem,
  CommandList,
  CommandSeparator,
  CommandShortcut,
} from "@/components/ui/command";
import { useTheme } from "@/hooks/ThemeContext";
import { useHeaderConfig } from "@/hooks/useHeaderConfig";
import { tableParams, tableParamsOptions } from "@/lib/tableParams";
import { WORKFLOW_STATES } from "@/lib/workflow";
import { cn } from "@/lib/utils";

interface Props {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  onNavigate: (screenUuid: string) => void;
}

/**
 * ⌘K palette — jump between screens and apply status filters without leaving
 * the keyboard. This is a queue-triage app; reaching for the mouse to change a
 * filter is the slow path.
 */
export default function CommandPalette({ open, onOpenChange, onNavigate }: Props) {
  const { theme, toggleTheme } = useTheme();
  const { navItems } = useHeaderConfig();
  const [params, setParams] = useQueryStates(tableParams, tableParamsOptions);

  useEffect(() => {
    const onKey = (e: KeyboardEvent) => {
      if (e.key === "k" && (e.metaKey || e.ctrlKey)) {
        e.preventDefault();
        onOpenChange(!open);
      }
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [open, onOpenChange]);

  const run = (fn: () => void) => {
    fn();
    onOpenChange(false);
  };

  const filtersActive = params.status.length > 0 || !!params.q;

  return (
    <CommandDialog
      open={open}
      onOpenChange={onOpenChange}
      title="Command palette"
      description="Jump to a screen or filter the queue"
    >
      <CommandInput placeholder="Jump to a screen, or filter by status…" />
      <CommandList>
        <CommandEmpty>No matches.</CommandEmpty>

        {navItems.length > 0 && (
          <CommandGroup heading="Screens">
            {navItems.map((item) => (
              <CommandItem
                key={item.id}
                value={`screen ${item.label}`}
                onSelect={() => run(() => onNavigate(item.screen_uuid))}
              >
                <FileText className="size-3.5" aria-hidden />
                {item.label}
              </CommandItem>
            ))}
          </CommandGroup>
        )}

        <CommandSeparator />

        <CommandGroup heading="Filter by status">
          {WORKFLOW_STATES.map((s) => {
            const selected = params.status.includes(s.name);
            return (
              <CommandItem
                key={s.key}
                value={`filter ${s.label}`}
                onSelect={() =>
                  run(() =>
                    setParams({
                      status: selected
                        ? params.status.filter((x) => x !== s.name)
                        : [...params.status, s.name],
                      page: 1,
                    }),
                  )
                }
              >
                <span className={cn("size-2 shrink-0 rounded-full", s.tone.solid)} aria-hidden />
                {s.label}
                {selected && <CommandShortcut>active</CommandShortcut>}
              </CommandItem>
            );
          })}
          {filtersActive && (
            <CommandItem
              value="clear filters"
              onSelect={() => run(() => setParams({ status: [], q: "", page: 1 }))}
            >
              <X className="size-3.5" aria-hidden />
              Clear all filters
            </CommandItem>
          )}
        </CommandGroup>

        <CommandSeparator />

        <CommandGroup heading="Actions">
          <CommandItem
            value="focus search"
            onSelect={() =>
              run(() => {
                // Defer so the dialog has released focus first.
                requestAnimationFrame(() => {
                  document
                    .querySelector<HTMLInputElement>('input[aria-label="Search records"]')
                    ?.focus();
                });
              })
            }
          >
            <Search className="size-3.5" aria-hidden />
            Search records
            <CommandShortcut>/</CommandShortcut>
          </CommandItem>
          <CommandItem value="toggle theme" onSelect={() => run(toggleTheme)}>
            {theme === "dark" ? (
              <Sun className="size-3.5" aria-hidden />
            ) : (
              <Moon className="size-3.5" aria-hidden />
            )}
            Switch to {theme === "dark" ? "light" : "dark"} mode
          </CommandItem>
          <CommandItem value="filters help" disabled>
            <ListFilter className="size-3.5" aria-hidden />
            Tip: tiles on the dashboard also filter the queue
          </CommandItem>
        </CommandGroup>
      </CommandList>
    </CommandDialog>
  );
}
