/* src/v2/palette.jsx — CommandPalette (⌘K). Commands + symbol search. */

const { useState: _pcS, useEffect: _pcE, useRef: _pcR } = React;

const CMD_ITEMS = [
  { group: 'Theme',    s: 'theme.toggle',    t: 'Toggle theme',                  hint: 'light ↔ dark' },
  { group: 'Theme',    s: 'density.toggle',  t: 'Toggle density',                hint: 'comfy ↔ compact' },
  { group: 'Watchlist', s: 'watchlist.add',  t: 'Open watchlist',                hint: 'Add or remove symbols' },
  { group: 'Watchlist', s: 'watchlist.export', t: 'Export watchlist CSV',        hint: '' },

  // Markets
  { group: 'Markets',  s: 'go.dashboard',    t: 'Go to dashboard',               hint: '/dashboard' },
  { group: 'Markets',  s: 'go.heatmap',      t: 'Open Heatmap',                  hint: 'S&P 500 sector heatmap' },
  { group: 'Markets',  s: 'go.hyperliquid',  t: 'Open HyperLiquid',              hint: 'HyperLiquid DEX dashboard' },
  { group: 'Markets',  s: 'go.screener',     t: 'Open Stock Screener',           hint: 'Multi-factor screener' },
  { group: 'Markets',  s: 'go.commodities',  t: 'Open Commodities & FX',         hint: 'Commodity & currency markets' },
  { group: 'Markets',  s: 'go.earnings',     t: 'Open Market Earnings Report',   hint: 'Earnings season & revisions' },
  { group: 'Markets',  s: 'go.13f',          t: 'Open Capital Allocators (13F)', hint: '13F filing analysis' },
  { group: 'Markets',  s: 'go.ipo',          t: 'Open IPO Tracker',              hint: 'Recent & upcoming IPOs' },

  // Research
  { group: 'Research', s: 'go.calendar',     t: 'Open Economic Calendar',        hint: 'Upcoming data releases' },
  { group: 'Research', s: 'go.macro',        t: 'Open Macro Environment',        hint: 'Federal Reserve economic data' },
  { group: 'Research', s: 'go.factors',      t: 'Open Regime & Sector Analysis', hint: 'Factor analysis & regimes' },
  { group: 'Research', s: 'go.cpi',          t: 'Open Inflation Dashboard',      hint: 'CPI breakdown & trends' },
  { group: 'Research', s: 'go.bulletin',     t: 'Open Signals Desk',             hint: 'Anomaly detection & signals' },

  // AI
  { group: 'AI',       s: 'go.ai',           t: 'Open AI Hyperscale Dashboard',  hint: 'AI industry tracker' },
  { group: 'AI',       s: 'go.data-centers', t: 'Open AI Data Centers',          hint: 'Data center REITs & demand' },
  { group: 'AI',       s: 'go.utilities',    t: 'Open Utilities & Power',        hint: 'Power generation & utilities' },

  // More
  { group: 'More',     s: 'go.relative-strength', t: 'Open Watchlist Relative Strength', hint: 'RS rankings & momentum' },
  { group: 'More',     s: 'go.portfolio',    t: 'Open Portfolio',                hint: 'Track your holdings' },
];

function CommandPalette({ open, onClose, onCmd }) {
  const [query, setQuery] = _pcS('');
  const [symResults, setSymResults] = _pcS([]);
  const [active, setActive] = _pcS(0);
  const inputRef = _pcR(null);

  _pcE(() => {
    if (open) {
      setQuery('');
      setSymResults([]);
      setActive(0);
      setTimeout(() => inputRef.current && inputRef.current.focus(), 30);
    }
  }, [open]);

  // Symbol search — debounced
  _pcE(() => {
    if (!open) return;
    const q = query.trim();
    if (q.length < 1) { setSymResults([]); return; }
    let alive = true;
    const id = setTimeout(async () => {
      try {
        const data = await window.TMT_API.getJSON('/search?q=' + encodeURIComponent(q));
        if (!alive) return;
        setSymResults(((data && data.results) || []).slice(0, 8));
      } catch { if (alive) setSymResults([]); }
    }, 180);
    return () => { alive = false; clearTimeout(id); };
  }, [query, open]);

  // Filtered commands
  const filteredCmds = (() => {
    if (!query) return CMD_ITEMS;
    const q = query.toLowerCase();
    return CMD_ITEMS.filter(c => c.t.toLowerCase().includes(q) || c.s.includes(q) || (c.group || '').toLowerCase().includes(q));
  })();

  // Flattened list for keyboard navigation
  const flat = [
    ...filteredCmds.map(c => ({ type: 'cmd', data: c })),
    ...symResults.map(r => ({ type: 'sym', data: r })),
  ];

  _pcE(() => {
    if (!open) return;
    const onKey = (e) => {
      if (e.key === 'Escape') { e.preventDefault(); onClose && onClose(); return; }
      if (e.key === 'ArrowDown') { e.preventDefault(); setActive(a => Math.min(flat.length - 1, a + 1)); return; }
      if (e.key === 'ArrowUp')   { e.preventDefault(); setActive(a => Math.max(0, a - 1)); return; }
      if (e.key === 'Enter' && flat[active]) {
        e.preventDefault();
        pickItem(flat[active]);
      }
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [open, flat, active]);

  const pickItem = (item) => {
    if (!item) return;
    if (item.type === 'cmd') {
      if (onCmd) onCmd(item);
      const s = item.data.s;
      // Navigation commands — route table mirrors the legacy header tool registry
      // so anyone familiar with the old site finds the same destinations.
      const ROUTES = {
        'go.dashboard':         '/dashboard.html',
        'go.heatmap':           '/heatmap.html',
        'go.hyperliquid':       '/hyperliquid.html',
        'go.screener':          '/screener.html',
        'go.commodities':       '/commodities.html',
        'go.earnings':          '/earnings.html',
        'go.13f':               '/13f.html',
        'go.ipo':               '/ipo.html',
        'go.calendar':          '/calendar.html',
        'go.macro':             '/macro.html',
        'go.factors':           '/factors.html',
        'go.cpi':               '/cpi.html',
        'go.bulletin':          '/bulletin.html',
        'go.ai':                '/ai-tracker.html',
        'go.data-centers':      '/ai-tracker.html?tab=data-centers',
        'go.utilities':         '/utilities.html',
        'go.relative-strength': '/relative-strength.html',
        'go.portfolio':         '/portfolio.html',
      };
      if (ROUTES[s]) window.location.href = ROUTES[s];
      onClose && onClose();
    } else if (item.type === 'sym') {
      window.location.href = '/details.html?symbol=' + encodeURIComponent(item.data.symbol);
    }
  };

  if (!open) return null;

  return (
    <div className="cmd-scrim" onClick={onClose}>
      <div className="cmd-modal" onClick={e => e.stopPropagation()}>
        <div className="cmd-input-row">
          <span className="p">⌕</span>
          <input
            ref={inputRef}
            type="text"
            placeholder="Search symbols, news, funds, or type a command…"
            value={query}
            onChange={e => { setQuery(e.target.value); setActive(0); }}
          />
          <span className="s" style={{ fontFamily: 'var(--mono)', color: 'var(--ink-3)', fontSize: 11 }}>ESC</span>
        </div>
        <div className="cmd-list">
          {filteredCmds.length > 0 && <div className="cmd-group-hd">Commands</div>}
          {filteredCmds.map((c, i) => {
            const idx = i;
            return (
              <div
                key={c.s}
                className={'cmd-item ' + (idx === active ? 'active' : '')}
                onMouseEnter={() => setActive(idx)}
                onClick={() => pickItem({ type: 'cmd', data: c })}
              >
                <span className="i">›</span>
                <span className="t">{c.t}</span>
                <span className="s">{c.hint}</span>
              </div>
            );
          })}
          {symResults.length > 0 && <div className="cmd-group-hd">Symbols</div>}
          {symResults.map((r, i) => {
            const idx = filteredCmds.length + i;
            return (
              <div
                key={r.symbol}
                className={'cmd-item ' + (idx === active ? 'active' : '')}
                onMouseEnter={() => setActive(idx)}
                onClick={() => pickItem({ type: 'sym', data: r })}
              >
                <span className="i">#</span>
                <span className="t"><b>{r.symbol}</b> · {r.shortname || r.longname || r.name || ''}</span>
                <span className="s">{r.exchange || ''}</span>
              </div>
            );
          })}
          {flat.length === 0 && (
            <div style={{ padding: 20, textAlign: 'center', color: 'var(--ink-3)', fontFamily: 'var(--serif)', fontStyle: 'italic' }}>
              Nothing matches.
            </div>
          )}
        </div>
        <div className="cmd-hint">
          <span><kbd>↑↓</kbd> navigate</span>
          <span><kbd>↵</kbd> select</span>
          <span><kbd>ESC</kbd> close</span>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { CommandPalette });
