import { useState, useEffect, useRef, useCallback } from "react";
import { useNavigate } from "@tanstack/react-router";
import { Search, Briefcase, Bot, Settings, ArrowRight } from "lucide-react";
import { trpc } from "@/lib/trpc";
import { cn } from "@/lib/utils";

interface CommandItem {
  id: string;
  label: string;
  group: string;
  path: string;
  icon: typeof Briefcase;
  meta?: string;
}

function fuzzyMatch(query: string, text: string): boolean {
  const terms = query.toLowerCase().split(/\s+/).filter(Boolean);
  const lower = text.toLowerCase();
  return terms.every((term) => lower.includes(term));
}

const RECENT_KEY = "cw-command-recent";

function getRecent(): string[] {
  try {
    return JSON.parse(sessionStorage.getItem(RECENT_KEY) ?? "[]");
  } catch {
    return [];
  }
}

function addRecent(id: string) {
  const recent = getRecent().filter((r) => r !== id);
  recent.unshift(id);
  sessionStorage.setItem(RECENT_KEY, JSON.stringify(recent.slice(0, 5)));
}

interface CommandPaletteProps {
  open: boolean;
  onClose: () => void;
}

export function CommandPalette({ open, onClose }: CommandPaletteProps) {
  const [query, setQuery] = useState("");
  const [activeIndex, setActiveIndex] = useState(0);
  const inputRef = useRef<HTMLInputElement>(null);
  const listRef = useRef<HTMLDivElement>(null);
  const navigate = useNavigate();

  const initiatives = trpc.listInitiatives.useQuery(undefined, { enabled: open });
  const agents = trpc.listAgents.useQuery(undefined, { enabled: open });

  // Build items list
  const items: CommandItem[] = [];

  // Static navigation items
  const staticItems: CommandItem[] = [
    { id: "nav-initiatives", label: "Initiatives", group: "Navigation", path: "/initiatives", icon: Briefcase },
    { id: "nav-agents", label: "Agents", group: "Navigation", path: "/agents", icon: Bot },
    { id: "nav-inbox", label: "Inbox", group: "Navigation", path: "/inbox", icon: ArrowRight },
    { id: "nav-settings", label: "Settings", group: "Navigation", path: "/settings/health", icon: Settings },
  ];

  for (const item of staticItems) items.push(item);

  if (initiatives.data) {
    for (const init of initiatives.data) {
      items.push({
        id: `initiative-${init.id}`,
        label: init.name,
        group: "Initiatives",
        path: `/initiatives/${init.id}`,
        icon: Briefcase,
        meta: init.status,
      });
    }
  }

  if (agents.data) {
    for (const agent of agents.data) {
      items.push({
        id: `agent-${agent.id}`,
        label: agent.name,
        group: "Agents",
        path: "/agents",
        icon: Bot,
        meta: agent.status,
      });
    }
  }

  // Filter
  const filtered = query
    ? items.filter((item) => fuzzyMatch(query, `${item.label} ${item.meta ?? ""}`))
    : items;

  // Group
  const groups = new Map<string, CommandItem[]>();
  for (const item of filtered) {
    const list = groups.get(item.group) ?? [];
    list.push(item);
    groups.set(item.group, list);
  }

  // Flat list for keyboard nav
  const flatItems = Array.from(groups.values()).flat();

  const select = useCallback(
    (item: CommandItem) => {
      addRecent(item.id);
      onClose();
      navigate({ to: item.path });
    },
    [navigate, onClose],
  );

  // Focus input when opened
  useEffect(() => {
    if (open) {
      setQuery("");
      setActiveIndex(0);
      requestAnimationFrame(() => inputRef.current?.focus());
    }
  }, [open]);

  // Reset active index on filter change
  useEffect(() => {
    setActiveIndex(0);
  }, [query]);

  // Scroll active item into view
  useEffect(() => {
    const el = listRef.current?.querySelector('[data-active="true"]');
    el?.scrollIntoView({ block: "nearest" });
  }, [activeIndex]);

  function handleKeyDown(e: React.KeyboardEvent) {
    switch (e.key) {
      case "ArrowDown":
        e.preventDefault();
        setActiveIndex((i) => Math.min(i + 1, flatItems.length - 1));
        break;
      case "ArrowUp":
        e.preventDefault();
        setActiveIndex((i) => Math.max(i - 1, 0));
        break;
      case "Enter":
        e.preventDefault();
        if (flatItems[activeIndex]) select(flatItems[activeIndex]);
        break;
      case "Escape":
        e.preventDefault();
        onClose();
        break;
    }
  }

  if (!open) return null;

  let flatIndex = 0;

  return (
    <>
      {/* Backdrop */}
      <div
        className="fixed inset-0 z-command bg-black/50"
        onClick={onClose}
      />
      {/* Palette */}
      <div className="fixed left-1/2 top-[20%] z-command w-full max-w-lg -translate-x-1/2 rounded-lg border bg-popover shadow-xl dark:bg-[hsl(var(--surface-3))]">
        {/* Search */}
        <div className="flex items-center gap-2 border-b px-3">
          <Search className="h-4 w-4 shrink-0 text-muted-foreground" />
          <input
            ref={inputRef}
            value={query}
            onChange={(e) => setQuery(e.target.value)}
            onKeyDown={handleKeyDown}
            placeholder="Search initiatives, agents, settings..."
            className="h-11 flex-1 bg-transparent text-sm outline-none placeholder:text-muted-foreground"
          />
          <kbd className="hidden sm:inline-flex items-center gap-0.5 rounded border bg-muted px-1.5 py-0.5 text-[10px] font-mono text-muted-foreground">
            ESC
          </kbd>
        </div>
        {/* Results */}
        <div ref={listRef} className="max-h-[300px] overflow-y-auto p-1">
          {flatItems.length === 0 ? (
            <p className="px-3 py-6 text-center text-sm text-muted-foreground">
              No results
            </p>
          ) : (
            Array.from(groups.entries()).map(([group, groupItems]) => (
              <div key={group}>
                <p className="px-3 py-1.5 text-xs font-medium text-muted-foreground">
                  {group}
                </p>
                {groupItems.map((item) => {
                  const isActive = flatIndex === activeIndex;
                  const idx = flatIndex;
                  flatIndex++;
                  const Icon = item.icon;
                  return (
                    <button
                      key={item.id}
                      data-active={isActive}
                      className={cn(
                        "flex w-full items-center gap-2 rounded-md px-3 py-2 text-sm transition-colors",
                        isActive
                          ? "bg-accent text-accent-foreground"
                          : "text-foreground hover:bg-muted",
                      )}
                      onClick={() => select(item)}
                      onMouseEnter={() => setActiveIndex(idx)}
                    >
                      <Icon className="h-4 w-4 shrink-0 text-muted-foreground" />
                      <span className="flex-1 truncate text-left">{item.label}</span>
                      {item.meta && (
                        <span className="text-xs text-muted-foreground">{item.meta}</span>
                      )}
                    </button>
                  );
                })}
              </div>
            ))
          )}
        </div>
      </div>
    </>
  );
}
