import { useState, useEffect, useCallback } from "react";
import {
  FileText,
  LayoutDashboard,
  Plus,
  Moon,
  Settings,
  Search,
} from "lucide-react";
import {
  CommandDialog,
  CommandInput,
  CommandList,
  CommandEmpty,
  CommandGroup,
  CommandItem,
  CommandSeparator,
} from "@/components/ui/command";
import { useAppStore } from "@/stores/app-store";
import { useBoardStore } from "@/stores/board-store";
import { searchAllBoards, type SearchResult } from "@/lib/storage";

interface CommandPaletteProps {
  onOpenSettings: () => void;
}

export function CommandPalette({ onOpenSettings }: CommandPaletteProps) {
  const [open, setOpen] = useState(false);
  const [query, setQuery] = useState("");
  const [crossBoardResults, setCrossBoardResults] = useState<SearchResult[]>(
    []
  );

  const boards = useAppStore((s) => s.boards);
  const setView = useAppStore((s) => s.setView);
  const setTheme = useAppStore((s) => s.setTheme);
  const theme = useAppStore((s) => s.settings.theme);
  const addRecentBoard = useAppStore((s) => s.addRecentBoard);
  const board = useBoardStore((s) => s.board);
  const openBoard = useBoardStore((s) => s.openBoard);

  // Listen for Ctrl+K and custom event to open
  useEffect(() => {
    function handleKeyDown(e: KeyboardEvent) {
      if (e.key === "k" && (e.metaKey || e.ctrlKey)) {
        e.preventDefault();
        setOpen((prev) => !prev);
      }
    }

    function handleOpenPalette() {
      setOpen(true);
    }

    document.addEventListener("keydown", handleKeyDown);
    document.addEventListener("open-command-palette", handleOpenPalette);
    return () => {
      document.removeEventListener("keydown", handleKeyDown);
      document.removeEventListener("open-command-palette", handleOpenPalette);
    };
  }, []);

  // Cross-board search when query has 2+ characters
  useEffect(() => {
    if (query.length < 2) {
      setCrossBoardResults([]);
      return;
    }

    let cancelled = false;
    searchAllBoards(query).then((results) => {
      if (!cancelled) {
        setCrossBoardResults(results);
      }
    });

    return () => {
      cancelled = true;
    };
  }, [query]);

  // Reset state when closing
  useEffect(() => {
    if (!open) {
      setQuery("");
      setCrossBoardResults([]);
    }
  }, [open]);

  const handleSelectBoard = useCallback(
    async (boardId: string) => {
      setOpen(false);
      await openBoard(boardId);
      setView({ type: "board", boardId });
      addRecentBoard(boardId);
    },
    [openBoard, setView, addRecentBoard]
  );

  const handleSelectCard = useCallback(
    (cardId: string, boardId: string) => {
      setOpen(false);
      // If the card is from the current board, dispatch a custom event to open it
      if (board && board.id === boardId) {
        document.dispatchEvent(
          new CustomEvent("open-card-detail", { detail: { cardId } })
        );
      } else {
        // Navigate to the board first, then open the card
        openBoard(boardId).then(() => {
          setView({ type: "board", boardId });
          addRecentBoard(boardId);
          // Small delay to allow BoardView to mount
          setTimeout(() => {
            document.dispatchEvent(
              new CustomEvent("open-card-detail", { detail: { cardId } })
            );
          }, 100);
        });
      }
    },
    [board, openBoard, setView, addRecentBoard]
  );

  const handleToggleTheme = useCallback(() => {
    setOpen(false);
    const next = theme === "dark" ? "light" : "dark";
    setTheme(next);
  }, [theme, setTheme]);

  const handleNewBoard = useCallback(() => {
    setOpen(false);
    // Go to board list and trigger new board dialog
    setView({ type: "board-list" });
    setTimeout(() => {
      document.dispatchEvent(new CustomEvent("open-new-board-dialog"));
    }, 100);
  }, [setView]);

  const handleOpenSettings = useCallback(() => {
    setOpen(false);
    onOpenSettings();
  }, [onOpenSettings]);

  // Current board cards for search
  const currentBoardCards = board
    ? Object.values(board.cards)
    : [];

  return (
    <CommandDialog open={open} onOpenChange={setOpen} showCloseButton={false}>
      <CommandInput
        placeholder="Search cards, boards, actions..."
        value={query}
        onValueChange={setQuery}
      />
      <CommandList>
        <CommandEmpty>No results found.</CommandEmpty>

        {/* Current board cards */}
        {board && currentBoardCards.length > 0 && (
          <CommandGroup heading="Cards">
            {currentBoardCards.map((card) => (
              <CommandItem
                key={card.id}
                value={`card-${card.title}`}
                onSelect={() => handleSelectCard(card.id, board.id)}
              >
                <FileText className="size-4" />
                <span>{card.title}</span>
              </CommandItem>
            ))}
          </CommandGroup>
        )}

        {/* Cross-board search results */}
        {crossBoardResults.length > 0 && (
          <>
            <CommandSeparator />
            <CommandGroup heading="Cross-board Results">
              {crossBoardResults
                .filter(
                  (r) => !board || r.boardId !== board.id
                )
                .slice(0, 10)
                .map((result) => (
                  <CommandItem
                    key={`${result.boardId}-${result.cardId}`}
                    value={`cross-${result.cardTitle}-${result.boardTitle}`}
                    onSelect={() =>
                      handleSelectCard(result.cardId, result.boardId)
                    }
                  >
                    <Search className="size-4" />
                    <span>{result.cardTitle}</span>
                    <span className="ml-auto text-xs text-muted-foreground">
                      {result.boardTitle}
                    </span>
                  </CommandItem>
                ))}
            </CommandGroup>
          </>
        )}

        <CommandSeparator />

        {/* Boards */}
        <CommandGroup heading="Boards">
          {boards.map((b) => (
            <CommandItem
              key={b.id}
              value={`board-${b.title}`}
              onSelect={() => handleSelectBoard(b.id)}
            >
              <LayoutDashboard className="size-4" />
              <span>{b.title}</span>
              <span className="ml-auto text-xs text-muted-foreground">
                {b.columnCount} cols, {b.cardCount} cards
              </span>
            </CommandItem>
          ))}
        </CommandGroup>

        <CommandSeparator />

        {/* Actions */}
        <CommandGroup heading="Actions">
          <CommandItem value="new-board" onSelect={handleNewBoard}>
            <Plus className="size-4" />
            <span>New Board</span>
          </CommandItem>
          <CommandItem value="toggle-dark-mode" onSelect={handleToggleTheme}>
            <Moon className="size-4" />
            <span>Toggle Dark Mode</span>
          </CommandItem>
          <CommandItem value="settings" onSelect={handleOpenSettings}>
            <Settings className="size-4" />
            <span>Settings</span>
          </CommandItem>
        </CommandGroup>
      </CommandList>
    </CommandDialog>
  );
}
