"use client";

import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { useRouter } from "next/navigation";
import { CornerDownLeft, Search } from "lucide-react";
import { useNavItems, type NavItem } from "@/features/navigation";
import { useI18n, useT } from "@/i18n";
import { cn } from "@/lib/cn";
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";

function runPrefetch(item: NavItem) {
  item.prefetch?.();
}

/** Lets any header button open the same instance the ⌘K listener controls. */
export function openCommandPalette() {
  window.dispatchEvent(new CustomEvent("kapitano:open-command"));
}

/**
 * ⌘K / Ctrl+K command palette: type to filter every reachable page, arrow keys
 * to move, Enter to go, prefetch on hover. Keyboard-first, shares the exact nav
 * model with the sidebar so permissions never drift.
 */
export function CommandPalette() {
  const t = useT();
  const { dir } = useI18n();
  const router = useRouter();
  const groups = useNavItems();
  const [open, setOpen] = useState(false);
  const [query, setQuery] = useState("");
  const [activeIndex, setActiveIndex] = useState(0);
  const inputRef = useRef<HTMLInputElement>(null);

  const items = useMemo(() => groups.flatMap((g) => g.items.filter((i) => i.visible())), [groups]);

  const results = useMemo(() => {
    const q = query.trim().toLowerCase();
    if (!q) return items;
    return items.filter(
      (item) => item.label.toLowerCase().includes(q) || item.href.toLowerCase().includes(q),
    );
  }, [items, query]);

  const openPalette = useCallback(() => {
    setQuery("");
    setActiveIndex(0);
    setOpen(true);
  }, []);

  useEffect(() => {
    function onKeyDown(event: KeyboardEvent) {
      if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === "k") {
        event.preventDefault();
        openPalette();
      }
    }
    function onOpenRequest() {
      openPalette();
    }
    window.addEventListener("keydown", onKeyDown);
    window.addEventListener("kapitano:open-command", onOpenRequest);
    return () => {
      window.removeEventListener("keydown", onKeyDown);
      window.removeEventListener("kapitano:open-command", onOpenRequest);
    };
  }, [openPalette]);

  useEffect(() => {
    if (!open) return;
    const id = window.setTimeout(() => inputRef.current?.focus(), 50);
    return () => window.clearTimeout(id);
  }, [open]);

  function go(item: NavItem) {
    setOpen(false);
    router.push(item.href);
  }

  function onKeyDown(event: React.KeyboardEvent<HTMLInputElement>) {
    if (event.key === "ArrowDown") {
      event.preventDefault();
      if (results.length > 0) setActiveIndex((i) => (i + 1) % results.length);
    } else if (event.key === "ArrowUp") {
      event.preventDefault();
      if (results.length > 0) setActiveIndex((i) => (i - 1 + results.length) % results.length);
    } else if (event.key === "Enter" && results[activeIndex]) {
      event.preventDefault();
      go(results[activeIndex]);
    }
  }

  return (
    <Dialog open={open} onOpenChange={setOpen}>
      <DialogContent className="gap-0 overflow-hidden p-0" aria-describedby={undefined}>
        <DialogHeader className="border-b px-4 py-3">
          <div className="flex items-center gap-2">
            <Search className="h-4 w-4 shrink-0 text-muted-foreground" aria-hidden />
            <DialogTitle className="sr-only">{t("widgets.commandPalette.title")}</DialogTitle>
            <Input
              ref={inputRef}
              value={query}
              onChange={(e) => {
                setQuery(e.target.value);
                setActiveIndex(0);
              }}
              onKeyDown={onKeyDown}
              placeholder={t("widgets.commandPalette.placeholder")}
              className="h-8 border-0 bg-transparent px-0 shadow-none focus-visible:ring-0"
              aria-label={t("widgets.commandPalette.placeholder")}
            />
          </div>
        </DialogHeader>
        <div className="max-h-[42vh] overflow-y-auto px-1.5 py-2">
          {results.length === 0 ? (
            <p className="px-3 py-6 text-center text-sm text-muted-foreground">
              {t("widgets.commandPalette.empty")}
            </p>
          ) : (
            <ul className="space-y-0.5">
              {results.map((item, index) => {
                const Icon = item.icon;
                const active = index === activeIndex;
                return (
                  <li key={item.href}>
                    <button
                      type="button"
                      onMouseMove={() => setActiveIndex(index)}
                      onMouseDown={(e) => {
                        e.preventDefault();
                        go(item);
                      }}
                      onMouseEnter={() => runPrefetch(item)}
                      className={cn(
                        "flex w-full items-center gap-3 rounded-md px-3 py-2 text-start text-sm transition-colors",
                        active ? "bg-muted text-foreground" : "text-muted-foreground",
                      )}
                    >
                      <Icon className="h-4 w-4 shrink-0" aria-hidden />
                      <span className="min-w-0 flex-1 truncate">{item.label}</span>
                      <span
                        className={cn(
                          "text-xs",
                          active ? "text-foreground/70" : "text-muted-foreground/70",
                        )}
                      >
                        {item.href}
                      </span>
                    </button>
                  </li>
                );
              })}
            </ul>
          )}
        </div>
        <div className="flex items-center justify-between border-t px-4 py-2 text-xs text-muted-foreground">
          <span className="inline-flex items-center gap-1" dir={dir}>
            <CornerDownLeft className="h-3 w-3" aria-hidden />
            {t("widgets.commandPalette.open")}
          </span>
          <span>{t("widgets.commandPalette.hint")}</span>
        </div>
      </DialogContent>
    </Dialog>
  );
}