"use client";
import { Command } from "cmdk";
import { useEffect, useState } from "react";
import { useRouter } from "next/navigation";
import { useQuery } from "@tanstack/react-query";
import { FileText, Plus, Sparkles, Home, Share2, Settings, Search, BarChart3, Trash2, Database, FlaskConical, Moon, Sun, Columns3, Bot, Inbox } from "lucide-react";
import { useUI } from "@/lib/client/store";
import { api } from "@/lib/client/api";
import type { TreeNode } from "./types";
import { cn } from "@/lib/utils";
export function CommandPalette({ tree }: { tree: TreeNode[] }) {
const ui = useUI(); const r = useRouter(); const [q, setQ] = useState(""); const [mode, setMode] = useState<"quick" | "full">("quick");
useEffect(() => { if (!ui.paletteOpen) { setQ(""); setMode("quick"); } }, [ui.paletteOpen]);
const { data: hits = [] } = useQuery({ queryKey: ["search", mode, q], queryFn: () => api(`/api/search?mode=${mode === "full" ? "hybrid" : "quick"}&q=${encodeURIComponent(q)}&limit=12`), enabled: ui.paletteOpen && (mode === "full" ? q.length > 2 : true), staleTime: 5000 });
const go = (href: string) => { ui.set({ paletteOpen: false }); r.push(href); };
const run = (fn: () => void) => { ui.set({ paletteOpen: false }); fn(); };
if (!ui.paletteOpen) return null;
const Item = ({ onSelect, icon, children, hint, value }: { onSelect: () => void; icon: React.ReactNode; children: React.ReactNode; hint?: string; value: string }) => {icon}{children}{hint && {hint}};
return (
ui.set({ paletteOpen: false })}>
e.stopPropagation()} onKeyDown={(e) => { if (e.key === "Escape") ui.set({ paletteOpen: false }); if (e.key === "Tab") { e.preventDefault(); setMode((m) => (m === "quick" ? "full" : "quick")); } }}>
{mode === "full" && q.length <= 2 ? "Type at least 3 characters" : "Nothing found"}
{mode === "quick" ? (<>
{q.trim() && } onSelect={() => go(`/search?q=${encodeURIComponent(q)}`)}>Search content for “{q}”}
{q.trim() && } onSelect={() => run(async () => { const p = await api("/api/pages", { method: "POST", json: { title: q } }); r.push(`/p/${p.id}`); })}>New page “{q}” } onSelect={() => run(() => ui.openAI({ prefill: q }))}>Ask AI “{q}”}
{(q ? (hits as any[]) : tree.slice(0, 8)).map((p: any) => : p.type === "research" ? : )} hint={p.section} onSelect={() => go(`/p/${p.id}`)}>{p.title || "Untitled"})}
} onSelect={() => go("/")}>Home } onSelect={() => go("/inbox")}>Tasks } onSelect={() => go("/graph")}>Knowledge graph } onSelect={() => go("/ai/models")}>AI models dashboard } onSelect={() => go("/ai/compare")}>Compare models } onSelect={() => go("/ai/agents")}>Agents } onSelect={() => go("/trash")}>Trash } onSelect={() => go("/settings")}>Settings
} hint="⌘⇧N" onSelect={() => run(async () => { const p = await api("/api/pages", { method: "POST", json: { title: "" } }); r.push(`/p/${p.id}`); })}>New page } onSelect={() => run(async () => { const p = await api("/api/pages", { method: "POST", json: { title: "New database", type: "database", section: "databases" } }); r.push(`/p/${p.id}`); })}>New database } hint="⌘/" onSelect={() => run(() => ui.openAI())}>Open AI assistant } onSelect={() => run(() => ui.setTheme("dark"))}>Dark mode } onSelect={() => run(() => ui.setTheme("light"))}>Light mode
>) : (
(hits as any[]).map((h: any) => go(`/p/${h.pageId}${h.blockId ? `#block-${h.blockId}` : ""}`)} className="cursor-pointer rounded-md px-2 py-2 data-[selected=true]:bg-bg-sunk">{h.icon ?? "📄"}{h.title}{h.heading && › {h.heading}}{h.semantic ? `sem ${(h.semantic * 100).toFixed(0)}%` : "kw"}
{h.content}
)
)}
);
}