import { createContext, useContext, useEffect, useCallback, useState } from 'react';
import { useNavigate, useLocation } from 'react-router-dom';

interface KeyboardShortcut {
  key: string;
  modifier?: 'ctrl' | 'cmd' | 'alt' | 'shift';
  description: string;
  action: () => void;
  condition?: () => boolean;
}

interface KeyboardShortcutsContextType {
  shortcuts: KeyboardShortcut[];
  registerShortcut: (shortcut: KeyboardShortcut) => void;
  unregisterShortcut: (key: string) => void;
  showHelp: boolean;
  setShowHelp: (show: boolean) => void;
}

const KeyboardShortcutsContext = createContext<KeyboardShortcutsContextType | undefined>(undefined);

// Check if Mac
const isMac = navigator.platform.toUpperCase().indexOf('MAC') >= 0;

export function KeyboardShortcutsProvider({ children }: { children: React.ReactNode }) {
  const navigate = useNavigate();
  const location = useLocation();
  const [customShortcuts, setCustomShortcuts] = useState<KeyboardShortcut[]>([]);
  const [showHelp, setShowHelp] = useState(false);
  const [modalOpen, setModalOpen] = useState(false);

  // Default shortcuts
  const defaultShortcuts: KeyboardShortcut[] = [
    {
      key: 'k',
      modifier: isMac ? 'cmd' : 'ctrl',
      description: 'Open command palette',
      action: () => {
        // Command palette is handled separately
      },
    },
    {
      key: 'n',
      description: 'New scenario',
      action: () => {
        if (!modalOpen) {
          navigate('/scenarios', { state: { openNew: true } });
        }
      },
      condition: () => !modalOpen,
    },
    {
      key: 'c',
      description: 'Compare scenarios',
      action: () => {
        navigate('/compare');
      },
    },
    {
      key: 'r',
      description: 'Go to reports',
      action: () => {
        navigate('/');
      },
    },
    {
      key: 'a',
      description: 'Analytics dashboard',
      action: () => {
        navigate('/analytics');
      },
    },
    {
      key: 'Escape',
      description: 'Close modal / Cancel',
      action: () => {
        if (modalOpen) {
          setModalOpen(false);
        }
      },
    },
    {
      key: '?',
      description: 'Show keyboard shortcuts',
      action: () => {
        setShowHelp(true);
      },
    },
    {
      key: 'd',
      description: 'Go to dashboard',
      action: () => {
        navigate('/');
      },
    },
    {
      key: 's',
      description: 'Go to scenarios',
      action: () => {
        navigate('/scenarios');
      },
    },
  ];

  const allShortcuts = [...defaultShortcuts, ...customShortcuts];

  const registerShortcut = useCallback((shortcut: KeyboardShortcut) => {
    setCustomShortcuts((prev) => {
      // Remove existing shortcut with same key
      const filtered = prev.filter((s) => s.key !== shortcut.key);
      return [...filtered, shortcut];
    });
  }, []);

  const unregisterShortcut = useCallback((key: string) => {
    setCustomShortcuts((prev) => prev.filter((s) => s.key !== key));
  }, []);

  // Track modal state from URL
  useEffect(() => {
    const checkModal = () => {
      const hasModal = document.querySelector('[role="dialog"][data-state="open"]') !== null;
      setModalOpen(hasModal);
    };

    // Check initially and on mutations
    checkModal();
    const observer = new MutationObserver(checkModal);
    observer.observe(document.body, { childList: true, subtree: true });

    return () => observer.disconnect();
  }, [location]);

  useEffect(() => {
    const handleKeyDown = (event: KeyboardEvent) => {
      // Don't trigger shortcuts when typing in inputs
      const target = event.target as HTMLElement;
      if (
        target.tagName === 'INPUT' ||
        target.tagName === 'TEXTAREA' ||
        target.contentEditable === 'true' ||
        target.getAttribute('role') === 'textbox'
      ) {
        // Allow Escape to close modals even when in input
        if (event.key === 'Escape') {
          const shortcut = allShortcuts.find((s) => s.key === 'Escape');
          if (shortcut) {
            event.preventDefault();
            shortcut.action();
          }
        }
        return;
      }

      const key = event.key;
      const ctrl = event.ctrlKey;
      const meta = event.metaKey;
      const alt = event.altKey;
      const shift = event.shiftKey;

      // Find matching shortcut
      const shortcut = allShortcuts.find((s) => {
        if (s.key !== key) return false;

        const modifier = s.modifier;
        if (!modifier) {
          // No modifier required - make sure none are pressed (except shift for uppercase letters)
          return !ctrl && !meta && !alt;
        }

        switch (modifier) {
          case 'ctrl':
            return ctrl && !meta && !alt;
          case 'cmd':
            return meta && !ctrl && !alt;
          case 'alt':
            return alt && !ctrl && !meta;
          case 'shift':
            return shift;
          default:
            return false;
        }
      });

      if (shortcut) {
        // Check condition
        if (shortcut.condition && !shortcut.condition()) {
          return;
        }

        event.preventDefault();
        shortcut.action();
      }
    };

    window.addEventListener('keydown', handleKeyDown);
    return () => window.removeEventListener('keydown', handleKeyDown);
  }, [allShortcuts]);

  return (
    <KeyboardShortcutsContext.Provider
      value={{
        shortcuts: allShortcuts,
        registerShortcut,
        unregisterShortcut,
        showHelp,
        setShowHelp,
      }}
    >
      {children}
      <KeyboardShortcutsHelp
        isOpen={showHelp}
        onClose={() => setShowHelp(false)}
        shortcuts={allShortcuts}
      />
    </KeyboardShortcutsContext.Provider>
  );
}

export function useKeyboardShortcuts() {
  const context = useContext(KeyboardShortcutsContext);
  if (context === undefined) {
    throw new Error('useKeyboardShortcuts must be used within a KeyboardShortcutsProvider');
  }
  return context;
}

// Keyboard shortcuts help modal
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';

interface KeyboardShortcutsHelpProps {
  isOpen: boolean;
  onClose: () => void;
  shortcuts: KeyboardShortcut[];
}

function KeyboardShortcutsHelp({ isOpen, onClose, shortcuts }: KeyboardShortcutsHelpProps) {
  const formatKey = (shortcut: KeyboardShortcut): string => {
    const parts: string[] = [];
    
    if (shortcut.modifier) {
      switch (shortcut.modifier) {
        case 'ctrl':
          parts.push(isMac ? '⌃' : 'Ctrl');
          break;
        case 'cmd':
          parts.push(isMac ? '⌘' : 'Ctrl');
          break;
        case 'alt':
          parts.push(isMac ? '⌥' : 'Alt');
          break;
        case 'shift':
          parts.push('⇧');
          break;
      }
    }
    
    parts.push(shortcut.key.toUpperCase());
    return parts.join(' + ');
  };

  // Group shortcuts by category
  const navigationShortcuts = shortcuts.filter((s) =>
    ['d', 's', 'c', 'r', 'a'].includes(s.key)
  );
  
  const actionShortcuts = shortcuts.filter((s) =>
    ['n', 'k'].includes(s.key)
  );
  
  const otherShortcuts = shortcuts.filter((s) =>
    !['d', 's', 'c', 'r', 'a', 'n', 'k'].includes(s.key)
  );

  return (
    <Dialog open={isOpen} onOpenChange={onClose}>
      <DialogContent className="max-w-2xl">
        <DialogHeader>
          <DialogTitle>Keyboard Shortcuts</DialogTitle>
        </DialogHeader>
        
        <div className="space-y-6 py-4">
          <ShortcutGroup title="Navigation" shortcuts={navigationShortcuts} formatKey={formatKey} />
          <ShortcutGroup title="Actions" shortcuts={actionShortcuts} formatKey={formatKey} />
          <ShortcutGroup title="Other" shortcuts={otherShortcuts} formatKey={formatKey} />
        </div>

        <p className="text-xs text-muted-foreground mt-4">
          Press any key combination when not focused on an input field.
        </p>
      </DialogContent>
    </Dialog>
  );
}

interface ShortcutGroupProps {
  title: string;
  shortcuts: KeyboardShortcut[];
  formatKey: (s: KeyboardShortcut) => string;
}

function ShortcutGroup({ title, shortcuts, formatKey }: ShortcutGroupProps) {
  if (shortcuts.length === 0) return null;

  return (
    <div>
      <h3 className="text-sm font-semibold mb-2">{title}</h3>
      <div className="space-y-1">
        {shortcuts.map((shortcut) => (
          <div
            key={shortcut.key + (shortcut.modifier || '')}
            className="flex justify-between items-center py-1"
          >
            <span className="text-sm text-muted-foreground">{shortcut.description}</span>
            <kbd className="px-2 py-1 bg-muted rounded text-xs font-mono">
              {formatKey(shortcut)}
            </kbd>
          </div>
        ))}
      </div>
    </div>
  );
}
