const { useState, useEffect, useRef, useMemo, useCallback } = React;

const ICONS = {
  chat: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>,
  compare: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><line x1="9" y1="3" x2="9" y2="21"/><line x1="15" y1="3" x2="15" y2="21"/><rect x="3" y="3" width="18" height="18" rx="2"/></svg>,
  calc: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><rect x="4" y="2" width="16" height="20" rx="2"/><line x1="8" y1="6" x2="16" y2="6"/><line x1="8" y1="14" x2="8" y2="14.01"/><line x1="12" y1="14" x2="12" y2="14.01"/><line x1="16" y1="14" x2="16" y2="14.01"/><line x1="8" y1="18" x2="8" y2="18.01"/><line x1="12" y1="18" x2="12" y2="18.01"/><line x1="16" y1="18" x2="16" y2="18.01"/></svg>,
  'user-check': <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="8.5" cy="7" r="4"/><polyline points="17 11 19 13 23 9"/></svg>,
  file: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/></svg>,
  users: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><circle cx="9" cy="7" r="4"/><path d="M3 21v-2a4 4 0 0 1 4-4h4a4 4 0 0 1 4 4v2M16 3.13a4 4 0 0 1 0 7.75M21 21v-2a4 4 0 0 0-3-3.87"/></svg>,
  pen: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M12 19l7-7 3 3-7 7-3-3z"/><path d="M18 13l-1.5-7.5L2 2l3.5 14.5L13 18l5-5z"/><path d="M2 2l7.586 7.586"/><circle cx="11" cy="11" r="2"/></svg>,
  activity: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><polyline points="22 12 18 12 15 21 9 3 6 12 2 12"/></svg>,
  refresh: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8M3 3v5h5"/></svg>,
  card: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><rect x="2" y="6" width="20" height="14" rx="2"/><line x1="2" y1="10" x2="22" y2="10"/></svg>,
  map: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/></svg>,
  refund: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><line x1="12" y1="1" x2="12" y2="23"/><path d="M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"/></svg>,
  shield: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>,
  briefcase: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><rect x="2" y="7" width="20" height="14" rx="2"/><path d="M16 21V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16"/></svg>,
  funnel: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3"/></svg>,
  wallet: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M21 12V7H5a2 2 0 0 1 0-4h14v4"/><path d="M3 5v14a2 2 0 0 0 2 2h16v-5"/><path d="M18 12a2 2 0 0 0 0 4h4v-4z"/></svg>,
  bell: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.73 21a2 2 0 0 1-3.46 0"/></svg>,
  send: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round"><path d="M5 12h14M13 6l6 6-6 6"/></svg>,
  plus: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round"><path d="M12 5v14M5 12h14"/></svg>,
  expand: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><polyline points="15 3 21 3 21 9"/><polyline points="9 21 3 21 3 15"/><line x1="21" y1="3" x2="14" y2="10"/><line x1="3" y1="21" x2="10" y2="14"/></svg>,
  x: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>,
  share: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><circle cx="18" cy="5" r="3"/><circle cx="6" cy="12" r="3"/><circle cx="18" cy="19" r="3"/><line x1="8.59" y1="13.51" x2="15.42" y2="17.49"/><line x1="15.41" y1="6.51" x2="8.59" y2="10.49"/></svg>,
  paperclip: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48"/></svg>,
  sun: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41"/></svg>,
  moon: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg>,
  qr: <svg viewBox="0 0 24 24" fill="currentColor"><path d="M3 3h7v7H3V3zm2 2v3h3V5H5zm9-2h7v7h-7V3zm2 2v3h3V5h-3zM3 14h7v7H3v-7zm2 2v3h3v-3H5zm9-2h2v2h-2v-2zm2 2h2v2h-2v-2zm-2 2h2v2h-2v-2zm2 2h2v2h-2v-2zm2-2h2v2h-2v-2zm2 2h2v2h-2v-2zm-2-4h2v2h-2v-2zm2 0h2v2h-2v-2z"/></svg>,
  menu: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><line x1="3" y1="6" x2="21" y2="6"/><line x1="3" y1="12" x2="21" y2="12"/><line x1="3" y1="18" x2="21" y2="18"/></svg>,
};

function Icon({ name, size = 16 }) {
  const svg = ICONS[name];
  if (!svg) return null;
  return React.cloneElement(svg, { width: size, height: size });
}

function TopHead({ persona, theme, onToggleTheme, onOpenMenu }) {
  return (
    <header className="tophead">
      <button className="menu-btn" onClick={onOpenMenu} aria-label="Abrir menu">
        <Icon name="menu" size={18} />
      </button>
      <a className="brand-link" href="/" title="Voltar à página mãe">
        <div className="brand-mark">b</div>
        <div className="brand-text">BKR618</div>
      </a>
      <span style={{ color: 'var(--ink-4)', fontSize: 14 }}>/</span>
      <div className="ctx-pill">
        <span className="dot"></span>
        <span>{persona.label}</span>
        <span style={{ color: 'var(--ink-4)' }}>·</span>
        <span className="meta">{persona.meta}</span>
      </div>
      <div className="spacer"></div>
      <button className="theme-toggle" onClick={onToggleTheme} aria-label="Alternar tema">
        <Icon name={theme === 'dark' ? 'moon' : 'sun'} size={13} />
        <span>{theme === 'dark' ? 'Dark' : 'Light'}</span>
      </button>
    </header>
  );
}

function Sidebar({ persona, activeFeature, onFeatureClick, onNewConv, onHistClick, open, onClose }) {
  const handleFeature = (f) => {
    onFeatureClick(f);
    if (onClose) onClose();
  };
  const handleHist = (h) => {
    if (onHistClick) onHistClick(h);
    if (onClose) onClose();
  };
  const handleNew = () => {
    onNewConv();
    if (onClose) onClose();
  };
  return (
    <aside className={'sidebar' + (open ? ' open' : '')}>
      <div className="sb-top">
        <button className="sb-newconv" onClick={handleNew}>
          <Icon name="plus" size={13} />
          <span>Nova conversa</span>
        </button>
      </div>
      <div className="sb-section">
        <div className="sb-h">Funcionalidades</div>
        {persona.features.map(f => (
          <button
            key={f.id}
            className={'sb-item' + (activeFeature === f.id ? ' active' : '')}
            onClick={() => handleFeature(f)}
          >
            <span className="sb-item-icon"><Icon name={f.icon} size={15} /></span>
            <span className="sb-item-name">{f.name}</span>
            {f.pill && <span className={'sb-item-pill' + (f.pillCls === 'warn' ? ' warn' : '')}>{f.pill}</span>}
          </button>
        ))}
      </div>
      <div className="sb-section" style={{ paddingTop: 4, paddingBottom: 4 }}>
        <div className="sb-h">Recentes</div>
      </div>
      <div className="sb-history">
        {persona.history.map((h, i) => (
          <button key={i} className="sb-hist-item" onClick={() => handleHist(h)}>
            <div className="sb-hist-t">{h.title}</div>
            <div className="sb-hist-m">{h.meta}</div>
          </button>
        ))}
      </div>
      <div className="sb-foot">
        <div className="sb-avatar" style={{ background: persona.user.color }}>{persona.user.initial}</div>
        <div className="sb-foot-text">
          <div className="sb-uname">{persona.user.name}</div>
          <div className="sb-uorg">{persona.user.org}</div>
        </div>
      </div>
    </aside>
  );
}

function Welcome({ persona, onStarterClick }) {
  const w = persona.welcome;
  return (
    <div className="welcome">
      <div className="welcome-eb">{w.eyebrow}</div>
      <h1 className="welcome-h1">{w.title}</h1>
      <p className="welcome-sub">{w.sub}</p>
      <div className="starter-grid">
        {w.starters.map((s, i) => (
          <button key={i} className="starter-card" onClick={() => onStarterClick(s.q)}>
            <span className="starter-eb">{s.eb}</span>
            <span className="starter-t">{s.t}</span>
            <span className="starter-s">{s.s}</span>
          </button>
        ))}
      </div>
      {w.trust && (
        <div className="trust-row">
          <span className="trust-i"><span className="pulse"></span><span>BrasilAPI ao vivo</span></span>
          <span className="trust-i"><span style={{width:5,height:5,borderRadius:'50%',background:'var(--ink-3)'}}></span><span>20 operadoras</span></span>
          <span className="trust-i"><span style={{width:5,height:5,borderRadius:'50%',background:'var(--ink-3)'}}></span><span>3 min · sem cadastro</span></span>
        </div>
      )}
    </div>
  );
}

function Typing() {
  return (
    <div className="typing">
      <span className="typing-dots"><span></span><span></span><span></span></span>
      <span>BKR618 está consultando…</span>
    </div>
  );
}

function Composer({ onSend, placeholder, persona }) {
  const [text, setText] = useState('');
  const ref = useRef(null);

  useEffect(() => {
    if (ref.current) ref.current.style.height = 'auto';
    if (ref.current && text) ref.current.style.height = ref.current.scrollHeight + 'px';
  }, [text]);

  const submit = () => {
    if (!text.trim()) return;
    onSend(text.trim());
    setText('');
    if (ref.current) ref.current.style.height = 'auto';
  };

  return (
    <div className="composer-wrap">
      <div className="composer">
        <div className="composer-row">
          <textarea
            ref={ref}
            value={text}
            onChange={e => setText(e.target.value)}
            onKeyDown={e => {
              if (e.key === 'Enter' && !e.shiftKey) {
                e.preventDefault();
                submit();
              }
            }}
            placeholder={placeholder}
            rows={1}
          />
          <button className="composer-send" onClick={submit} disabled={!text.trim()}>↑</button>
        </div>
        <div className="composer-tools">
          <button className="composer-tool"><Icon name="paperclip" size={11} /><span>Anexar</span></button>
          <div className="composer-spacer"></div>
          <span className="composer-hint">Enter envia · Shift+Enter quebra linha</span>
        </div>
      </div>
    </div>
  );
}

function Message({ msg, onSuggest }) {
  const role = msg.role || 'system';
  const cls = 'msg msg-' + role;
  const meta = role === 'user' ? (msg.meta || 'visitante') : (role === 'system' ? 'sistema' : (role === 'broker' ? 'corretor' : 'BKR618'));
  return (
    <div className={cls}>
      <div className="msg-meta">
        <span className="msg-meta-dot"></span>
        <span>{meta}</span>
        {msg.time && <span style={{ marginLeft: 'auto', color: 'var(--ink-4)' }}>{msg.time}</span>}
      </div>
      <div className="msg-body" dangerouslySetInnerHTML={{ __html: msg.text }} />
      {msg.suggests && (
        <div className="suggest-row">
          {msg.suggests.map((s, i) => (
            <button key={i} className="suggest-chip" onClick={() => onSuggest(s)}>{s}</button>
          ))}
        </div>
      )}
      {msg.artifact && <ArtifactRouter artifact={msg.artifact} onExpand={msg.onExpand} />}
    </div>
  );
}

function ArtifactRouter({ artifact, onExpand }) {
  if (!artifact) return null;
  const { kind } = artifact;
  let body, title, sub, icon;
  switch (kind) {
    case 'company_card':
      title = artifact.data.razao_social;
      sub = 'Empresa · Receita Federal';
      icon = '🏢';
      body = <CompanyCard data={artifact.data} onConfirm={artifact.onConfirm} onReject={artifact.onReject} />;
      break;
    case 'plan_comparison':
      title = 'Comparativo de planos';
      sub = artifact.data.lives + ' vidas · ' + (artifact.data.contracting || 'compulsório');
      icon = '⚖';
      body = <PlanComparison data={artifact.data} />;
      break;
    case 'lives_movement':
      title = 'Inclusão de beneficiários';
      sub = artifact.data.length + ' pessoas';
      icon = '👥';
      body = <LivesMovement data={artifact.data} />;
      break;
    case 'billing':
      title = 'Fatura ' + artifact.data.month;
      sub = artifact.data.policy;
      icon = '💳';
      body = <Billing data={artifact.data} />;
      break;
    case 'carteirinha':
      title = 'Sua carteirinha';
      sub = artifact.data.operator;
      icon = '🪪';
      body = <Carteirinha data={artifact.data} />;
      break;
    case 'network_search':
      title = artifact.data.specialty + ' perto de você';
      sub = artifact.data.results.length + ' resultados · ' + artifact.data.location;
      icon = '🗺';
      body = <NetworkSearch data={artifact.data} />;
      break;
    case 'sinistralidade':
      title = 'Sinistralidade · 12 meses';
      sub = artifact.data.policy;
      icon = '📈';
      body = <Sinistralidade data={artifact.data} />;
      break;
    case 'broker_portfolio':
      title = 'Sua carteira';
      sub = artifact.data.length + ' clientes PME';
      icon = '💼';
      body = <BrokerPortfolio data={artifact.data} />;
      break;
    default:
      return null;
  }
  return (
    <div className="art-card">
      <div className="art-head">
        <div className="art-icon">{icon}</div>
        <div className="art-head-t">
          <div className="art-title">{title}</div>
          <div className="art-sub">{sub}</div>
        </div>
        <div className="art-actions">
          {onExpand && (
            <button className="art-icon-btn" onClick={onExpand} title="Expandir">
              <Icon name="expand" size={14} />
            </button>
          )}
          <button className="art-icon-btn" title="Compartilhar"><Icon name="share" size={14} /></button>
        </div>
      </div>
      <div className="art-body">{body}</div>
      <div className="art-foot">
        <span>● gerado agora</span>
        <span style={{ opacity: 0.5 }}>·</span>
        <span>Inteligência BKR</span>
        <div className="af-spacer"></div>
        <button>Atualizar</button>
        <button>Exportar</button>
      </div>
    </div>
  );
}

function CompanyCard({ data, onConfirm, onReject }) {
  return (
    <div>
      <div className="company-hero">
        <div className="company-name">{data.razao_social}</div>
        {data.nome_fantasia && data.nome_fantasia !== data.razao_social && (
          <div className="company-trade">{data.nome_fantasia}</div>
        )}
        <div className="company-cnpj">{BKR.fmtCNPJ(data.cnpj)}</div>
      </div>
      <div className="company-grid">
        <div className="company-cell">
          <div className="company-cell-l">CNAE</div>
          <div className="company-cell-v small">{data.cnae_principal}</div>
        </div>
        <div className="company-cell">
          <div className="company-cell-l">Porte</div>
          <div className="company-cell-v">{data.porte}</div>
        </div>
        <div className="company-cell">
          <div className="company-cell-l">Situação</div>
          <div className="company-cell-v">{data.situacao_cadastral}</div>
        </div>
        <div className="company-cell">
          <div className="company-cell-l">UF · Município</div>
          <div className="company-cell-v">{data.uf} · {data.municipio}</div>
        </div>
        <div className="company-cell">
          <div className="company-cell-l">Abertura</div>
          <div className="company-cell-v">{data.data_abertura ? new Date(data.data_abertura).toLocaleDateString('pt-BR') : '—'}</div>
        </div>
        <div className="company-cell">
          <div className="company-cell-l">Fonte</div>
          <div className="company-cell-v small">{data.source || 'Receita Federal'}</div>
        </div>
      </div>
      {(onConfirm || onReject) && (
        <div className="confirm-row">
          {onReject && <button className="confirm-btn" onClick={onReject}>Não, é outra</button>}
          {onConfirm && <button className="confirm-btn primary" onClick={onConfirm}>É essa, segue ›</button>}
        </div>
      )}
    </div>
  );
}

function PlanComparison({ data }) {
  return (
    <div className="plans-row">
      {data.plans.map((p, i) => (
        <div key={p.id || i} className={'plan-card' + (p.recommended ? ' recommended' : '')}>
          {p.recommended && <span className="plan-rec-tag">Recomendado</span>}
          <div className="plan-op">{p.operator}</div>
          <div className="plan-name">{p.name}</div>
          <div className="plan-tier">{p.tier} · {p.accommodation}</div>
          <div className="plan-price-from">a partir de</div>
          <div className="plan-price">{BKR.fmtBRL(p.price)}</div>
          <div className="plan-price-sub">por vida / mês</div>
          <div className="plan-features">
            {(p.features || []).map((f, j) => (
              <div key={j} className="plan-feature">
                <span className="plan-feature-dot">●</span>
                <span>{f}</span>
              </div>
            ))}
          </div>
          {p.ans && <div className="plan-ans">ANS · {p.ans}</div>}
        </div>
      ))}
    </div>
  );
}

function LivesMovement({ data }) {
  return (
    <div className="lives-list">
      {data.map((l, i) => (
        <div key={i} className="life-row">
          <div className="life-pill">✓</div>
          <div>
            <div className="life-name">{l.name}</div>
            <div className="life-meta">{l.cpf || '—'} · {l.relation || 'titular'} · {l.startDate || 'maio/2026'}</div>
          </div>
          <div className={'life-tag' + (l.relation === 'dependente' ? ' dep' : '')}>{l.tag || 'titular'}</div>
        </div>
      ))}
    </div>
  );
}

function Billing({ data }) {
  return (
    <div>
      <div className="bill-hero">
        <div className="bill-amount">{BKR.fmtBRL(data.total)}</div>
        <span className={'bill-status' + (data.status === 'paid' ? ' paid' : '')}>● {data.status === 'paid' ? 'pago' : 'a vencer'}</span>
      </div>
      <div className="bill-meta">
        <span>vence {data.due}</span>
        <span>·</span>
        <span>{data.policy}</span>
      </div>
      <div className="bill-items">
        {data.items.map((it, i) => (
          <div key={i} className="bill-item">
            <span className="bill-item-l">{it.label}</span>
            <span className={'bill-item-v' + (it.amount < 0 ? ' neg' : '')}>{BKR.fmtBRL(it.amount)}</span>
          </div>
        ))}
      </div>
    </div>
  );
}

function Carteirinha({ data }) {
  return (
    <div className="carteirinha">
      <div className="cart-head">
        <div>
          <div className="cart-op">{data.operator}</div>
          <div className="cart-name">{data.name}</div>
        </div>
      </div>
      <div className="cart-num">{data.number}</div>
      <div className="cart-grid">
        <div>
          <div className="cart-cell-l">Plano</div>
          <div className="cart-cell-v">{data.plan}</div>
        </div>
        <div>
          <div className="cart-cell-l">Acomodação</div>
          <div className="cart-cell-v">{data.accommodation}</div>
        </div>
        <div>
          <div className="cart-cell-l">Validade</div>
          <div className="cart-cell-v">{data.validity}</div>
        </div>
      </div>
      <div className="cart-qr"><Icon name="qr" size={36} /></div>
    </div>
  );
}

function NetworkSearch({ data }) {
  return (
    <div className="net-list">
      {data.results.map((r, i) => (
        <div key={i} className="net-row">
          <div className="net-icon">{(r.type || 'M').slice(0, 1).toUpperCase()}</div>
          <div>
            <div className="net-name">{r.name}</div>
            <div className="net-addr">{r.addr} · {r.specialty}</div>
          </div>
          <div className="net-dist">{r.distance}</div>
        </div>
      ))}
    </div>
  );
}

function Sinistralidade({ data }) {
  const max = Math.max(...data.series.map(p => p.value));
  const min = Math.min(...data.series.map(p => p.value));
  const w = 540, h = 80, pad = 8;
  const points = data.series.map((p, i) => {
    const x = pad + (i / (data.series.length - 1)) * (w - 2 * pad);
    const y = h - pad - ((p.value - min) / (max - min || 1)) * (h - 2 * pad);
    return [x, y];
  });
  const path = 'M' + points.map(p => p[0].toFixed(1) + ',' + p[1].toFixed(1)).join(' L');
  const fillPath = path + ` L${points[points.length-1][0].toFixed(1)},${h-pad} L${pad},${h-pad} Z`;
  return (
    <div>
      <div className="kpi-hero">
        <div className="kpi-value">{data.current.toFixed(1).replace('.', ',')}%</div>
        <div className="kpi-target">teto <strong>80%</strong> · trend {data.trend}</div>
      </div>
      <svg className="spark" width="100%" viewBox={`0 0 ${w} ${h}`} preserveAspectRatio="none" style={{ height: 80 }}>
        <path d={fillPath} fill="var(--accent-soft)" />
        <path d={path} stroke="var(--accent)" strokeWidth="2" fill="none" />
      </svg>
      <div className="kpi-grid">
        <div className="kpi-cell">
          <div className="kpi-cell-l">Eventos 12m</div>
          <div className="kpi-cell-v">{data.events}</div>
        </div>
        <div className="kpi-cell">
          <div className="kpi-cell-l">Custo médio</div>
          <div className="kpi-cell-v">{BKR.fmtBRL(data.avg).replace('R$ ', '')}</div>
        </div>
        <div className="kpi-cell">
          <div className="kpi-cell-l">Top categoria</div>
          <div className="kpi-cell-v" style={{ fontSize: 13 }}>{data.topCategory}</div>
        </div>
        <div className="kpi-cell">
          <div className="kpi-cell-l">Reajuste estim.</div>
          <div className="kpi-cell-v">{data.estimatedAdj}</div>
        </div>
      </div>
    </div>
  );
}

function BrokerPortfolio({ data }) {
  return (
    <table className="tbl">
      <thead>
        <tr>
          <th>Cliente</th>
          <th>Vidas</th>
          <th>Sinistralidade</th>
          <th>Renovação</th>
          <th>Status</th>
        </tr>
      </thead>
      <tbody>
        {data.slice(0, 6).map((c, i) => (
          <tr key={i}>
            <td style={{ fontWeight: 600 }}>{c.name}</td>
            <td>{c.lives}</td>
            <td><span style={{ color: c.sinist > 80 ? 'var(--bad)' : c.sinist > 70 ? 'var(--warn)' : 'var(--good)', fontWeight: 600 }}>{c.sinist.toFixed(1)}%</span></td>
            <td>{c.renewal}</td>
            <td>
              <span style={{ fontSize: 10, padding: '2px 7px', borderRadius: 4, background: c.status === 'urgent' ? 'var(--bad-soft)' : c.status === 'warn' ? 'var(--warn-soft)' : 'var(--good-soft)', color: c.status === 'urgent' ? 'var(--bad)' : c.status === 'warn' ? 'var(--warn)' : 'var(--good)', fontFamily: 'var(--mono)', fontWeight: 600, letterSpacing: '0.06em', textTransform: 'uppercase' }}>
                {c.status === 'urgent' ? '● urgente' : c.status === 'warn' ? '● atenção' : '● ok'}
              </span>
            </td>
          </tr>
        ))}
      </tbody>
    </table>
  );
}

const SCRIPTS = {
  comprador: {
    starterMatch: (q) => {
      if (/cota[r]?.*empresa/i.test(q) || /pra minha empresa/i.test(q)) return 'cnpj';
      if (/comparar.*plano/i.test(q) || /cart[ãa]o atual/i.test(q)) return 'compare';
      if (/op[çc][ãa]o.*vidas/i.test(q) || /18 vidas/i.test(q)) return 'simulate';
      if (/falar.*corretor|humano/i.test(q)) return 'human';
      return 'cnpj';
    },
    runners: {
      cnpj: async (api) => {
        api.add({ role: 'assistant', text: 'Boa, vamos cotar para sua empresa. Manda o CNPJ que eu busco na Receita Federal.', suggests: ['10.987.654/0001-21', '47.960.950/0001-21', '00.776.574/0001-56'] });
      },
      compare: async (api) => {
        api.add({ role: 'assistant', text: 'Beleza. Manda foto do cartão atual ou diz qual operadora e plano você tem hoje.', suggests: ['Bradesco Top Nacional', 'Amil 400 QC', 'Sulamerica Especial'] });
      },
      simulate: async (api) => {
        await api.typing(800);
        const plans = [
          { id: 'p1', operator: 'Bradesco', name: 'Top Nacional Flex Plus', tier: 'Executivo', accommodation: 'APTO', price: 825.40, features: ['Albert Einstein', 'Sírio-Libanês', 'Cobertura Nacional'], ans: '472.512/15-7' },
          { id: 'p2', operator: 'Amil', name: 'One Health 400', tier: 'Executivo', accommodation: 'APTO', price: 798.12, recommended: true, features: ['HCor', 'Albert Einstein', 'Reembolso 100%'], ans: '438.999/19-3' },
          { id: 'p3', operator: 'SulAmerica', name: 'Especial 400 QC', tier: 'Executivo', accommodation: 'APTO', price: 851.60, features: ['Hospital Alemão Oswaldo Cruz', 'Vila Nova Star'], ans: '443.224/16-4' },
        ];
        api.add({
          role: 'assistant',
          text: 'Pronto. <strong>3 opções pra 18 vidas em São Paulo</strong>, executivo, apartamento. Calculadas com base na sua faixa etária estimada.',
          artifact: { kind: 'plan_comparison', data: { plans, lives: 18, contracting: 'compulsório' } },
        });
        api.add({ role: 'assistant', text: 'Quer detalhar algum, comparar com plano atual ou já marcar com nosso corretor?', suggests: ['Detalhar Amil 400', 'Comparar com plano atual', 'Falar com corretor agora'] });
      },
      human: async (api) => {
        await api.typing(500);
        api.add({ role: 'system', text: 'Eduardo Almeida, seu corretor BKR618, foi notificado. Ele te chama em até 5 minutos.' });
        api.add({ role: 'broker', text: 'Olá! Sou o Eduardo. Vi sua conversa aqui. Posso te ligar agora ou prefere continuar por escrito?', meta: 'Eduardo · corretor' });
      },
      cnpj_lookup: async (api, cnpj) => {
        await api.typing(400);
        api.add({ role: 'assistant', text: 'Tô consultando a Receita…' });
        const data = await BKR.enrichCNPJ(cnpj);
        if (!data || data._error) {
          api.add({ role: 'assistant', text: 'Não achei esse CNPJ na Receita. Confere o número e me manda de novo?' });
          return;
        }
        api.add({
          role: 'assistant',
          text: 'Achei. É essa a empresa?',
          artifact: {
            kind: 'company_card',
            data,
            onConfirm: () => api.runScript('after_company', data),
            onReject: () => api.add({ role: 'assistant', text: 'Sem problema. Manda o CNPJ correto.' }),
          },
        });
      },
      after_company: async (api, company) => {
        await api.typing(600);
        api.add({ role: 'assistant', text: `Show, ${company.razao_social}. Agora me diz: <strong>quantas vidas</strong> entram no plano? Pode ser estimativa.`, suggests: ['18 vidas', '30 vidas', '50 vidas'] });
      },
      lives_received: async (api, lives) => {
        await api.typing(900);
        const plans = [
          { id: 'p1', operator: 'Bradesco', name: 'Top Nacional Flex Plus', tier: 'Executivo', accommodation: 'APTO', price: 825.40, features: ['Albert Einstein', 'Sírio-Libanês', 'Cobertura Nacional'], ans: '472.512/15-7' },
          { id: 'p2', operator: 'Amil', name: 'One Health 400', tier: 'Executivo', accommodation: 'APTO', price: 798.12, recommended: true, features: ['HCor', 'Albert Einstein', 'Reembolso 100%'], ans: '438.999/19-3' },
          { id: 'p3', operator: 'SulAmerica', name: 'Especial 400 QC', tier: 'Executivo', accommodation: 'APTO', price: 851.60, features: ['Hospital Alemão Oswaldo Cruz', 'Vila Nova Star'], ans: '443.224/16-4' },
        ];
        api.add({
          role: 'assistant',
          text: `Beleza, <strong>${lives} vidas</strong>. Calculei <strong>3 melhores opções</strong> com base no seu CNAE e localização.`,
          artifact: { kind: 'plan_comparison', data: { plans, lives, contracting: 'compulsório' } },
        });
        api.add({ role: 'assistant', text: 'Quer prosseguir com alguma dessas? Em 1 minuto eu mando proposta formal pro seu email.', suggests: ['Prosseguir com Amil 400', 'Comparar mais opções', 'Falar com corretor'] });
      },
    },
  },

  onboarding: {
    starterMatch: (q) => {
      if (/dados.*empresa|confirmar.*dados/i.test(q)) return 'company';
      if (/contrato social|enviar.*documento/i.test(q)) return 'docs';
      if (/funcionari|18 vidas|adicionar.*vidas/i.test(q)) return 'lives';
      if (/assinatura|clicksign/i.test(q)) return 'sign';
      return 'company';
    },
    runners: {
      company: async (api) => {
        await api.typing(700);
        const data = { razao_social: 'Vega Tecnologia LTDA', nome_fantasia: 'Vega Tec', cnpj: '47960950000121', cnae_principal: '6201-5/01 · Desenvolvimento de programas de computador sob encomenda', porte: 'DEMAIS', situacao_cadastral: 'ATIVA', uf: 'SP', municipio: 'SAO PAULO', data_abertura: '2018-03-12', source: 'BrasilAPI / Receita Federal' };
        api.add({ role: 'assistant', text: 'Confere os dados que peguei na Receita:', artifact: { kind: 'company_card', data } });
        api.add({ role: 'assistant', text: 'Tudo certo? Próximo passo: subir Contrato Social e ata de eleição dos sócios.', suggests: ['Tudo certo', 'Corrigir endereço', 'Pular pra documentos'] });
      },
      docs: async (api) => {
        await api.typing(800);
        api.add({ role: 'assistant', text: 'Manda foto ou PDF do <strong>Contrato Social</strong>. Tenho Vision AI: extraio razão social, sócios, capital, endereço — tudo automático.' });
        api.add({ role: 'assistant', text: 'Vou precisar também de: comprovante de endereço da empresa, RG dos sócios e ata de eleição (se SA).', suggests: ['Subir Contrato Social', 'O que é ata de eleição?', 'Posso enviar depois?'] });
      },
      lives: async (api) => {
        await api.typing(700);
        const lives = [
          { name: 'Júnior Freire', cpf: '123.***.***-45', relation: 'titular', tag: 'sócio', startDate: 'jun/2026' },
          { name: 'Marina Vega', cpf: '987.***.***-21', relation: 'titular', tag: 'titular', startDate: 'jun/2026' },
          { name: 'Pedro Almeida', cpf: '456.***.***-12', relation: 'titular', tag: 'titular', startDate: 'jun/2026' },
          { name: 'Beatriz Almeida', cpf: '654.***.***-87', relation: 'dependente', tag: 'cônjuge', startDate: 'jun/2026' },
        ];
        api.add({ role: 'assistant', text: 'Carregue lista de funcionários (CSV ou planilha). Posso aceitar formato eSocial direto. Aqui o que já tem:', artifact: { kind: 'lives_movement', data: lives } });
        api.add({ role: 'assistant', text: 'Faltam <strong>14 vidas</strong> para chegar nas 18 prometidas. Quer enviar planilha?', suggests: ['Enviar planilha', 'Modelo eSocial', 'Adicionar 1 a 1'] });
      },
      sign: async (api) => {
        await api.typing(600);
        api.add({ role: 'assistant', text: '<strong>Status assinatura:</strong> Clicksign aberto há 2h, faltam <strong>2 sócios</strong> assinarem. Vou cutucar?' });
        api.add({ role: 'assistant', text: 'Quando todos assinarem, a apólice vira ativa imediatamente. Vou mandar lembrete agora.', suggests: ['Mandar lembrete', 'Status detalhado', 'Mudar assinante'] });
      },
    },
  },

  cliente: {
    starterMatch: (q) => {
      if (/incluir|nov[oa]s? colaborador|inclusão/i.test(q)) return 'include';
      if (/fatura|abril|financeiro/i.test(q)) return 'bill';
      if (/sinistralidade|análise/i.test(q)) return 'sinist';
      if (/renovação|renovar|cotar|2026/i.test(q)) return 'renew';
      if (/vidas|mostre.*vidas/i.test(q)) return 'lives';
      return 'include';
    },
    runners: {
      include: async (api) => {
        await api.typing(700);
        const lives = [
          { name: 'Beatriz Carvalho', cpf: '111.***.***-22', relation: 'titular', tag: 'titular', startDate: 'maio/2026' },
          { name: 'Marcos Oliveira', cpf: '333.***.***-44', relation: 'titular', tag: 'titular', startDate: 'maio/2026' },
          { name: 'Helena Souza', cpf: '555.***.***-66', relation: 'dependente', tag: 'filha', startDate: 'maio/2026' },
        ];
        api.add({ role: 'assistant', text: 'Beleza, Marina. <strong>3 inclusões</strong> com início em <strong>01/maio/2026</strong>. Confere:', artifact: { kind: 'lives_movement', data: lives } });
        api.add({ role: 'assistant', text: 'Vou abrir movimentação no Bradesco e mandar SLA de 3 dias úteis. Algum vai precisar de coparticipação especial?', suggests: ['Confirmar e enviar', 'Adicionar mais', 'Cancelar'] });
      },
      bill: async (api) => {
        await api.typing(600);
        const bill = {
          month: 'Abril/2026',
          policy: 'Apólice 47.823.156/0001-92',
          due: '10/05/2026',
          status: 'pending',
          total: 71845.50,
          items: [
            { label: '18 vidas titulares', amount: 64580.40 },
            { label: '6 dependentes', amount: 9072.00 },
            { label: 'Reajuste contratual (jan/26)', amount: 2193.10 },
            { label: 'Crédito coparticipação março', amount: -4000.00 },
          ],
        };
        api.add({ role: 'assistant', text: 'Aqui sua fatura de abril:', artifact: { kind: 'billing', data: bill } });
        api.add({ role: 'assistant', text: 'Vence em 10/05. Quer 2ª via, boleto PIX ou agendar débito automático?', suggests: ['Boleto PIX', 'Débito automático', 'Por que reajuste?'] });
      },
      sinist: async (api) => {
        await api.typing(800);
        const data = {
          policy: 'Bradesco · 18 vidas · 12 meses',
          current: 71.4,
          trend: '↘ –4,2%',
          series: [{ value: 76.2 }, { value: 79.8 }, { value: 81.4 }, { value: 78.6 }, { value: 75.1 }, { value: 72.9 }, { value: 71.8 }, { value: 70.4 }, { value: 69.2 }, { value: 71.0 }, { value: 70.8 }, { value: 71.4 }],
          events: 142,
          avg: 685.40,
          topCategory: 'Consultas eletivas',
          estimatedAdj: '8,2%',
        };
        api.add({ role: 'assistant', text: 'Sua sinistralidade está <strong>controlada</strong>. Abaixo do teto contratual e em queda nos últimos 6 meses.', artifact: { kind: 'sinistralidade', data } });
        api.add({ role: 'assistant', text: 'Reajuste estimado pra renovação 2026: <strong>8,2%</strong>. Quer simular cenários ou comparar com VCMH do setor?', suggests: ['Simular cenários', 'VCMH do setor', 'Negociar com Bradesco'] });
      },
      renew: async (api) => {
        await api.typing(900);
        const plans = [
          { id: 'r1', operator: 'Bradesco', name: 'Top Nacional Flex Plus (atual)', tier: 'Executivo', accommodation: 'APTO', price: 871.20, features: ['Renovação · reajuste 8,2%', 'Mantém rede atual', 'Sem carência'], ans: '472.512/15-7' },
          { id: 'r2', operator: 'Amil', name: 'One Health 400', tier: 'Executivo', accommodation: 'APTO', price: 798.12, recommended: true, features: ['Equiv. de rede', '–8% vs atual', 'Aproveitamento de carência'], ans: '438.999/19-3' },
          { id: 'r3', operator: 'SulAmerica', name: 'Especial 400 QC', tier: 'Executivo', accommodation: 'APTO', price: 851.60, features: ['Rede premium', 'Reembolso 100%'], ans: '443.224/16-4' },
        ];
        api.add({ role: 'assistant', text: '<strong>Renovação 06/2026</strong> · 90 dias. Comparei seu plano atual com 2 alternativas equivalentes:', artifact: { kind: 'plan_comparison', data: { plans, lives: 18, contracting: 'renovação' } } });
        api.add({ role: 'assistant', text: 'Amil sai 8% mais barato com rede equivalente e aproveitamento de carência. Quer pedir proposta formal?', suggests: ['Pedir proposta Amil', 'Negociar com Bradesco', 'Ver detalhes da rede'] });
      },
      lives: async (api) => {
        await api.typing(500);
        const lives = [
          { name: 'Júnior Freire', cpf: '123.***.***-45', relation: 'titular', tag: 'sócio', startDate: '03/2018' },
          { name: 'Marina Vega', cpf: '987.***.***-21', relation: 'titular', tag: 'RH', startDate: '06/2019' },
          { name: 'Pedro Almeida', cpf: '456.***.***-12', relation: 'titular', tag: 'titular', startDate: '08/2020' },
          { name: 'Beatriz Almeida', cpf: '654.***.***-87', relation: 'dependente', tag: 'cônjuge', startDate: '08/2020' },
        ];
        api.add({ role: 'assistant', text: '<strong>18 vidas ativas</strong>. Aqui as primeiras 4 (titular + dependente):', artifact: { kind: 'lives_movement', data: lives } });
        api.add({ role: 'assistant', text: 'Quer ver todas, filtrar por departamento ou exportar pra eSocial?', suggests: ['Ver todas as 18', 'Filtrar TI', 'Exportar eSocial'] });
      },
    },
  },

  colaborador: {
    starterMatch: (q) => {
      if (/carteirinha/i.test(q)) return 'card';
      if (/cardiologista|m[ée]dico|rede.*credenciada|perto/i.test(q)) return 'net';
      if (/reembolso/i.test(q)) return 'refund';
      if (/cobertura|funciona.*plano/i.test(q)) return 'cover';
      return 'card';
    },
    runners: {
      card: async (api) => {
        await api.typing(400);
        const data = {
          operator: 'BRADESCO SAÚDE',
          name: 'PEDRO ALMEIDA',
          number: '883.0024.4567.8901',
          plan: 'TOP NAC FLEX PLUS',
          accommodation: 'APTO',
          validity: '12/2026',
        };
        api.add({ role: 'assistant', text: 'Sua carteirinha digital. QR válido pra atendimento.', artifact: { kind: 'carteirinha', data } });
        api.add({ role: 'assistant', text: 'Quer compartilhar por WhatsApp, salvar no Apple Wallet ou pedir 2ª via física?', suggests: ['WhatsApp', 'Apple Wallet', '2ª via física'] });
      },
      net: async (api) => {
        await api.typing(700);
        const data = {
          specialty: 'Cardiologistas',
          location: 'Pinheiros · 2,5 km',
          results: [
            { name: 'Dr. Ricardo Mendes', addr: 'R. Henrique Schaumann, 270', specialty: 'Cardiologia · CRM 12345', distance: '0,8 km', type: 'M' },
            { name: 'Hospital Sírio-Libanês', addr: 'R. Adma Jafet, 91', specialty: 'Cardiologia · 24h', distance: '1,4 km', type: 'H' },
            { name: 'Clínica CardioCare Pinheiros', addr: 'R. dos Pinheiros, 1.105', specialty: 'Equipe multidisciplinar', distance: '1,9 km', type: 'C' },
            { name: 'Dr. Ana Paula Ferreira', addr: 'Av. Brig. Faria Lima, 1.811', specialty: 'Cardiologia · CRM 67890', distance: '2,3 km', type: 'M' },
          ],
        };
        api.add({ role: 'assistant', text: 'Achei <strong>4 cardiologistas</strong> na sua rede, perto de Pinheiros:', artifact: { kind: 'network_search', data } });
        api.add({ role: 'assistant', text: 'Quer agendar com algum? Posso ligar ou abrir WhatsApp do consultório.', suggests: ['Agendar Dr. Ricardo', 'Filtrar por horário', 'Ver Sírio-Libanês'] });
      },
      refund: async (api) => {
        await api.typing(800);
        api.add({ role: 'assistant', text: 'Manda foto da nota da consulta. Vou extrair com Vision AI: valor, CRM, data, especialidade.' });
        api.add({ role: 'assistant', text: 'Reembolso de consulta eletiva: até <strong>R$ 320</strong>. Sua nota é de R$ 380, sai R$ 320 em 5 dias úteis.', suggests: ['Subir foto da nota', 'Por que só R$ 320?', 'Tabela de reembolso'] });
      },
      cover: async (api) => {
        await api.typing(500);
        api.add({ role: 'assistant', text: 'Seu plano: <strong>Bradesco Top Nacional Flex Plus · APTO</strong>.<br/>· Cobertura nacional (qualquer estado)<br/>· Sem carência (já cumprida)<br/>· Reembolso até R$ 320/consulta · 70% exames<br/>· Coparticipação: R$ 35/consulta eletiva' });
        api.add({ role: 'assistant', text: 'Quer detalhar urgência, internação, exames específicos ou parto?', suggests: ['Internação', 'Exames complexos', 'Parto e maternidade'] });
      },
    },
  },

  corretor: {
    starterMatch: (q) => {
      if (/carteira|18 clientes|visão geral/i.test(q)) return 'portfolio';
      if (/aurora|urgente|15 dias/i.test(q)) return 'aurora';
      if (/pipeline|leads|semana/i.test(q)) return 'pipe';
      if (/vega|marina/i.test(q)) return 'vega';
      if (/comissões|comissão/i.test(q)) return 'comm';
      if (/alertas/i.test(q)) return 'alerts';
      return 'portfolio';
    },
    runners: {
      portfolio: async (api) => {
        await api.typing(700);
        const data = [
          { name: 'Aurora Logística', lives: 47, sinist: 87.4, renewal: '15 dias', status: 'urgent' },
          { name: 'Vega Tecnologia', lives: 18, sinist: 71.4, renewal: '90 dias', status: 'ok' },
          { name: 'Mineração Brasil', lives: 412, sinist: 76.8, renewal: '45 dias', status: 'warn' },
          { name: 'Indústria Bahia', lives: 89, sinist: 68.2, renewal: '120 dias', status: 'ok' },
          { name: 'Comércio SP', lives: 32, sinist: 73.5, renewal: '60 dias', status: 'warn' },
          { name: 'Hospital Vida', lives: 156, sinist: 79.1, renewal: '30 dias', status: 'warn' },
        ];
        api.add({ role: 'assistant', text: '<strong>18 clientes ativos · 3.124 vidas</strong>. Ordenados por urgência:', artifact: { kind: 'broker_portfolio', data } });
        api.add({ role: 'assistant', text: '<strong>Aurora Logística</strong> está vermelha: sinistralidade 87% e 15 dias pra renovar. Quer atacar ela primeiro?', suggests: ['Status Aurora', 'Ver Mineração Brasil', 'Pipeline da semana'] });
      },
      aurora: async (api) => {
        await api.typing(700);
        const data = {
          policy: 'Aurora Logística · Amil · 47 vidas',
          current: 87.4,
          trend: '↑ +6,1%',
          series: [{ value: 70.2 }, { value: 72.8 }, { value: 75.4 }, { value: 78.6 }, { value: 80.1 }, { value: 81.9 }, { value: 83.4 }, { value: 84.8 }, { value: 85.6 }, { value: 86.2 }, { value: 86.9 }, { value: 87.4 }],
          events: 312,
          avg: 1240.80,
          topCategory: 'Internações',
          estimatedAdj: '21,4%',
        };
        api.add({ role: 'assistant', text: '<strong>Aurora · sinistralidade crítica</strong>. Subiu 17 pontos em 12 meses. Reajuste estimado <strong>21,4%</strong>:', artifact: { kind: 'sinistralidade', data } });
        api.add({ role: 'assistant', text: 'Recomendo: (1) cotar com 3 alternativas mais baratas, (2) pedir relatório de top utilizadores ao Amil, (3) propor copay no plano. Por onde?', suggests: ['Cotar 3 alternativas', 'Top utilizadores', 'Propor copay'] });
      },
      pipe: async (api) => {
        await api.typing(600);
        api.add({ role: 'assistant', text: '<strong>Pipeline da semana · 6 leads:</strong><br/>· <strong>FastTech</strong> (24 vidas) · proposta enviada · 80% probabilidade<br/>· <strong>Engenharia X</strong> (12 vidas) · 2ª reunião · 60%<br/>· <strong>Restaurante BR</strong> (8 vidas) · cotação · 40%<br/>· <strong>Estúdio Verde</strong> (15 vidas) · proposta enviada · 70%<br/>· 2 leads frios em qualificação', suggests: ['Ver FastTech', 'Mandar follow-up', 'Adicionar lead'] });
      },
      vega: async (api) => {
        await api.typing(500);
        api.add({ role: 'assistant', text: '<strong>Vega Tecnologia</strong> · 18 vidas · sinist. 71,4% · renovação 90d.<br/>Marina (RH) abriu hoje pedido de inclusão de 3 vidas: <strong>Beatriz, Marcos, Helena</strong>. SLA 3 dias.<br/>Renovação: 8,2% estimado · oportunidade de migrar pra Amil (–8%).' });
        api.add({ role: 'assistant', text: 'Quer entrar na thread da Marina, ver inclusões pendentes ou cotar renovação?', suggests: ['Entrar na thread Marina', 'Cotar renovação', 'Ver inclusões'] });
      },
      comm: async (api) => {
        await api.typing(400);
        api.add({ role: 'assistant', text: '<strong>Comissões previstas abril:</strong><br/>· Inicial (300%): R$ 12.450 (FastTech, Estúdio Verde)<br/>· Recorrente (2%): R$ 18.230 (carteira ativa)<br/>· Total: <strong>R$ 30.680</strong> · pago dia 5/05', suggests: ['Detalhar por cliente', 'Histórico 6 meses', 'Projeção renovações'] });
      },
      alerts: async (api) => {
        await api.typing(500);
        api.add({ role: 'assistant', text: '<strong>4 alertas pendentes:</strong><br/>🔴 <strong>Aurora · 15 dias renovação · sinist. 87%</strong> (urgente)<br/>🟡 <strong>Hospital Vida · 30 dias renovação · sinist. 79%</strong><br/>🟡 <strong>Mineração Brasil · 45 dias · vidas crescendo +18%</strong><br/>🟡 <strong>FastTech · proposta enviada há 5 dias · sem resposta</strong>', suggests: ['Ação Aurora', 'Follow-up FastTech', 'Ver todos'] });
      },
    },
  },
};

function App({ persona }) {
  const [theme, setTheme] = useState(() => BKR.initTheme());
  const [activeFeature, setActiveFeature] = useState('chat');
  const [messages, setMessages] = useState([]);
  const [typing, setTyping] = useState(false);
  const [pendingCNPJ, setPendingCNPJ] = useState(null);
  const [pendingLives, setPendingLives] = useState(false);
  const [companyConfirmed, setCompanyConfirmed] = useState(null);
  const [menuOpen, setMenuOpen] = useState(false);
  const threadRef = useRef(null);
  const script = SCRIPTS[persona.id];

  useEffect(() => {
    const onKey = (e) => { if (e.key === 'Escape') setMenuOpen(false); };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, []);

  const scrollToBottom = useCallback(() => {
    setTimeout(() => {
      if (threadRef.current) threadRef.current.scrollTop = threadRef.current.scrollHeight;
    }, 50);
  }, []);

  const api = useMemo(() => ({
    add: (msg) => {
      setMessages(prev => [...prev, { ...msg, id: prev.length + Math.random() }]);
      scrollToBottom();
    },
    typing: async (ms = 700) => {
      setTyping(true);
      await new Promise(r => setTimeout(r, ms));
      setTyping(false);
    },
    runScript: async (key, ...args) => {
      if (script && script.runners[key]) {
        await script.runners[key](api, ...args);
      }
    },
  }), [script, scrollToBottom]);

  const handleSend = useCallback(async (text) => {
    api.add({ role: 'user', text, meta: persona.user.name });
    setTyping(true);
    await new Promise(r => setTimeout(r, 600));
    setTyping(false);

    if (persona.id === 'comprador') {
      const cnpjMatch = text.match(/\d{2}\.?\d{3}\.?\d{3}\/?\d{4}-?\d{2}/);
      if (cnpjMatch) {
        await script.runners.cnpj_lookup(api, cnpjMatch[0]);
        return;
      }
      const livesMatch = text.match(/(\d+)\s*vidas?/i);
      if (livesMatch && companyConfirmed) {
        await script.runners.lives_received(api, parseInt(livesMatch[1]));
        return;
      }
    }

    if (script) {
      const key = script.starterMatch(text);
      if (script.runners[key]) {
        await script.runners[key](api);
      } else {
        api.add({ role: 'assistant', text: 'Entendi. Em produção, eu acionaria o agente real do BKR618 aqui. Por ora, tenta um dos exemplos pra ver a simulação rodar.' });
      }
    }
  }, [api, persona, script, companyConfirmed]);

  const handleStarter = (q) => handleSend(q);

  const handleFeature = (f) => {
    setActiveFeature(f.id);
    if (f.prompt) handleSend(f.prompt);
  };

  const handleNewConv = () => {
    setMessages([]);
    setActiveFeature('chat');
    setCompanyConfirmed(null);
  };

  const handleHistClick = (h) => {
    handleSend('Recupera a conversa "' + h.title + '"');
  };

  const handleToggleTheme = () => {
    setTheme(BKR.toggleTheme());
  };

  useEffect(() => {
    const origAdd = api.add;
    if (persona.id === 'comprador') {
      const interceptedRunner = SCRIPTS.comprador.runners.cnpj_lookup;
      SCRIPTS.comprador.runners.cnpj_lookup = async (apiArg, cnpj) => {
        await apiArg.typing(400);
        apiArg.add({ role: 'assistant', text: 'Tô consultando a Receita Federal pelo BrasilAPI…' });
        const data = await BKR.enrichCNPJ(cnpj);
        if (!data || data._error) {
          apiArg.add({ role: 'assistant', text: 'Não achei esse CNPJ na Receita. Confere o número e me manda de novo?' });
          return;
        }
        apiArg.add({
          role: 'assistant',
          text: 'Achei. É essa a empresa?',
          artifact: {
            kind: 'company_card',
            data,
            onConfirm: async () => {
              setCompanyConfirmed(data);
              await SCRIPTS.comprador.runners.after_company(apiArg, data);
            },
            onReject: () => apiArg.add({ role: 'assistant', text: 'Sem problema. Manda o CNPJ correto.' }),
          },
        });
      };
    }
  }, [persona.id, api]);

  return (
    <div className="shell">
      <TopHead persona={persona} theme={theme} onToggleTheme={handleToggleTheme} onOpenMenu={() => setMenuOpen(true)} />
      <div className="shell-grid">
        <div className={'sb-overlay' + (menuOpen ? ' open' : '')} onClick={() => setMenuOpen(false)}></div>
        <Sidebar
          persona={persona}
          activeFeature={activeFeature}
          onFeatureClick={handleFeature}
          onNewConv={handleNewConv}
          onHistClick={handleHistClick}
          open={menuOpen}
          onClose={() => setMenuOpen(false)}
        />
        <main className="thread-col">
          <div className="thread-top">
            <div className="tt-org">{persona.org}</div>
            <span className="tt-divider">/</span>
            <div className="tt-sub">{persona.sub}</div>
            {persona.tags.map((t, i) => (
              <span key={i} className={t.cls || 'tt-tag'}>● {t.label}</span>
            ))}
            <div className="tt-spacer"></div>
            <div className="ai-pill">
              <span className="ai-pill-dot"></span>
              <span>{persona.aiBar.text}</span>
              <span className="ai-pill-muted">{persona.aiBar.muted}</span>
            </div>
          </div>
          <div className="thread" ref={threadRef}>
            <div className="thread-inner">
              {messages.length === 0 && <Welcome persona={persona} onStarterClick={handleStarter} />}
              {messages.map(m => (
                <Message key={m.id} msg={m} onSuggest={handleStarter} />
              ))}
              {typing && <Typing />}
            </div>
          </div>
          <Composer onSend={handleSend} placeholder={persona.placeholder} persona={persona} />
        </main>
      </div>
    </div>
  );
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App persona={BKR.PERSONAS[window.PERSONA]} />);
