// Command palette. Cmd-K / Ctrl+K / "/" opens. Indexes sections, projects,
// capabilities, writing, contact actions. Substring filter, ↑/↓ to navigate,
// Enter to activate, Esc to close.

const CommandPalette = ({ open, setOpen }) => {
  const D = window.SITE_DATA;
  const [q, setQ] = React.useState('');
  const [idx, setIdx] = React.useState(0);
  const inputRef = React.useRef(null);
  const listRef = React.useRef(null);

  // Build index. Every entry: {kind, label, hint, category, action}
  const items = React.useMemo(() => {
    const out = [];

    // TOC sections: jump
    [
      { id: 'about', label: 'About', hint: 'Operating parameters, footnoted bio' },
      { id: 'domains', label: 'Disciplines × Lifecycle', hint: 'Where I work across the V-model' },
      { id: 'projects', label: 'Selected Work', hint: 'Case studies' },
      { id: 'experience', label: 'Service Record', hint: 'Career timeline' },
      { id: 'skills', label: 'Capabilities', hint: 'Tools of the trade' },
      { id: 'writing', label: 'Field Notes', hint: 'Notes & writing' },
      { id: 'now', label: 'Now', hint: 'Current focus' },
      { id: 'contact', label: 'Comms', hint: 'Get in touch' },
    ].forEach(s => out.push({
      kind: 'section', category: 'JUMP TO',
      label: s.label, hint: s.hint, glyph: '§',
      action: () => {
        const el = document.getElementById(s.id);
        if (el) {
          el.scrollIntoView({ behavior: 'smooth', block: 'start' });
          history.replaceState(null, '', '#' + s.id);
        }
      }
    }));

    // Projects: open case study
    (D.projects || []).forEach(p => out.push({
      kind: 'project', category: 'CASE STUDY',
      label: p.title, hint: (p.tags || []).join(' · '), glyph: p.code || '◇',
      action: () => {
        const el = document.getElementById('projects');
        if (el) el.scrollIntoView({ behavior: 'smooth', block: 'start' });
        // Trigger custom event the dossier listens for
        window.dispatchEvent(new CustomEvent('dossier:open-project', { detail: p.id }));
      }
    }));

    // Capabilities: jump to skills section, optionally highlight category
    Object.keys(D.skills || {}).forEach(cat => out.push({
      kind: 'skill', category: 'CAPABILITY',
      label: cat, hint: D.skills[cat].slice(0, 4).join(' · '), glyph: '◆',
      action: () => {
        const el = document.getElementById('skills');
        if (el) el.scrollIntoView({ behavior: 'smooth', block: 'start' });
      }
    }));

    // Writing
    (D.writing || []).forEach(w => out.push({
      kind: 'writing', category: 'FIELD NOTE',
      label: w.title, hint: w.date, glyph: '✎',
      action: () => {
        const el = document.getElementById('writing');
        if (el) el.scrollIntoView({ behavior: 'smooth', block: 'start' });
      }
    }));

    // Contact actions: direct
    out.push({
      kind: 'action', category: 'ACTION',
      label: 'Email Matthew', hint: D.contact.email, glyph: '✉',
      action: () => { window.location.href = `mailto:${D.contact.email}`; }
    });
    out.push({
      kind: 'action', category: 'ACTION',
      label: 'Open LinkedIn', hint: D.contact.linkedin, glyph: '↗',
      action: () => { window.open(`https://${D.contact.linkedin}`, '_blank'); }
    });
    out.push({
      kind: 'action', category: 'ACTION',
      label: 'Open Resume', hint: 'Resume.html · printable', glyph: '⎙',
      action: () => { window.location.href = 'Resume.html'; }
    });
    out.push({
      kind: 'action', category: 'ACTION',
      label: 'Download Resume PDF', hint: 'Opens print dialog', glyph: '⤓',
      action: () => { window.location.href = 'Resume.html?print=1'; }
    });

    return out;
  }, [D]);

  // Filter
  const filtered = React.useMemo(() => {
    const needle = q.trim().toLowerCase();
    if (!needle) return items;
    return items.filter(it => {
      const hay = (it.label + ' ' + (it.hint || '') + ' ' + it.category).toLowerCase();
      return hay.includes(needle);
    });
  }, [items, q]);

  // Acronym glossary — filtered by the same query
  const glossary = React.useMemo(() => {
    const A = window.ACRONYMS || {};
    const entries = Object.entries(A).sort((a, b) => a[0].localeCompare(b[0]));
    const needle = q.trim().toLowerCase();
    if (!needle) return entries;
    return entries.filter(([term, def]) => (term + ' ' + def).toLowerCase().includes(needle));
  }, [q]);

  // Reset index on filter / open
  React.useEffect(() => { setIdx(0); }, [q, open]);

  // Focus on open
  React.useEffect(() => {
    if (open) {
      setQ('');
      setTimeout(() => inputRef.current?.focus(), 50);
    }
  }, [open]);

  // Global keybinding: ⌘K, Ctrl+K, "/" (when not focused on input)
  React.useEffect(() => {
    const onKey = (e) => {
      const tgt = e.target;
      const inField = tgt && (tgt.tagName === 'INPUT' || tgt.tagName === 'TEXTAREA' || tgt.isContentEditable);
      if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 'k') {
        e.preventDefault();
        setOpen(o => !o);
      } else if (e.key === '/' && !inField && !open) {
        e.preventDefault();
        setOpen(true);
      } else if (e.key === 'Escape' && open) {
        setOpen(false);
      }
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [open, setOpen]);

  // Arrow keys + Enter inside palette
  const onInputKey = (e) => {
    if (e.key === 'ArrowDown') {
      e.preventDefault();
      setIdx(i => Math.min(filtered.length - 1, i + 1));
    } else if (e.key === 'ArrowUp') {
      e.preventDefault();
      setIdx(i => Math.max(0, i - 1));
    } else if (e.key === 'Enter') {
      e.preventDefault();
      const it = filtered[idx];
      if (it) {
        it.action();
        setOpen(false);
      }
    }
  };

  // Keep selected row in view
  React.useEffect(() => {
    if (!listRef.current) return;
    const row = listRef.current.querySelector('.cmd-row.sel');
    if (row && row.scrollIntoView) {
      row.scrollIntoView({ block: 'nearest' });
    }
  }, [idx, filtered]);

  if (!open) return null;

  // Group filtered items by category
  const groups = [];
  const seen = new Map();
  filtered.forEach((it, i) => {
    if (!seen.has(it.category)) {
      seen.set(it.category, groups.length);
      groups.push({ category: it.category, items: [] });
    }
    groups[seen.get(it.category)].items.push({ ...it, _i: i });
  });

  return (
    <div className="cmd-overlay" onClick={() => setOpen(false)}>
      <div className="cmd-palette" onClick={(e) => e.stopPropagation()}>
        <div className="cmd-bar">
          <span className="cmd-glyph">⌖</span>
          <input
            ref={inputRef}
            value={q}
            onChange={(e) => setQ(e.target.value)}
            onKeyDown={onInputKey}
            placeholder="Search sections, projects, capabilities…"
            spellCheck="false"
          />
          <span className="cmd-count">{filtered.length} / {items.length}</span>
        </div>
        <div className="cmd-list" ref={listRef}>
          {groups.length === 0 && (
            <div className="cmd-empty">No matches for "{q}"</div>
          )}
          {groups.map(g => (
            <div key={g.category} className="cmd-group">
              <div className="cmd-group-h">{g.category}</div>
              {g.items.map(it => (
                <div
                  key={it._i}
                  className={'cmd-row ' + (it._i === idx ? 'sel' : '')}
                  onMouseEnter={() => setIdx(it._i)}
                  onClick={() => { it.action(); setOpen(false); }}
                >
                  <span className="cmd-row-glyph">{it.glyph}</span>
                  <span className="cmd-row-label">{it.label}</span>
                  <span className="cmd-row-hint">{it.hint}</span>
                </div>
              ))}
            </div>
          ))}
        </div>
        <div className="cmd-foot">
          <span><kbd>↑</kbd><kbd>↓</kbd> navigate</span>
          <span><kbd>↵</kbd> open</span>
          <span><kbd>esc</kbd> close</span>
          <span><kbd>j</kbd><kbd>k</kbd> sections</span>
          <span style={{ marginLeft: 'auto', color: 'var(--dim)' }}>⌘K · /</span>
        </div>

        <aside className="cmd-glossary" onClick={(e) => e.stopPropagation()}>
          <div className="cmd-gloss-h">
            <span>Acronyms</span>
            <span className="n">{glossary.length}</span>
          </div>
          <div className="cmd-gloss-list">
            {glossary.length === 0 && (
              <div className="cmd-gloss-empty">No acronyms match "{q}"</div>
            )}
            {glossary.map(([term, def]) => (
              <div className="cmd-gloss-row" key={term}>
                <div className="cmd-gloss-term">{term}</div>
                <div className="cmd-gloss-def">{def}</div>
              </div>
            ))}
          </div>
        </aside>
      </div>
    </div>
  );
};

window.CommandPalette = CommandPalette;
