import React, { useState, useEffect, useRef, useCallback } from 'react';
import { createPortal } from 'react-dom';
import type { EditorStore } from '../../store/editorStore';
import { BLOCKS } from './BlockPicker';

interface Props {
  store: EditorStore;
  onClose: () => void;
}

type ActionItem = {
  group: string;
  label: string;
  shortcut?: string;
  icon: string;
  action: () => void;
};

export function CommandPalette({ store, onClose }: Props) {
  const [query, setQuery] = useState('');
  const [focusIdx, setFocusIdx] = useState(0);
  const inputRef = useRef<HTMLInputElement>(null);
  const isMac = typeof navigator !== 'undefined' && navigator.platform.includes('Mac');
  const mod = isMac ? '⌘' : 'Ctrl+';
  const { state } = store;

  useEffect(() => {
    const t = setTimeout(() => inputRef.current?.focus(), 30);
    return () => clearTimeout(t);
  }, []);

  const elementActions: ActionItem[] = BLOCKS.map((block) => ({
    group: 'Elements',
    label: `Add ${block.label}`,
    icon: block.icon,
    action: () => {
      if (state.selectedId) {
        const selected = state.pageData.sections
          .flatMap(function flat(n: any): any[] { return [n, ...(n.children?.flatMap(flat) ?? [])]; })
          .find((n: any) => n.id === state.selectedId);
        if (selected?.type === 'section') {
          store.addElementInContainer(state.selectedId, block.defaultNode);
        } else if (selected?.type === 'container' || selected?.type === 'column') {
          store.addElement(state.selectedId, block.defaultNode);
        } else {
          // leaf element or unknown — add to new section
          store.addElementInNewSection(undefined, block.defaultNode);
        }
      } else {
        store.addElementInNewSection(undefined, block.defaultNode);
      }
      onClose();
    },
  }));

  const coreActions: ActionItem[] = [
    { group: 'Actions', label: 'Undo',            icon: '↩', shortcut: `${mod}Z`,   action: () => { store.undo(); onClose(); } },
    { group: 'Actions', label: 'Redo',            icon: '↪', shortcut: `${mod}Y`,   action: () => { store.redo(); onClose(); } },
    { group: 'Actions', label: 'Duplicate',       icon: '⎘', shortcut: `${mod}D`,   action: () => { if (state.selectedId) store.duplicateNode(state.selectedId); onClose(); } },
    { group: 'Actions', label: 'Copy',            icon: '⊕', shortcut: `${mod}C`,   action: () => { if (state.selectedId) store.copyNode(state.selectedId); onClose(); } },
    { group: 'Actions', label: 'Paste',           icon: '⊗', shortcut: `${mod}V`,   action: () => { if (state.selectedId) store.pasteNode(state.selectedId); onClose(); } },
    { group: 'Actions', label: 'Delete Selected', icon: '✕', shortcut: 'Del',        action: () => { if (state.selectedId) store.deleteNode(state.selectedId); onClose(); } },
    { group: 'Actions', label: 'Deselect',        icon: '○', shortcut: 'Esc',        action: () => { store.selectNode(null); onClose(); } },
  ];

  const allActions = [...elementActions, ...coreActions];

  const filtered = query.trim()
    ? allActions.filter((a) => a.label.toLowerCase().includes(query.toLowerCase()))
    : allActions;

  // Group results
  const grouped = filtered.reduce<Record<string, ActionItem[]>>((acc, item) => {
    if (!acc[item.group]) acc[item.group] = [];
    acc[item.group].push(item);
    return acc;
  }, {});

  const flat = filtered;
  const total = flat.length;

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

  const handleKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === 'ArrowDown')  { e.preventDefault(); setFocusIdx((i) => Math.min(i + 1, total - 1)); }
    if (e.key === 'ArrowUp')    { e.preventDefault(); setFocusIdx((i) => Math.max(i - 1, 0)); }
    if (e.key === 'Enter')      { e.preventDefault(); if (flat[focusIdx]) flat[focusIdx].action(); }
    if (e.key === 'Escape')     { onClose(); }
  };

  return createPortal(
    <div className="jalpi-cmd-backdrop" onClick={(e) => { if (e.target === e.currentTarget) onClose(); }}>
      <div className="jalpi-cmd-palette" onKeyDown={handleKeyDown}>
        <div className="jalpi-cmd-palette__search">
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
            <circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/>
          </svg>
          <input
            ref={inputRef}
            className="jalpi-cmd-palette__input"
            placeholder="Search elements and actions…"
            value={query}
            onChange={(e) => setQuery(e.target.value)}
          />
          <span className="jalpi-cmd-palette__hint">{mod}K to close</span>
        </div>

        <div className="jalpi-cmd-palette__results">
          {Object.entries(grouped).map(([group, items]) => (
            <div key={group} className="jalpi-cmd-palette__group">
              <div className="jalpi-cmd-palette__group-label">{group}</div>
              {items.map((item) => {
                const globalIdx = flat.indexOf(item);
                return (
                  <button
                    key={item.label + item.icon}
                    className={`jalpi-cmd-palette__item${globalIdx === focusIdx ? ' is-focused' : ''}`}
                    onClick={item.action}
                    onMouseEnter={() => setFocusIdx(globalIdx)}
                  >
                    <span className="jalpi-cmd-palette__item-icon">{item.icon}</span>
                    <span className="jalpi-cmd-palette__item-label">{item.label}</span>
                    {item.shortcut && <span className="jalpi-cmd-palette__item-shortcut">{item.shortcut}</span>}
                  </button>
                );
              })}
            </div>
          ))}
          {filtered.length === 0 && (
            <div className="jalpi-cmd-palette__empty">No results for "{query}"</div>
          )}
        </div>
      </div>
    </div>,
    document.body
  );
}
