// ⌘K command palette — fuzzy search across pages, commands, guilds, actions.

function CommandPalette({ open, onClose, onRoute, onOpenGuild, onOpenCommand }) {
  const [q, setQ] = React.useState('');
  const [idx, setIdx] = React.useState(0);
  const inputRef = React.useRef(null);

  // Build flat item list
  const items = React.useMemo(() => {
    const pages = [
      { kind: 'page', label: 'Overview', sub: 'Live snapshot · stats', icon: 'home', go: () => onRoute('overview') },
      { kind: 'page', label: 'Shifts', sub: 'On-duty board · hours leaderboard', icon: 'clock', go: () => onRoute('shifts') },
      { kind: 'page', label: 'Requests', sub: 'Pending approvals · /request /need', icon: 'inbox', go: () => onRoute('requests') },
      { kind: 'page', label: 'Servers', sub: 'Guild list', icon: 'server', go: () => onRoute('servers') },
      { kind: 'page', label: 'Commands', sub: 'Slash commands · analytics', icon: 'zap', go: () => onRoute('commands') },
      { kind: 'page', label: 'Activity', sub: 'Leaderboard · users', icon: 'users', go: () => onRoute('activity') },
      { kind: 'page', label: 'Moderation', sub: 'Bans, kicks, timeouts', icon: 'shield', go: () => onRoute('moderation') },
      { kind: 'page', label: 'Logs', sub: 'Live event stream', icon: 'list', go: () => onRoute('logs') },
      { kind: 'page', label: 'Errors', sub: 'Tracked exceptions', icon: 'alert', go: () => onRoute('errors') },
      { kind: 'page', label: 'Scheduler', sub: 'Cron jobs · reminders', icon: 'calendar', go: () => onRoute('scheduler') },
      { kind: 'page', label: 'Plugins', sub: 'Cog manager', icon: 'plug', go: () => onRoute('plugins') },
      { kind: 'page', label: 'Settings', sub: 'Bot configuration · connection', icon: 'gear', go: () => onRoute('settings') },
    ];
    const actions = [
      { kind: 'action', label: 'Restart bot', sub: 'PM2 restart shift.bot', icon: 'power', go: () => { if (CONN.status !== 'connected') return toast('ยังไม่ได้เชื่อมต่อบอท', 'warning'); toastConfirm('Restart บอท?', { danger: true }).then((ok) => { if (ok) REALDATA.doAction('restart').then(() => toast('สั่ง restart แล้ว', 'success')).catch((e) => toast(e.message, 'error')); }); } },
      { kind: 'action', label: 'Reload all commands', sub: 'Hot-reload command modules', icon: 'refresh', go: () => { if (CONN.status !== 'connected') return toast('ยังไม่ได้เชื่อมต่อบอท', 'warning'); REALDATA.doAction('reload').then(() => { toast('Reload สำเร็จ', 'success'); REALDATA.refreshAll(); }).catch((e) => toast(e.message, 'error')); } },
      { kind: 'action', label: 'Send weekly report now', sub: 'Owner-only', icon: 'arrow', go: () => { if (CONN.status !== 'connected') return toast('ยังไม่ได้เชื่อมต่อบอท', 'warning'); REALDATA.doAction('weeklyreport').then(() => toast('ส่งสรุปรายสัปดาห์แล้ว', 'success')).catch((e) => toast(e.message, 'error')); } },
      { kind: 'action', label: 'Pause live stream', sub: 'Stop tick simulator', icon: 'power', go: () => LIVE.pause(!LIVE.paused) },
    ];
    const guilds = GUILDS.map((g) => ({
      kind: 'guild', label: g.name, sub: `${g.members} members · ${g.online} online`,
      color: g.color, icon: g.icon, go: () => onOpenGuild(g),
    }));
    const cmds = ALL_COMMANDS.map((c) => ({
      kind: 'command', label: `/${c.name}`, sub: c.desc, color: c.color,
      go: () => onOpenCommand(c),
    }));
    return [...pages, ...actions, ...guilds, ...cmds];
  }, [onRoute, onOpenGuild, onOpenCommand]);

  const filtered = React.useMemo(() => {
    if (!q.trim()) return items.slice(0, 30);
    const needle = q.toLowerCase();
    return items.filter((it) =>
      it.label.toLowerCase().includes(needle) ||
      (it.sub && it.sub.toLowerCase().includes(needle))
    ).slice(0, 40);
  }, [q, items]);

  React.useEffect(() => { setIdx(0); }, [q]);
  React.useEffect(() => {
    if (open && inputRef.current) {
      setTimeout(() => inputRef.current?.focus(), 30);
      setQ('');
    }
  }, [open]);

  const onKey = (e) => {
    if (e.key === 'Escape') { onClose(); return; }
    if (e.key === 'ArrowDown') { e.preventDefault(); setIdx((i) => Math.min(i + 1, filtered.length - 1)); }
    if (e.key === 'ArrowUp') { e.preventDefault(); setIdx((i) => Math.max(i - 1, 0)); }
    if (e.key === 'Enter') {
      const it = filtered[idx];
      if (it) { it.go(); onClose(); }
    }
  };

  if (!open) return null;

  // group by kind for headers
  const grouped = filtered.reduce((acc, it) => {
    (acc[it.kind] = acc[it.kind] || []).push(it);
    return acc;
  }, {});
  const groupOrder = ['page', 'action', 'guild', 'command'];
  const groupLabel = { page: 'Jump to', action: 'Actions', guild: 'Servers', command: 'Commands' };

  let runningIdx = 0;

  return (
    <div className="palette-scrim" onClick={onClose}>
      <div className="palette" onClick={(e) => e.stopPropagation()} onKeyDown={onKey}>
        <div className="palette-input">
          <I.search width="16" height="16"/>
          <input ref={inputRef} placeholder="Search commands, guilds, pages…" value={q} onChange={(e) => setQ(e.target.value)}/>
          <kbd>ESC</kbd>
        </div>
        <div className="palette-list">
          {filtered.length === 0 && <div style={{ padding: 24, color: 'var(--text-muted)', textAlign: 'center', fontSize: 13 }}>No results</div>}
          {groupOrder.map((k) => grouped[k] && (
            <div key={k}>
              <div className="palette-group">{groupLabel[k]}</div>
              {grouped[k].map((it) => {
                const myIdx = runningIdx++;
                const active = myIdx === idx;
                const Icon = it.icon ? I[it.icon] : null;
                return (
                  <button
                    key={it.label + it.sub}
                    className="palette-item"
                    data-active={active}
                    onMouseEnter={() => setIdx(myIdx)}
                    onClick={() => { it.go(); onClose(); }}
                  >
                    {it.kind === 'guild' && (
                      <div className="guild-avatar" style={{ background: it.color, width: 22, height: 22, borderRadius: 6, fontSize: 9.5 }}>{it.icon}</div>
                    )}
                    {it.kind === 'command' && (
                      <span style={{ width: 22, height: 22, borderRadius: 6, background: `color-mix(in oklab, ${it.color} 18%, transparent)`, color: it.color, display: 'grid', placeItems: 'center', fontFamily: 'var(--font-mono)', fontSize: 11 }}>/</span>
                    )}
                    {Icon && <Icon width="16" height="16"/>}
                    <div style={{ flex: 1, minWidth: 0 }}>
                      <div className="palette-label ellipsis">{it.label}</div>
                      <div className="palette-sub ellipsis">{it.sub}</div>
                    </div>
                    <span className="palette-kind">{it.kind}</span>
                    {active && <I.arrow width="13" height="13"/>}
                  </button>
                );
              })}
            </div>
          ))}
        </div>
        <div className="palette-footer">
          <span><kbd>↑↓</kbd> navigate</span>
          <span><kbd>↵</kbd> select</span>
          <span><kbd>ESC</kbd> close</span>
          <span style={{ marginLeft: 'auto', fontFamily: 'var(--font-mono)' }}>{filtered.length} / {items.length}</span>
        </div>
      </div>
    </div>
  );
}

window.CommandPalette = CommandPalette;
