import { useEffect, useCallback } from 'react';
import { createPortal } from 'react-dom';
import { useCommandPalette, type PaletteScope } from './use-command-palette';
import { usePaletteSearch, type PaletteResult } from './use-palette-search';
import { useExecutionSearch } from '../../pages/executions/use-execution-search';
import { PaletteInput } from './PaletteInput';
import { ScopeTabs } from './ScopeTabs';
import { ResultsList } from './ResultsList';
import { PaletteFooter } from './PaletteFooter';
import type { ExecutionSummary, AgentInstance } from '../../api/schema';
import styles from './CommandPalette.module.css';

const SCOPES: PaletteScope[] = ['all', 'executions', 'agents'];

export function CommandPalette() {
  const { isOpen, close, scope, setScope, selectedIndex, setSelectedIndex, reset, filters } =
    useCommandPalette();
  const { results, executionCount, agentCount, isLoading } = usePaletteSearch();
  const execSearch = useExecutionSearch();

  const handleSelect = useCallback(
    (result: PaletteResult) => {
      if (result.type === 'execution') {
        const exec = result.data as ExecutionSummary;
        execSearch.setText(exec.executionId);
        execSearch.setRouteId('');
        execSearch.setAgentId('');
        execSearch.setProcessorType('');
      } else if (result.type === 'agent') {
        const agent = result.data as AgentInstance;
        execSearch.setAgentId(agent.agentId);
        execSearch.setText('');
        execSearch.setRouteId('');
        execSearch.setProcessorType('');
      }
      // Apply any active palette filters to the execution search
      for (const f of filters) {
        if (f.key === 'status') execSearch.setStatus([f.value.toUpperCase()]);
        if (f.key === 'route') execSearch.setRouteId(f.value);
        if (f.key === 'agent') execSearch.setAgentId(f.value);
        if (f.key === 'processor') execSearch.setProcessorType(f.value);
      }
      close();
      reset();
    },
    [close, reset, execSearch, filters],
  );

  const handleKeyDown = useCallback(
    (e: KeyboardEvent) => {
      if (!isOpen) return;

      switch (e.key) {
        case 'Escape':
          e.preventDefault();
          close();
          reset();
          break;
        case 'ArrowDown':
          e.preventDefault();
          setSelectedIndex(
            results.length > 0 ? (selectedIndex + 1) % results.length : 0,
          );
          break;
        case 'ArrowUp':
          e.preventDefault();
          setSelectedIndex(
            results.length > 0
              ? (selectedIndex - 1 + results.length) % results.length
              : 0,
          );
          break;
        case 'Enter':
          e.preventDefault();
          if (results[selectedIndex]) {
            handleSelect(results[selectedIndex]);
          }
          break;
        case 'Tab':
          e.preventDefault();
          const idx = SCOPES.indexOf(scope);
          setScope(SCOPES[(idx + 1) % SCOPES.length]);
          break;
      }
    },
    [isOpen, close, reset, selectedIndex, setSelectedIndex, results, handleSelect, scope, setScope],
  );

  // Global Cmd+K / Ctrl+K listener
  useEffect(() => {
    function onKeyDown(e: KeyboardEvent) {
      if ((e.metaKey || e.ctrlKey) && e.key === 'k') {
        e.preventDefault();
        const store = useCommandPalette.getState();
        if (store.isOpen) {
          store.close();
          store.reset();
        } else {
          store.open();
        }
      }
    }
    document.addEventListener('keydown', onKeyDown);
    return () => document.removeEventListener('keydown', onKeyDown);
  }, []);

  // Keyboard handling when open
  useEffect(() => {
    document.addEventListener('keydown', handleKeyDown);
    return () => document.removeEventListener('keydown', handleKeyDown);
  }, [handleKeyDown]);

  if (!isOpen) return null;

  return createPortal(
    <div className={styles.overlay} onClick={(e) => {
      if (e.target === e.currentTarget) {
        close();
        reset();
      }
    }}>
      <div className={styles.modal}>
        <PaletteInput />
        <ScopeTabs executionCount={executionCount} agentCount={agentCount} />
        <ResultsList results={results} isLoading={isLoading} onSelect={handleSelect} />
        <PaletteFooter />
      </div>
    </div>,
    document.body,
  );
}
