import React, { useState, useEffect, useCallback, useMemo, useRef } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import {
  Search,
  Command as CommandIcon,
  File,
  Settings,
  Moon,
  Sun,
  Plus,
  FolderPlus,
  Bookmark,
  Split,
  Maximize2,
  RefreshCw,
} from 'lucide-react';
import { useEditorStore } from '@/core/store';
import { useSecureFileOpen } from '@/hooks/useSecureFileOpen';
import type { Command } from '@/core/types';
import { Dialog, DialogContent } from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { 
  appleCommandPalette, 
  appleListItem, 
  appleSpringGentle,
  appleStagger 
} from '@/lib/apple-animations';

const CommandPalette: React.FC = () => {
  const { isCommandPaletteOpen, toggleCommandPalette, files, addFile, toggleSidebar } = useEditorStore();
  const { openFile, UnlockDialog } = useSecureFileOpen();
  const [query, setQuery] = useState('');
  const [selectedIndex, setSelectedIndex] = useState(0);
  const inputRef = useRef<HTMLInputElement>(null);

  const commands: Command[] = useMemo(() => [
    {
      id: 'new-file',
      label: 'New File',
      shortcut: 'Ctrl+N',
      category: 'File',
      action: () => {
        addFile({
          name: 'untitled.txt',
          type: 'file',
          parentId: 'root',
          content: '',
          language: 'plaintext',
        });
      },
    },
    {
      id: 'new-folder',
      label: 'New Folder',
      shortcut: 'Ctrl+Shift+N',
      category: 'File',
      action: () => {
        addFile({
          name: 'new-folder',
          type: 'folder',
          parentId: 'root',
          isExpanded: true,
        });
      },
    },
    {
      id: 'toggle-sidebar',
      label: 'Toggle Sidebar',
      shortcut: 'Ctrl+B',
      category: 'View',
      action: toggleSidebar,
    },
    {
      id: 'go-to-file',
      label: 'Go to File...',
      shortcut: 'Ctrl+P',
      category: 'Navigation',
      action: () => {},
    },
    {
      id: 'zen-mode',
      label: 'Toggle Zen Mode',
      shortcut: 'Ctrl+K Z',
      category: 'View',
      action: () => {},
    },
    {
      id: 'settings',
      label: 'Open Settings',
      shortcut: 'Ctrl+,',
      category: 'Preferences',
      action: () => {},
    },
  ], [addFile, toggleSidebar]);

  const fileCommands: Command[] = useMemo(() => {
    return files
      .filter((f) => f.type === 'file')
      .map((f) => ({
        id: `file-${f.id}`,
        label: f.name,
        category: 'Files',
        action: () => openFile(f.id),
      }));
  }, [files, openFile]);

  const allCommands = useMemo(() => [...commands, ...fileCommands], [commands, fileCommands]);

  const filteredCommands = useMemo(() => {
    if (!query) return allCommands;
    const lowerQuery = query.toLowerCase();
    return allCommands.filter(
      (cmd) =>
        cmd.label.toLowerCase().includes(lowerQuery) ||
        cmd.category.toLowerCase().includes(lowerQuery)
    );
  }, [query, allCommands]);

  const groupedCommands = useMemo(() => {
    const groups: Record<string, Command[]> = {};
    filteredCommands.forEach((cmd) => {
      if (!groups[cmd.category]) {
        groups[cmd.category] = [];
      }
      groups[cmd.category].push(cmd);
    });
    return groups;
  }, [filteredCommands]);

  useEffect(() => {
    if (isCommandPaletteOpen) {
      setQuery('');
      setSelectedIndex(0);
      setTimeout(() => inputRef.current?.focus(), 0);
    }
  }, [isCommandPaletteOpen]);

  useEffect(() => {
    setSelectedIndex(0);
  }, [query]);

  const handleKeyDown = useCallback(
    (e: React.KeyboardEvent) => {
      if (e.key === 'ArrowDown') {
        e.preventDefault();
        setSelectedIndex((i) => Math.min(i + 1, filteredCommands.length - 1));
      } else if (e.key === 'ArrowUp') {
        e.preventDefault();
        setSelectedIndex((i) => Math.max(i - 1, 0));
      } else if (e.key === 'Enter') {
        e.preventDefault();
        const cmd = filteredCommands[selectedIndex];
        if (cmd) {
          cmd.action();
          toggleCommandPalette();
        }
      }
    },
    [filteredCommands, selectedIndex, toggleCommandPalette]
  );

  const getCategoryIcon = (category: string) => {
    switch (category) {
      case 'File':
        return <File className="w-3 h-3" />;
      case 'Files':
        return <File className="w-3 h-3" />;
      case 'View':
        return <Maximize2 className="w-3 h-3" />;
      case 'Navigation':
        return <Search className="w-3 h-3" />;
      case 'Preferences':
        return <Settings className="w-3 h-3" />;
      default:
        return <CommandIcon className="w-3 h-3" />;
    }
  };

  let flatIndex = 0;

  return (
    <Dialog open={isCommandPaletteOpen} onOpenChange={toggleCommandPalette}>
      <DialogContent className="command-palette p-0 max-w-xl gap-0 border-0">
        <div className="flex items-center gap-3 px-4 py-3 border-b border-border">
          <Search className="w-4 h-4 text-muted-foreground" />
          <Input
            ref={inputRef}
            value={query}
            onChange={(e) => setQuery(e.target.value)}
            onKeyDown={handleKeyDown}
            placeholder="Type a command or search..."
            className="flex-1 border-0 bg-transparent focus-visible:ring-0 p-0 h-auto text-sm"
          />
          <kbd className="text-[10px] font-mono bg-muted px-1.5 py-0.5 rounded text-muted-foreground">
            ESC
          </kbd>
        </div>

        <div className="max-h-80 overflow-auto py-2 apple-scroll">
          <AnimatePresence mode="popLayout">
            {Object.entries(groupedCommands).map(([category, cmds]) => (
              <motion.div
                key={category}
                {...appleListItem}
                transition={appleSpringGentle}
              >
                <div className="px-4 py-1">
                  <span className="text-[10px] font-medium uppercase tracking-wider text-muted-foreground">
                    {category}
                  </span>
                </div>
                {cmds.map((cmd) => {
                  const currentIndex = flatIndex++;
                  const isSelected = currentIndex === selectedIndex;
                  return (
                    <motion.div
                      key={cmd.id}
                      className={`flex items-center gap-3 px-4 py-2 cursor-pointer transition-colors ${
                        isSelected ? 'bg-primary/10 text-primary' : 'hover:bg-muted/50'
                      }`}
                      onClick={() => {
                        cmd.action();
                        toggleCommandPalette();
                      }}
                      whileHover={{ x: 2 }}
                      transition={appleSpringGentle}
                    >
                      <span className="text-muted-foreground">{getCategoryIcon(category)}</span>
                      <span className="flex-1 text-sm">{cmd.label}</span>
                      {cmd.shortcut && (
                        <kbd className="text-[10px] font-mono bg-muted px-1.5 py-0.5 rounded text-muted-foreground">
                          {cmd.shortcut}
                        </kbd>
                      )}
                    </motion.div>
                  );
                })}
              </motion.div>
            ))}
          </AnimatePresence>

          {filteredCommands.length === 0 && (
            <div className="px-4 py-8 text-center text-muted-foreground text-sm">
              No commands found
            </div>
          )}
        </div>
      </DialogContent>
      {UnlockDialog}
    </Dialog>
  );
};

export default CommandPalette;
