// Cents — Hitcents' in-house AI assistant overlay
// Modes: Chat (text + tool calls), Voice (live conversation), Meeting (transcribe + extract)
// Interfaces with the ERP via tool calls — create tasks, update deals, send messages, etc.

const { useState: aiState, useEffect: aiEffect, useRef: aiRef, useMemo: aiMemo } = React;

// ── Sparkle / star mark for Cents ──
function CentsMark({ size = 16, color }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" aria-hidden="true">
      <defs>
        <linearGradient id={`cents-grad-${size}`} x1="0" y1="0" x2="1" y2="1">
          <stop offset="0%" stopColor="#FFB089"/>
          <stop offset="100%" stopColor="#E0552B"/>
        </linearGradient>
      </defs>
      <path
        d="M12 2 L13.7 9.1 L21 11 L13.7 12.9 L12 20 L10.3 12.9 L3 11 L10.3 9.1 Z"
        fill={color || `url(#cents-grad-${size})`} />
      <path
        d="M19 3 L19.7 5.3 L22 6 L19.7 6.7 L19 9 L18.3 6.7 L16 6 L18.3 5.3 Z"
        fill={color || `url(#cents-grad-${size})`} opacity="0.85" />
    </svg>
  );
}

// ── Pre-baked chat thread — an LLM back-and-forth where Cents surfaces rich
// inline cards (KPIs, sparklines, a live kanban, record cards) and performs
// faked CRUD across the whole ERP via tool calls. ──
const AI_CHAT_THREAD = [
  { role: 'user', text: 'Morning — give me a pulse on Q2: revenue, pipeline, and anything on fire.', when: '9:42 AM' },
  { role: 'tool', state: 'done', title: 'Read across 4 workspaces', sub: 'CRM · Finance · IT Services · Projects — 11 deals, 8 invoices, 6 tickets', icon: 'search' },
  {
    role: 'assistant', when: '9:42 AM',
    text: 'Here\'s where Q2 stands. Pipeline is healthy, two deals are slipping, and AR is running a little hot. Nothing on fire in support.',
    cards: [
      { type: 'kpi', items: [
        { label: 'Open pipeline', value: '$1.06M', delta: '+8% wk', tone: 'up' },
        { label: 'Weighted', value: '$486K', delta: 'prob-adj', tone: 'flat' },
        { label: 'Closed won · Q2', value: '$214K', delta: '3 deals', tone: 'up' },
        { label: 'AR outstanding', value: '$98K', delta: '2 overdue', tone: 'down' },
      ] },
    ],
  },
  { role: 'user', text: 'Compare this quarter\'s revenue to last. What\'s the trend?', when: '9:43 AM' },
  {
    role: 'assistant', when: '9:43 AM',
    text: 'Up and to the right — recurring is carrying it. Services dipped after the Pinecrest one-off closed out.',
    cards: [
      { type: 'spark', title: 'Revenue trend · last 8 weeks', series: [
        { label: 'Total revenue', value: '$1.21M', delta: '+12%', tone: 'up', points: [34, 38, 36, 42, 40, 48, 52, 58] },
        { label: 'Recurring (MRR×3)', value: '$642K', delta: '+6%', tone: 'up', points: [40, 41, 42, 44, 45, 47, 49, 52] },
        { label: 'Services', value: '$71K', delta: '−18%', tone: 'down', points: [28, 32, 30, 26, 22, 20, 18, 15] },
      ] },
    ],
  },
  { role: 'user', text: 'Northbrook renewal keeps stalling. What\'s the state — and can you push it forward?', when: '9:44 AM' },
  { role: 'tool', state: 'done', title: 'Read deal', sub: 'CRM · Northbrook — Renewal + Add-on', icon: 'card' },
  {
    role: 'assistant', when: '9:44 AM',
    text: 'It\'s been parked in Proposal for 9 days — past our 7-day stage SLA. Garrett owns it; the blocker is a security review on their side. Here\'s the live record:',
    cards: [
      { type: 'record', kind: 'deal', title: 'Northbrook — Renewal + Add-on',
        badge: { label: 'Proposal', tone: 'blue' },
        fields: [ { k: 'Value', v: '$384,000' }, { k: 'Owner', v: 'Garrett Holm' }, { k: 'Close', v: 'Jul 15' }, { k: 'Probability', v: '45%' } ],
        actions: [
          { label: 'Advance to Negotiation', icon: 'arrow_r', primary: true, tool: 'Updated deal · Northbrook → Negotiation', sub: 'CRM · stage changed, probability 45% → 60%', reply: 'Moved Northbrook to Negotiation and bumped probability to 60%. I dropped the security-review context into #sales so Garrett can unblock it.' },
          { label: 'Log activity', icon: 'pencil', tool: 'Logged activity · Northbrook', sub: 'CRM · note added to timeline', reply: 'Logged a note on the Northbrook timeline.' },
        ] },
    ],
  },
  { role: 'user', text: 'Good. What does eng\'s board look like for Atlas v4 — and move the migration runbook to In progress.', when: '9:46 AM' },
  { role: 'tool', state: 'done', title: 'Updated task', sub: 'Projects · ATL-4 "Migration runbook" → In progress', icon: 'check' },
  {
    role: 'assistant', when: '9:46 AM',
    text: 'Done — runbook is In progress now, still on Imani. Here\'s the live sprint board. You can nudge cards forward right here and I\'ll write it back.',
    cards: [ { type: 'kanban', title: 'Atlas v4 · sprint board' } ],
  },
  { role: 'user', text: 'Create a task for Imani to finish the multi-tenant rollback path by Friday, and delete that duplicate "Webhook v2" card.', when: '9:48 AM' },
  { role: 'tool', state: 'done', title: 'Created task', sub: 'Projects · ATL-4 "Rollback path" → Imani, due Fri', icon: 'plus' },
  { role: 'tool', state: 'done', title: 'Deleted task', sub: 'Projects · removed duplicate "Webhook v2 (copy)"', icon: 'trash' },
  {
    role: 'assistant', when: '9:48 AM',
    text: 'Created and assigned, and cleaned up the duplicate. Here\'s the new task:',
    cards: [
      { type: 'record', kind: 'task', title: 'Finish multi-tenant rollback path',
        badge: { label: 'In progress', tone: 'amber' },
        fields: [ { k: 'Assignee', v: 'Imani Ostrander' }, { k: 'Project', v: 'Atlas v4' }, { k: 'Due', v: 'Fri · May 16' }, { k: 'Priority', v: 'High' } ],
        actions: [
          { label: 'Reassign', icon: 'users', tool: 'Reassigned task', sub: 'Owner updated', reply: 'Who should own it instead? I can move it to anyone on eng.' },
        ] },
    ],
  },
];

const AI_SUGGESTIONS = [
  { icon: 'card',      text: 'Show me deals slipping in Q2' },
  { icon: 'briefcase', text: 'Status of every red project, one line each' },
  { icon: 'users',     text: 'Who hasn\'t taken PTO this quarter?' },
  { icon: 'spark',     text: 'Summarize this week\'s innovation pipeline' },
  { icon: 'card',      text: 'Draft a follow-up to Northbrook' },
  { icon: 'doc',       text: 'What\'s in the May affiliate payout batch?' },
];

const AI_VOICE_TRANSCRIPT = [
  { who: 'user', text: 'Hey Cents, where are we on the Atlas v4 launch checklist?' },
  { who: 'ai',   text: 'You\'re at 11 of 14 items green. Three are still amber: the migration runbook is in review with Imani, the EU DPA pack is waiting on legal, and the press kit needs Lucia\'s final approval.' },
  { who: 'user', text: 'How long until the migration runbook clears review?' },
  { who: 'ai',   text: 'Imani targeted today end of day. She\'s been heads-down on it since Tuesday. Want me to ping her for a confidence check?' },
  { who: 'user', text: 'Yes, do that, and pull the EU DPA over to Davis — legal is sitting on it.' },
];

const AI_MEETING_TRANSCRIPT = [
  { who: 'Davis Park',     role: 'VP Eng',     text: 'OK so the readiness gate — Imani, where are we on the migration runbook?' },
  { who: 'Imani Okafor',   role: 'Staff Eng',  text: 'Runbook is at 90%. I\'ll have it in PR by 4pm today. One open question on the multi-tenant rollback path — I want to walk it through with Nadia first.' },
  { who: 'Davis Park',     role: 'VP Eng',     text: 'OK. Maren, on the EU side — Frankfurt region is live, but the DPA pack is stuck.' },
  { who: 'Maren Chen',     role: 'CEO',        text: 'I\'ll move the DPA to the top of legal\'s queue this afternoon. Klein pilot can\'t slip — they\'re our beachhead in EU.' },
  { who: 'Lucia Romano',   role: 'Marketing',  text: 'Press kit is final pending the Stratoscale customer quote. Yuki is chasing that today.' },
  { who: 'Davis Park',     role: 'VP Eng',     text: 'Good. Anything blocking GA besides those three?' },
  { who: 'Imani Okafor',   role: 'Staff Eng',  text: 'No new blockers. Webhook v2 signed off after the canary review.' },
];

const AI_MEETING_INSIGHTS = {
  decisions: [
    'Migration runbook target: 4pm today PR-ready (Imani)',
    'EU DPA pack moved to top of legal queue (Maren, this afternoon)',
    'GA blockers = runbook · DPA · press kit. Webhook v2 signed off.',
  ],
  actions: [
    { who: 'e10', task: 'Walk multi-tenant rollback path with Nadia', due: 'today' },
    { who: 'e1',  task: 'Escalate Klein & Auer DPA to legal',         due: 'this afternoon' },
    { who: 'e19', task: 'Chase Stratoscale customer quote',           due: 'today EOD' },
    { who: 'e2',  task: 'Final readiness call after PR lands',        due: 'Friday' },
  ],
  mentions: [
    { kind: 'project', label: 'Atlas v4 · migration runbook', tone: 'orange' },
    { kind: 'project', label: 'Atlas v4 · EU DPA pack',       tone: 'blue' },
    { kind: 'customer',label: 'Klein & Auer',                 tone: 'teal' },
    { kind: 'customer',label: 'Stratoscale',                  tone: 'purple' },
  ],
};

// ─────────────────────────────────────────────────────────────
// Top-level overlay
// ─────────────────────────────────────────────────────────────
function AIAssistantOverlay({ open, onClose, currentUser }) {
  const [mode, setMode] = aiState('chat');
  const [draft, setDraft] = aiState('');
  const [thread, setThread] = aiState(AI_CHAT_THREAD);
  const { popped, setPopped, pos, onHeaderPointerDown } = usePopout({ x: 360, y: 80 });
  const scrollRef = aiRef(null);

  aiEffect(() => {
    if (scrollRef.current) scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
  }, [thread, mode, open]);

  if (!open) return null;

  function send() {
    if (!draft.trim()) return;
    setThread(t => [...t, { role: 'user', text: draft, when: 'now' }]);
    setDraft('');
  }
  function onKey(e) {
    if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); send(); }
  }

  // Faked CRUD: append a running tool row, settle it, then reply.
  function handleCardAction(action) {
    if (!action) return;
    if (action.nav) {
      window.dispatchEvent(new CustomEvent('hitcents:navigate', { detail: { section: action.nav } }));
      onClose();
      return;
    }
    const id = 'act-' + Date.now() + Math.random();
    setThread(t => [...t, { role: 'tool', state: 'running', title: action.tool, sub: action.sub, icon: action.icon || 'bolt', _id: id }]);
    setTimeout(() => {
      setThread(t => t.map(m => m._id === id ? { ...m, state: 'done' } : m));
      if (action.reply) setThread(t => [...t, { role: 'assistant', text: action.reply, when: 'now' }]);
    }, 850);
  }

  return (
    <div className={`ai-scrim ${popped ? 'popped' : ''}`} onClick={popped ? undefined : onClose}>
      <div className={`ai-shell ${popped ? 'popped' : ''}`} onClick={e => e.stopPropagation()}
           style={popped ? { left: pos.x, top: pos.y } : undefined}>
        {/* Header */}
        <header className="ai-head" onPointerDown={onHeaderPointerDown} style={popped ? { cursor: 'move' } : undefined}>
          <div className="row gap-2" style={{ flex: 1, minWidth: 0 }}>
            <div className="ai-mark"><CentsMark size={20} /></div>
            <div style={{ minWidth: 0 }}>
              <div className="row gap-2" style={{ fontWeight: 600, fontSize: 14, color: 'var(--text-on-dark)' }}>
                Cents
                <span className="ai-pill">in-house AI</span>
              </div>
              <div style={{ fontSize: 11, color: 'var(--text-on-dark-dim)', marginTop: 1 }}>
                Full read/write across 16 workspaces · 14 tools
              </div>
            </div>
          </div>
          <div className="row gap-1">
            <button className="ai-icon-btn" onClick={() => setPopped(p => !p)} title={popped ? 'Dock to side' : 'Pop out as window'}>
              <Icon name={popped ? 'arrow_r' : 'copy'} size={14} />
            </button>
            <button className="ai-icon-btn" onClick={onClose} title="Close"><Icon name="x" size={14} /></button>
          </div>
        </header>

        {/* Mode tabs */}
        <div className="ai-tabs">
          {[
            { id: 'chat',    label: 'Chat',    icon: 'chat' },
            { id: 'voice',   label: 'Voice',   icon: 'phone' },
            { id: 'meeting', label: 'Meeting', icon: 'users' },
          ].map(t => (
            <button key={t.id}
              className={`ai-tab ${mode === t.id ? 'active' : ''}`}
              onClick={() => setMode(t.id)}>
              <Icon name={t.icon} size={13} />
              <span>{t.label}</span>
              {t.id === 'meeting' && <span className="ai-tab-dot" />}
            </button>
          ))}
        </div>

        {/* Body */}
        {mode === 'chat' && (
          <AIChatPane thread={thread} scrollRef={scrollRef} currentUser={currentUser}
            draft={draft} setDraft={setDraft} onKey={onKey} onSend={send}
            onAction={handleCardAction}
            onSuggestion={(s) => setDraft(s)} />
        )}
        {mode === 'voice'   && <AIVoicePane currentUser={currentUser} onSwitch={() => setMode('chat')} />}
        {mode === 'meeting' && <AIMeetingPane onSwitch={() => setMode('chat')} />}
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Chat pane
// ─────────────────────────────────────────────────────────────
function AIChatPane({ thread, scrollRef, currentUser, draft, setDraft, onKey, onSend, onSuggestion, onAction }) {
  return (
    <>
      <div className="ai-messages" ref={scrollRef}>
        {/* Greeting / day header */}
        <div className="ai-day-marker"><span>Today · started 9:42 AM</span></div>

        {thread.map((m, i) => <AIMessage key={i} m={m} currentUser={currentUser} onAction={onAction} />)}

        {/* Suggested prompts at the end */}
        <div className="ai-suggestions">
          <div className="ai-suggestions-h">Try asking</div>
          <div className="ai-suggestions-grid">
            {AI_SUGGESTIONS.map((s, i) => (
              <button key={i} className="ai-suggestion" onClick={() => onSuggestion(s.text)}>
                <Icon name={s.icon} size={13} />
                <span>{s.text}</span>
              </button>
            ))}
          </div>
        </div>
      </div>

      <div className="ai-composer">
        <div className="ai-composer-row">
          <textarea
            value={draft}
            onChange={e => setDraft(e.target.value)}
            onKeyDown={onKey}
            placeholder="Ask Cents to do anything across Hitcents…"
            rows={1} />
        </div>
        <div className="ai-composer-foot">
          <div className="row gap-1">
            <button className="ai-pill-btn"><Icon name="link" size={12} /><span>Attach</span></button>
            <button className="ai-pill-btn"><Icon name="layers" size={12} /><span>Context</span><span className="ai-ctx-count">3</span></button>
            <button className="ai-pill-btn"><Icon name="bolt" size={12} /><span>Tools</span><span className="ai-ctx-count">14</span></button>
          </div>
          <div className="row gap-2">
            <span className="dim mono" style={{ fontSize: 10.5 }}>⌘↵</span>
            <button className={`ai-send ${draft.trim() ? 'on' : ''}`} onClick={onSend} disabled={!draft.trim()}>
              <Icon name="arrow_u" size={14} stroke={2.2} />
            </button>
          </div>
        </div>
      </div>
    </>
  );
}

function AIMessage({ m, currentUser, onAction }) {
  if (m.role === 'user') {
    return (
      <div className="ai-msg user">
        <div className="ai-bubble user">
          <div>{m.text}</div>
          {m.when && <div className="ai-msg-when">{m.when}</div>}
        </div>
        <Avatar person={currentUser} size={26} />
      </div>
    );
  }
  if (m.role === 'tool') {
    return (
      <div className="ai-tool-row">
        <div className="ai-tool-spine">
          <div className={`ai-tool-dot ${m.state}`}>
            {m.state === 'running'
              ? <span className="ai-spinner" />
              : <Icon name="check" size={10} stroke={3} />}
          </div>
        </div>
        <div className="ai-tool-card">
          <div className="row gap-2">
            <Icon name={m.icon} size={13} style={{ color: 'var(--brand-orange)' }} />
            <div style={{ flex: 1, minWidth: 0 }}>
              <div className="ai-tool-title">{m.title}</div>
              <div className="ai-tool-sub">{m.sub}</div>
            </div>
            {m.state === 'done' && <span className="ai-tool-state">done</span>}
            {m.state === 'running' && <span className="ai-tool-state running">running</span>}
          </div>
        </div>
      </div>
    );
  }
  // assistant
  return (
    <div className="ai-msg ai">
      <div className="ai-msg-avatar"><CentsMark size={16} /></div>
      <div className="ai-bubble ai">
        <div>{m.text}</div>
        {m.artifact && <AIRedlineArtifact a={m.artifact} />}
        {m.cards && m.cards.map((c, i) => <AICard key={i} card={c} onAction={onAction} />)}
        {m.citations && (
          <div className="ai-cites">
            {m.citations.map((c, i) => (
              <span key={i} className={`ai-cite ${c.tone}`}>
                <Icon name={c.kind === 'ticket' ? 'headset' : c.kind === 'project' ? 'briefcase' : 'doc'} size={10} />
                {c.label}
              </span>
            ))}
          </div>
        )}
        {m.when && <div className="ai-msg-when">{m.when}</div>}
      </div>
    </div>
  );
}

function AIRedlineArtifact({ a }) {
  return (
    <div className="ai-artifact">
      <div className="ai-artifact-h">
        <Icon name="pencil" size={11} />
        <span style={{ flex: 1 }}>{a.title}</span>
        <span className="ai-artifact-kind">redline</span>
      </div>
      <div className="ai-artifact-body mono">
        {a.lines.map((ln, i) => (
          <div key={i} className={ln.strike ? 'ai-line-out' : (i > 0 && a.lines[i-1].strike ? 'ai-line-in' : '')}>
            {ln.strike ? '− ' : (i > 0 && a.lines[i-1].strike ? '+ ' : '\u00A0\u00A0')}{ln.text}
          </div>
        ))}
      </div>
      <div className="ai-artifact-foot">
        <button className="ai-pill-btn"><Icon name="check" size={11} />Accept</button>
        <button className="ai-pill-btn"><Icon name="pencil" size={11} />Edit</button>
        <button className="ai-pill-btn"><Icon name="send" size={11} />Send to Ramon</button>
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Inline rich cards Cents can surface in chat
// ─────────────────────────────────────────────────────────────
function AICard({ card, onAction }) {
  if (card.type === 'kpi') return <AICardKpi items={card.items} />;
  if (card.type === 'spark') return <AICardSpark title={card.title} series={card.series} />;
  if (card.type === 'kanban') return <AICardKanban title={card.title} onAction={onAction} />;
  if (card.type === 'record') return <AICardRecord card={card} onAction={onAction} />;
  return null;
}

function AICardKpi({ items }) {
  return (
    <div className="ai-card ai-kpi-card">
      {items.map((k, i) => (
        <div key={i} className="ai-kpi">
          <div className="ai-kpi-label">{k.label}</div>
          <div className="ai-kpi-value">{k.value}</div>
          <div className={`ai-kpi-delta ${k.tone}`}>
            {k.tone === 'up' && <Icon name="arrow_u" size={10} stroke={2.4} />}
            {k.tone === 'down' && <Icon name="arrow_d" size={10} stroke={2.4} />}
            {k.delta}
          </div>
        </div>
      ))}
    </div>
  );
}

function sparkPath(points, w, h, pad = 2) {
  const min = Math.min(...points), max = Math.max(...points);
  const span = max - min || 1;
  const step = (w - pad * 2) / (points.length - 1);
  return points.map((p, i) => `${i === 0 ? 'M' : 'L'} ${(pad + i * step).toFixed(1)} ${(h - pad - ((p - min) / span) * (h - pad * 2)).toFixed(1)}`).join(' ');
}

function AICardSpark({ title, series }) {
  const toneColor = { up: '#1F8A5B', down: '#C2452C', flat: '#7A6B62' };
  return (
    <div className="ai-card ai-spark-card">
      <div className="ai-card-h">{title}</div>
      {series.map((s, i) => {
        const col = toneColor[s.tone] || '#7A6B62';
        return (
          <div key={i} className="ai-spark-row">
            <div className="ai-spark-meta">
              <div className="ai-spark-label">{s.label}</div>
              <div className="ai-spark-value">{s.value}</div>
            </div>
            <svg className="ai-spark-svg" viewBox="0 0 120 32" preserveAspectRatio="none">
              <path d={sparkPath(s.points, 120, 32)} fill="none" stroke={col} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
            </svg>
            <div className={`ai-spark-delta ${s.tone}`} style={{ color: col }}>{s.delta}</div>
          </div>
        );
      })}
    </div>
  );
}

const AI_KANBAN_COLS = [
  { id: 'todo', name: 'To do' },
  { id: 'doing', name: 'In progress' },
  { id: 'review', name: 'Review' },
  { id: 'done', name: 'Done' },
];
const AI_KANBAN_SEED = [
  { id: 'k1', title: 'Migration runbook', who: 'e10', col: 'doing' },
  { id: 'k2', title: 'EU DPA pack', who: 'e1', col: 'todo' },
  { id: 'k3', title: 'Press kit', who: 'e19', col: 'review' },
  { id: 'k4', title: 'Webhook v2 canary', who: 'e12', col: 'done' },
  { id: 'k5', title: 'Rollback path', who: 'e10', col: 'todo' },
];

function AICardKanban({ title, onAction }) {
  const [cards, setCards] = aiState(AI_KANBAN_SEED);
  function advance(card) {
    const idx = AI_KANBAN_COLS.findIndex(c => c.id === card.col);
    if (idx >= AI_KANBAN_COLS.length - 1) return;
    const next = AI_KANBAN_COLS[idx + 1];
    setCards(cs => cs.map(c => c.id === card.id ? { ...c, col: next.id } : c));
    onAction && onAction({ tool: `Updated task · ${card.title} → ${next.name}`, sub: 'Projects · ATL-4 board write-back', icon: 'check', silent: true });
  }
  return (
    <div className="ai-card ai-kanban-card">
      <div className="ai-card-h">{title}</div>
      <div className="ai-kanban">
        {AI_KANBAN_COLS.map(col => {
          const colCards = cards.filter(c => c.col === col.id);
          return (
            <div key={col.id} className="ai-kanban-col">
              <div className="ai-kanban-col-h">{col.name}<span>{colCards.length}</span></div>
              {colCards.map(c => {
                const p = getEmployee(c.who);
                const last = col.id === 'done';
                return (
                  <div key={c.id} className="ai-kanban-card-item">
                    <span style={{ flex: 1, minWidth: 0 }}>{c.title}</span>
                    <Avatar person={p} size={16} />
                    {!last && <button className="ai-kanban-adv" title="Advance" onClick={() => advance(c)}><Icon name="chev_r" size={11} stroke={2.4} /></button>}
                  </div>
                );
              })}
              {colCards.length === 0 && <div className="ai-kanban-empty">—</div>}
            </div>
          );
        })}
      </div>
    </div>
  );
}

function AICardRecord({ card, onAction }) {
  const kindIcon = { deal: 'card', task: 'check', customer: 'store', contract: 'doc' }[card.kind] || 'layers';
  return (
    <div className="ai-card ai-record-card">
      <div className="ai-record-h">
        <span className="ai-record-glyph"><Icon name={kindIcon} size={13} /></span>
        <span className="ai-record-title">{card.title}</span>
        {card.badge && <span className={`ai-cite ${card.badge.tone}`} style={{ flexShrink: 0 }}>{card.badge.label}</span>}
      </div>
      <div className="ai-record-fields">
        {card.fields.map((f, i) => (
          <div key={i} className="ai-record-field">
            <span className="ai-record-k">{f.k}</span>
            <span className="ai-record-v">{f.v}</span>
          </div>
        ))}
      </div>
      {card.actions && (
        <div className="ai-record-actions">
          {card.actions.map((a, i) => (
            <button key={i} className={`ai-card-btn ${a.primary ? 'primary' : ''}`} onClick={() => onAction && onAction(a)}>
              {a.icon && <Icon name={a.icon} size={11} />}{a.label}
            </button>
          ))}
        </div>
      )}
    </div>
  );
}

function AIVoicePane({ currentUser, onSwitch }) {
  const [muted, setMuted] = aiState(false);
  const [shownLines, setShownLines] = aiState(2);

  aiEffect(() => {
    if (shownLines >= AI_VOICE_TRANSCRIPT.length) return;
    const t = setTimeout(() => setShownLines(n => Math.min(n + 1, AI_VOICE_TRANSCRIPT.length)), 2800);
    return () => clearTimeout(t);
  }, [shownLines]);

  return (
    <div className="ai-voice">
      <div className="ai-voice-status">
        <span className="ai-voice-status-dot" />
        <span>Listening · 02:14</span>
      </div>

      {/* Orb */}
      <div className="ai-orb">
        <div className="ai-orb-ring r1" />
        <div className="ai-orb-ring r2" />
        <div className="ai-orb-ring r3" />
        <div className="ai-orb-core">
          <CentsMark size={48} color="#fff" />
        </div>
      </div>

      <div className="ai-eq">
        {Array.from({ length: 24 }).map((_, i) => (
          <span key={i} style={{ animationDelay: `${(i % 8) * 0.07}s` }} />
        ))}
      </div>

      {/* Live transcript — last few utterances */}
      <div className="ai-voice-tx">
        {AI_VOICE_TRANSCRIPT.slice(0, shownLines).map((l, i, a) => (
          <div key={i} className={`ai-voice-line ${l.who} ${i === a.length - 1 ? 'live' : ''}`}>
            <span className="ai-voice-who">{l.who === 'ai' ? 'Cents' : currentUser?.name?.split(' ')[0] || 'You'}</span>
            <span>{l.text}</span>
          </div>
        ))}
      </div>

      {/* Controls */}
      <div className="ai-voice-ctrls">
        <button className={`ai-vbtn ${muted ? 'on' : ''}`} onClick={() => setMuted(m => !m)} title={muted ? 'Unmute' : 'Mute'}>
          <Icon name={muted ? 'lock' : 'phone'} size={18} />
          <span>{muted ? 'Muted' : 'Mute'}</span>
        </button>
        <button className="ai-vbtn end" title="End call">
          <Icon name="x" size={20} stroke={2.4} />
        </button>
        <button className="ai-vbtn" onClick={onSwitch} title="Switch to chat">
          <Icon name="mail" size={18} />
          <span>Chat</span>
        </button>
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Meeting pane
// ─────────────────────────────────────────────────────────────
function AIMeetingPane({ onSwitch }) {
  const [tab, setTab] = aiState('insights'); // 'insights' | 'transcript'
  return (
    <div className="ai-meeting">
      {/* Recording bar */}
      <div className="ai-meeting-rec">
        <div className="row gap-2" style={{ flex: 1 }}>
          <span className="ai-rec-dot" />
          <div style={{ minWidth: 0 }}>
            <div style={{ fontWeight: 600, fontSize: 13 }}>Atlas v4 architecture sync</div>
            <div className="dim" style={{ fontSize: 11 }}>Recording · 14:22 · 6 participants · auto-transcribing</div>
          </div>
        </div>
        <button className="ai-pill-btn danger"><span style={{ width: 8, height: 8, background: 'currentColor', borderRadius: 1 }} />Stop</button>
      </div>

      {/* Tabs inside the pane */}
      <div className="ai-mtg-tabs">
        <button className={`ai-mtg-tab ${tab === 'insights' ? 'active' : ''}`} onClick={() => setTab('insights')}>
          <Icon name="bolt" size={12} />Live insights
          <span className="ai-tab-count">{AI_MEETING_INSIGHTS.actions.length + AI_MEETING_INSIGHTS.decisions.length}</span>
        </button>
        <button className={`ai-mtg-tab ${tab === 'transcript' ? 'active' : ''}`} onClick={() => setTab('transcript')}>
          <Icon name="doc" size={12} />Transcript
        </button>
      </div>

      {tab === 'insights' ? (
        <div className="ai-mtg-body">
          <div className="ai-mtg-sec">
            <div className="ai-mtg-sec-h"><Icon name="flag" size={12} />Decisions</div>
            {AI_MEETING_INSIGHTS.decisions.map((d, i) => (
              <div key={i} className="ai-mtg-decision">
                <span className="ai-mtg-bullet" />{d}
              </div>
            ))}
          </div>

          <div className="ai-mtg-sec">
            <div className="ai-mtg-sec-h"><Icon name="check" size={12} />Action items <span className="dim">— Cents will create these</span></div>
            {AI_MEETING_INSIGHTS.actions.map((a, i) => {
              const p = getEmployee(a.who);
              return (
                <div key={i} className="ai-mtg-action">
                  <Avatar person={p} size={22} />
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontSize: 12.5, color: 'var(--text)' }}>{a.task}</div>
                    <div className="dim" style={{ fontSize: 11 }}>{p?.name} · due {a.due}</div>
                  </div>
                  <button className="ai-mtg-create"><Icon name="plus" size={11} stroke={2.4} />Task</button>
                </div>
              );
            })}
          </div>

          <div className="ai-mtg-sec">
            <div className="ai-mtg-sec-h"><Icon name="link" size={12} />Mentioned</div>
            <div className="row gap-2" style={{ flexWrap: 'wrap' }}>
              {AI_MEETING_INSIGHTS.mentions.map((m, i) => (
                <span key={i} className={`ai-cite ${m.tone}`}>
                  <Icon name={m.kind === 'customer' ? 'card' : 'briefcase'} size={10} />
                  {m.label}
                </span>
              ))}
            </div>
          </div>
        </div>
      ) : (
        <div className="ai-mtg-body">
          {AI_MEETING_TRANSCRIPT.map((u, i) => (
            <div key={i} className="ai-mtg-utt">
              <div className="ai-mtg-utt-h">
                <strong>{u.who}</strong>
                <span className="dim">· {u.role}</span>
                <span className="dim mono" style={{ marginLeft: 'auto', fontSize: 10.5 }}>{14*60+i*8 < 600 ? `00:${String(14*60+i*8).padStart(4,'0')}` : `14:${String(i*8).padStart(2,'0')}`}</span>
              </div>
              <div className="ai-mtg-utt-text">{u.text}</div>
            </div>
          ))}
          <div className="ai-mtg-live">
            <span className="ai-mtg-cursor" /> transcribing live…
          </div>
        </div>
      )}

      {/* Composer / call-to-action */}
      <div className="ai-meeting-foot">
        <button className="ai-pill-btn"><Icon name="users" size={12} />Invite Cents to next meeting</button>
        <button className="ai-pill-btn primary"><Icon name="check" size={12} stroke={2.4} />Create 4 tasks</button>
      </div>
    </div>
  );
}

window.AIAssistantOverlay = AIAssistantOverlay;
window.CentsMark = CentsMark;
