// Command Center — versão React Babel-inline pra rodar dentro do index.html legacy.
// Origem: handoff Claude Design (marketing/Nexus-2.zip), 4 arquivos cc-shell+overview+clientes+app combinados.
// CSS dependente: ./cc-styles.css (mesma pasta).
// Mock data: window.CC_DATA via cc-data.js.
// API pública: window.mountCommandCenter(el) — monta o app dentro de el.

(function () {
  const { useState, useEffect, useRef, useMemo, useCallback } = React;
  // Aliases pra preservar nomes do código original sem conflito de redeclaração:
  const oUseState = useState, oUseMemo = useMemo;
  const cUseState = useState, cUseMemo = useMemo, cUseRef = useRef;
  const aUseState = useState, aUseEffect = useEffect, aUseMemo = useMemo;

// Componentes shared do Command Center: Icons, Sidebar, Topbar, Header, Ticker, useCountUp

const CCIcon = ({ name, size = 16, className = '' }) => {
  const s = size;
  const stroke = 'currentColor';
  const sw = 1.6;
  const props = { width: s, height: s, viewBox: '0 0 24 24', fill: 'none', stroke, strokeWidth: sw, strokeLinecap: 'round', strokeLinejoin: 'round', className };
  switch (name) {
    case 'overview':   return <svg {...props}><rect x="3" y="3" width="7" height="9"/><rect x="14" y="3" width="7" height="5"/><rect x="14" y="12" width="7" height="9"/><rect x="3" y="16" width="7" height="5"/></svg>;
    case 'clients':    return <svg {...props}><circle cx="9" cy="7" r="4"/><path d="M3 21v-2a4 4 0 0 1 4-4h4a4 4 0 0 1 4 4v2"/><circle cx="17" cy="7" r="3"/><path d="M21 21v-1a3 3 0 0 0-3-3"/></svg>;
    case 'business':   return <svg {...props}><path d="M3 3v18h18"/><path d="M7 14l4-4 4 4 5-7"/></svg>;
    case 'reps':       return <svg {...props}><circle cx="12" cy="8" r="4"/><path d="M5 21a7 7 0 0 1 14 0"/><path d="M12 12v5"/></svg>;
    case 'market':     return <svg {...props}><circle cx="12" cy="12" r="9"/><path d="M3 12h18"/><path d="M12 3a14 14 0 0 1 0 18a14 14 0 0 1 0-18"/></svg>;
    case 'arrow-r':    return <svg {...props}><path d="M5 12h14M13 6l6 6-6 6"/></svg>;
    case 'alert':      return <svg {...props}><path d="M12 9v4"/><circle cx="12" cy="17" r=".5" fill={stroke}/><path d="M10.3 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/></svg>;
    case 'trending-up':return <svg {...props}><path d="M22 7l-8.5 8.5-5-5L2 17"/><path d="M16 7h6v6"/></svg>;
    case 'trending-down':return <svg {...props}><path d="M22 17l-8.5-8.5-5 5L2 7"/><path d="M16 17h6v-6"/></svg>;
    case 'flat':       return <svg {...props}><path d="M3 12h18"/></svg>;
    case 'sparkles':   return <svg {...props}><path d="M12 3v4M12 17v4M5 12H1M23 12h-4M6 6l3 3M15 15l3 3M6 18l3-3M15 9l3-3"/></svg>;
    case 'compass':    return <svg {...props}><circle cx="12" cy="12" r="9"/><path d="M16.24 7.76l-2.12 6.36-6.36 2.12 2.12-6.36z"/></svg>;
    case 'pin':        return <svg {...props}><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>;
    case 'newspaper':  return <svg {...props}><path d="M4 22h16a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2H8a2 2 0 0 0-2 2v16a2 2 0 0 1-2 2zm0 0a2 2 0 0 1-2-2v-9c0-1.1.9-2 2-2h2"/><path d="M18 14h-8M15 18h-5M10 6h8v4h-8z"/></svg>;
    case 'plus':       return <svg {...props}><path d="M12 5v14M5 12h14"/></svg>;
    case 'minus':      return <svg {...props}><path d="M5 12h14"/></svg>;
    case 'reset':      return <svg {...props}><path d="M21 12a9 9 0 1 1-3-6.7"/><path d="M21 4v5h-5"/></svg>;
    case 'filter':     return <svg {...props}><path d="M3 4h18M6 12h12M10 20h4"/></svg>;
    case 'search':     return <svg {...props}><circle cx="11" cy="11" r="7"/><path d="M21 21l-4.3-4.3"/></svg>;
    case 'message':    return <svg {...props}><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>;
    case 'check':      return <svg {...props}><path d="M5 12l5 5L20 7"/></svg>;
    case 'x':          return <svg {...props}><path d="M18 6L6 18M6 6l12 12"/></svg>;
    case 'sliders':    return <svg {...props}><path d="M4 21v-7M4 10V3M12 21v-9M12 8V3M20 21v-5M20 12V3M1 14h6M9 8h6M17 16h6"/></svg>;
    case 'zap':        return <svg {...props}><path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"/></svg>;
    case 'bell':       return <svg {...props}><path d="M18 8a6 6 0 1 0-12 0c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.7 21a2 2 0 0 1-3.4 0"/></svg>;
    case 'home':       return <svg {...props}><path d="M3 12l9-9 9 9M5 10v10h14V10"/></svg>;
    case 'globe':      return <svg {...props}><circle cx="12" cy="12" r="9"/><path d="M3 12h18M12 3a14 14 0 0 1 0 18a14 14 0 0 1 0-18"/></svg>;
    case 'eye':        return <svg {...props}><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg>;
    case 'layers':     return <svg {...props}><path d="M12 2L2 7l10 5 10-5-10-5z"/><path d="M2 17l10 5 10-5M2 12l10 5 10-5"/></svg>;
    case 'menu':       return <svg {...props}><path d="M3 6h18M3 12h18M3 18h18"/></svg>;
    case 'building':   return <svg {...props}><rect x="4" y="2" width="16" height="20"/><path d="M9 22v-4h6v4M8 6h.01M16 6h.01M8 10h.01M16 10h.01M8 14h.01M16 14h.01"/></svg>;
    default: return null;
  }
};

// ============ Count-up hook ============
function useCountUp(target, opts = {}) {
  const { duration = 800, decimals = 0 } = opts;
  const [val, setVal] = useState(0);
  const startRef = useRef(null);
  useEffect(() => {
    let raf;
    const start = performance.now();
    startRef.current = start;
    const step = (now) => {
      const elapsed = now - start;
      const t = Math.min(1, elapsed / duration);
      const ease = 1 - Math.pow(1 - t, 3);
      setVal(target * ease);
      if (t < 1) raf = requestAnimationFrame(step);
      else setVal(target);
    };
    raf = requestAnimationFrame(step);
    return () => cancelAnimationFrame(raf);
  }, [target, duration]);
  return decimals > 0 ? val.toFixed(decimals) : Math.round(val);
}

// ============ Sidebar ============
const CCHeader = ({ tab, onTab, ticker }) => {
  const [now, setNow] = useState(new Date());
  useEffect(() => {
    const id = setInterval(() => setNow(new Date()), 30000);
    return () => clearInterval(id);
  }, []);
  const hh = String(now.getHours()).padStart(2,'0');
  const mm = String(now.getMinutes()).padStart(2,'0');
  const dt = now.toLocaleDateString('pt-BR', { weekday: 'long', day: '2-digit', month: 'long' });

  const tabs = [
    { id: 'overview',  label: 'Overview',                icon: 'overview', critical: 0 },
    { id: 'clientes',  label: 'Análise de Clientes',     icon: 'clients',  critical: 3 },
    { id: 'negocio',   label: 'Análise de Negócio',      icon: 'business' },
    { id: 'reps',      label: 'Análise de Reps',         icon: 'reps' },
    { id: 'mercado',   label: 'Inteligência de Mercado', icon: 'market' },
  ];

  return (
    <div className="cc-head">
      <div className="cc-head-row">
        <div className="cc-head-title">
          <div className="cc-head-orb"/>
          <div>
            <div className="cc-head-eyebrow">Inteligência de mercado · Brumar</div>
            <h1>Command Center</h1>
          </div>
        </div>
        <div className="cc-head-meta">
          <span className="live-pulse"/>
          <span>SINCRONIZADO</span>
          <span style={{ color: 'var(--g300)' }}>·</span>
          <span style={{ textTransform: 'capitalize' }}>{dt}</span>
          <span style={{ color: 'var(--g300)' }}>·</span>
          <span>{hh}:{mm}</span>
        </div>
      </div>

      <div className="cc-tabs">
        {tabs.map(t => (
          <button
            key={t.id}
            className={'cc-tab' + (t.id === tab ? ' active' : '') + (t.disabled ? ' disabled' : '')}
            onClick={() => !t.disabled && onTab(t.id)}
            title={t.disabled ? 'Disponível na próxima fase' : ''}
          >
            <CCIcon name={t.icon} size={14}/>
            <span>{t.label}</span>
            {t.critical > 0 && <span className="crit-dot"/>}
            {t.disabled && <span style={{ fontSize: 9, fontWeight: 600, color: 'var(--g400)', marginLeft: 4, textTransform: 'uppercase', letterSpacing: 0.6 }}>fase 2</span>}
          </button>
        ))}
      </div>

      <div className="cc-ticker">
        <div className="cc-ticker-label">
          <span className="live-pulse"/>
          <span>LIVE</span>
        </div>
        <div className="cc-ticker-track">
          {[...ticker, ...ticker].map((t, i) => {
            const dir = t.delta > 0 ? 'up' : t.delta < 0 ? 'down' : 'flat';
            const arrow = dir === 'up' ? '▲' : dir === 'down' ? '▼' : '–';
            const fmtVal = (() => {
              const num = t.value;
              if (num >= 1000) return num.toLocaleString('pt-BR');
              return num.toFixed(num < 10 ? 3 : 2);
            })();
            const fmtDelta = (() => {
              if (t.deltaPct == null) return Math.abs(t.delta).toFixed(2);
              return Math.abs(t.deltaPct).toFixed(2) + '%';
            })();
            return (
              <div key={i} className="cc-ticker-item">
                <span className="k">{t.label}</span>
                <span className="v">{t.prefix || ''}{fmtVal}{t.suffix || ''}</span>
                <span className={'d ' + dir}>{arrow} {fmtDelta}</span>
              </div>
            );
          })}
        </div>
      </div>
    </div>
  );
};

Object.assign(window, { CCIcon, useCountUp, CCHeader });
// Overview do Command Center: cards de seção, insight do dia, sinais críticos peek


// ============ Card de seção ============
const CCSectionCard = ({ icon, iconKind, title, stats, foot, footKind, gated, onClick }) => (
  <button className={'cc-section-card' + (gated ? ' gated' : '')} onClick={gated ? undefined : onClick}>
    <div className="cc-section-head">
      <h3>
        <div className={'cc-section-icon ' + (iconKind || '')}>
          <CCIcon name={icon} size={16}/>
        </div>
        {title}
      </h3>
      <div className="cc-section-arrow">
        {gated
          ? <span style={{ fontSize: 9, fontWeight: 700, letterSpacing: 0.8, color: 'var(--g400)' }}>FASE 2</span>
          : <CCIcon name="arrow-r" size={16}/>
        }
      </div>
    </div>
    <div className="cc-section-stats">
      {stats.map((s, i) => (
        <div key={i} className="cc-section-stat">
          <div className={'v' + (s.crit ? ' crit' : '')}>{s.v}</div>
          <div className="l">{s.l}</div>
        </div>
      ))}
    </div>
    <div className={'cc-section-foot ' + (footKind || '')}>
      {footKind && <span className="pulse"/>}
      <span>{foot}</span>
    </div>
  </button>
);

// ============ Mensagens & menções (topo do overview) ============
const CCMessages = ({ mensagens }) => {
  const naoLidas = (mensagens || []).filter(m => !m.lida).length;
  const tipoLabel = (t) => t === 'mention' ? 'mencionou você em' : t === 'reply' ? 'respondeu em' : 'comentou em';
  // Sistema de mensagens ainda não foi definido (memory: handoff Claude Design)
  // — mostra placeholder até decidir backend (Slack-like? E-mail? Próprio?).
  if (!mensagens || mensagens.length === 0) {
    return (
      <div className="cc-msgs">
        <div className="cc-msgs-head">
          <h3><CCIcon name="message" size={15}/> Mensagens & menções</h3>
          <span style={{ fontSize: 11, color: 'var(--g500)', fontStyle: 'italic' }}>em construção</span>
        </div>
        <div style={{ padding: '24px 18px', textAlign: 'center', color: 'var(--g500)', fontSize: 12 }}>
          Sistema de mensagens entre usuários ainda em design.<br/>
          Hoje use Observações no contexto da NF/cliente/pedido.
        </div>
      </div>
    );
  }
  return (
    <div className="cc-msgs">
      <div className="cc-msgs-head">
        <h3>
          <CCIcon name="message" size={15}/>
          Mensagens & menções
          {naoLidas > 0 && <span className="cc-msgs-count">{naoLidas} novas</span>}
        </h3>
        <button className="btn ghost" style={{ fontSize: 12 }}>Abrir caixa</button>
      </div>
      <div className="cc-msgs-list">
        {mensagens.map(m => (
          <div key={m.id} className={'cc-msg' + (m.lida ? ' lida' : '')}>
            <div className="cc-msg-avatar" style={{ background: m.autorCor }}>{m.autorAvatar}</div>
            <div className="cc-msg-body">
              <div className="cc-msg-line">
                <b>{m.autor}</b>
                <span className="cc-msg-action"> {tipoLabel(m.tipo)} </span>
                <a className="cc-msg-ctx">{m.contexto.label}</a>
                <span className="cc-msg-when">{m.em}</span>
              </div>
              <div className="cc-msg-text">"{m.texto}"</div>
            </div>
            {!m.lida && <span className="cc-msg-dot"/>}
          </div>
        ))}
      </div>
    </div>
  );
};

// ============ Insight do dia (AI) — versão clara ============
const CCInsight = ({ insight, onOpenSignal }) => (
  <div className="cc-insight">
    <div className="cc-insight-head">
      <span className="cc-insight-badge">
        <CCIcon name="sparkles" size={12}/>
        AI · Insight do dia
      </span>
      <span className="cc-insight-when">detectado há 4h</span>
    </div>
    <h3>{insight.titulo}</h3>
    <p className="cc-insight-text">{insight.texto}</p>
    <div className="cc-insight-action">
      <CCIcon name="zap" size={14}/>
      <div><b>Ação sugerida:</b> {insight.acao}</div>
    </div>
    <div className="cc-insight-foot">
      <button className="btn primary" onClick={() => onOpenSignal && onOpenSignal('sg-001')}>
        Ver clientes em risco
      </button>
      <button className="btn">
        <CCIcon name="message" size={13}/> Conversar com IA
      </button>
    </div>
  </div>
);

// ============ Sinais críticos peek (lista lateral) ============
const CCCritList = ({ signals, onOpen }) => {
  const crit = signals.filter(s => s.severity === 'red').slice(0, 4);
  return (
    <div className="cc-crit-list">
      <div className="cc-crit-head">
        <h3>Sinais críticos</h3>
        <span className="pill">
          <span className="dot"/>
          {crit.length} agora
        </span>
      </div>
      {crit.map(s => (
        <div key={s.id} className="cc-crit-item" onClick={() => onOpen(s)}>
          <div className="sev"><CCIcon name="alert" size={14}/></div>
          <div className="body">
            <div className="titulo">{s.titulo}</div>
            <div className="sub">{s.sub}</div>
          </div>
          <div className="when">{s.detectadoEm}</div>
        </div>
      ))}
    </div>
  );
};

// ============ Overview screen ============
const CCOverview = ({ data, layout, onTab, onOpenSignal }) => {
  const { kpisMacro, signals, clientes, ticker } = data;

  const cliRisk = clientes.filter(c => ['churn-iminente','churn-provavel','inadimplente','desaceleracao'].includes(c.status));
  const cliSaud = clientes.filter(c => ['saudavel','crescendo','reativado'].includes(c.status));
  const cliDorm = clientes.filter(c => c.status === 'dormindo');
  const noticiasAlta = data.noticias.filter(n => n.relevancia === 'alta').length;

  return (
    <div className={'cc-overview cc-stagger layout-' + (layout || 'side')}>
      <div className="cc-overview-main cc-stagger">

        <CCMessages mensagens={data.mensagens}/>

        <CCInsight insight={kpisMacro.insightDoDia} onOpenSignal={onOpenSignal}/>

        <CCSectionCard
          icon="clients"
          iconKind="red"
          title="Análise de Clientes"
          stats={[
            { v: 3,            l: 'Críticos',     crit: true },
            { v: cliRisk.length, l: 'Em risco' },
            { v: cliDorm.length, l: 'Dormindo' },
            { v: cliSaud.length, l: 'Saudáveis' },
          ]}
          foot="3 sinais novos detectados nas últimas 24h"
          footKind="red"
          onClick={() => onTab('clientes')}
        />

        <CCSectionCard
          icon="business"
          iconKind="blue"
          title="Análise de Negócio"
          stats={[
            { v: 'R$ 4.82M', l: 'Receita 30d' },
            { v: '+12%',     l: 'vs. período ant.' },
            { v: '—',        l: 'Margem média' },
            { v: '—',        l: 'Cotações abertas' },
          ]}
          foot="Câmbio, mix, geo de produtos"
          onClick={() => onTab('negocio')}
        />

        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16 }}>
          <CCSectionCard
            icon="reps"
            iconKind="amber"
            title="Análise de Reps"
            stats={[
              { v: 8,    l: 'Reps ativos' },
              { v: 'D.', l: 'Top mês' },
            ]}
            foot="Ranking, cobertura, ticket médio"
            onClick={() => onTab('reps')}
          />
          <CCSectionCard
            icon="market"
            iconKind="purple"
            title="Inteligência de Mercado"
            stats={[
              { v: noticiasAlta, l: 'Hoje' },
              { v: '+2.4%', l: 'EUR 7d' },
            ]}
            foot="Feed externo, caçador de bacalhau"
            onClick={() => onTab('mercado')}
          />
        </div>
      </div>

      <div className="cc-overview-side cc-stagger">
        <CCCritList signals={signals} onOpen={onOpenSignal}/>

        <CCOportunidades signals={signals} onTab={onTab}/>

        <CCLembretes lembretes={data.lembretes || []} />
      </div>
    </div>
  );
};

const CCOportunidades = ({ signals, onTab }) => {
  // Deriva de signals reais: green = oportunidade/reativação
  const greens = (signals || []).filter(s => s.severity === 'green');
  const cresc = greens.filter(s => s.tipo === 'oportunidade');
  const reat = greens.filter(s => s.tipo === 'reativacao');
  const top = greens[0];
  return (
    <button className="cc-section-card" onClick={() => onTab && onTab('clientes')} style={{ cursor: 'pointer' }}>
      <div className="cc-section-head">
        <h3>
          <div className="cc-section-icon green"><CCIcon name="trending-up" size={16}/></div>
          Oportunidades
        </h3>
        <div className="cc-section-arrow"><CCIcon name="arrow-r" size={16}/></div>
      </div>
      <div className="cc-section-stats">
        <div className="cc-section-stat">
          <div className="v" style={{ color: 'var(--green)' }}>{cresc.length}</div>
          <div className="l">Crescendo</div>
        </div>
        <div className="cc-section-stat">
          <div className="v">{reat.length}</div>
          <div className="l">Reativado</div>
        </div>
      </div>
      {top && top.titulo && (
        <div className="cc-section-foot green">
          <span className="pulse"/>
          <span>{top.titulo}</span>
        </div>
      )}
      {greens.length === 0 && (
        <div className="cc-section-foot" style={{ color: 'var(--g500)', fontStyle: 'italic' }}>
          <span>Nenhuma oportunidade detectada</span>
        </div>
      )}
    </button>
  );
};

const CCLembretes = ({ lembretes }) => {
  const formatWhen = (data_alvo) => {
    if (!data_alvo) return '—';
    const d = new Date(data_alvo);
    const hoje = new Date(); hoje.setHours(0,0,0,0);
    const amanha = new Date(hoje); amanha.setDate(amanha.getDate()+1);
    const alvo = new Date(d); alvo.setHours(0,0,0,0);
    if (alvo.getTime() === hoje.getTime()) return 'Hoje';
    if (alvo.getTime() === amanha.getTime()) return 'Amanhã';
    return d.toLocaleDateString('pt-BR', { timeZone: 'UTC', day: '2-digit', month: 'short' });
  };
  return (
    <div className="cc-section-card" style={{ cursor: 'default' }}>
      <div className="cc-section-head">
        <h3>
          <div className="cc-section-icon"><CCIcon name="bell" size={16}/></div>
          Lembretes {lembretes.length > 0 && <span style={{ fontSize: 11, color: 'var(--g500)', fontWeight: 'normal', marginLeft: 6 }}>({lembretes.length})</span>}
        </h3>
      </div>
      {lembretes.length === 0 ? (
        <div style={{ fontSize: 12, color: 'var(--g500)', fontStyle: 'italic', padding: '14px 0', textAlign: 'center' }}>
          Sem lembretes pendentes
        </div>
      ) : (
        <div style={{ fontSize: 12.5, color: 'var(--g700)', lineHeight: 1.6, maxHeight: 200, overflowY: 'auto' }}>
          {lembretes.slice(0, 6).map((l, i) => (
            <div key={l.id || i} style={{ padding: '6px 0', borderBottom: i < lembretes.length - 1 ? '1px solid var(--g100)' : 'none' }}>
              <b>{formatWhen(l.data_alvo)}</b> — {l.titulo || l.descricao || ''}
            </div>
          ))}
        </div>
      )}
    </div>
  );
};

Object.assign(window, { CCSectionCard, CCInsight, CCCritList, CCMessages, CCOverview, CCLembretes });
// Análise de Clientes do Command Center: KPIs, Heatmap, Sinais, Lista


// ============ KPIs do topo ============
const CCClientesKPIs = ({ clientes }) => {
  const total = clientes.length;
  const risco = clientes.filter(c => ['churn-iminente','churn-provavel','inadimplente','desaceleracao','mix-degradado'].includes(c.status)).length;
  const dormindo = clientes.filter(c => c.status === 'dormindo').length;
  const saudaveis = clientes.filter(c => ['saudavel','crescendo','reativado','estavel'].includes(c.status)).length;
  const receitaProtegida = clientes.filter(c => ['churn-iminente','churn-provavel','desaceleracao','inadimplente'].includes(c.status))
    .reduce((s, c) => s + c.receita90d, 0);

  const v0 = useCountUp(total);
  const v1 = useCountUp(risco);
  const v2 = useCountUp(dormindo);
  const v3 = useCountUp(saudaveis);

  return (
    <div className="cc-kpi-row">
      <div className="cc-kpi">
        <div className="cc-kpi-head">
          <span className="cc-kpi-label">Total ativos</span>
          <div className="cc-kpi-icon blue"><CCIcon name="clients" size={14}/></div>
        </div>
        <div className="cc-kpi-value">{v0}</div>
        <div className="cc-kpi-sub">CNPJ no escopo · São Paulo capital + grande SP</div>
      </div>

      <div className="cc-kpi">
        <div className="cc-kpi-head">
          <span className="cc-kpi-label">Em risco</span>
          <div className="cc-kpi-icon red"><CCIcon name="alert" size={14}/></div>
        </div>
        <div className="cc-kpi-value red">{v1}</div>
        <div className="cc-kpi-sub down">
          <CCIcon name="trending-down" size={11}/>
          R$ {(receitaProtegida/1000).toFixed(0)}k em receita 90d expostos
        </div>
      </div>

      <div className="cc-kpi">
        <div className="cc-kpi-head">
          <span className="cc-kpi-label">Dormindo</span>
          <div className="cc-kpi-icon amber"><CCIcon name="eye" size={14}/></div>
        </div>
        <div className="cc-kpi-value">{v2}</div>
        <div className="cc-kpi-sub">+180d sem comprar · oportunidade de reativação</div>
      </div>

      <div className="cc-kpi">
        <div className="cc-kpi-head">
          <span className="cc-kpi-label">Saudáveis</span>
          <div className="cc-kpi-icon green"><CCIcon name="trending-up" size={14}/></div>
        </div>
        <div className="cc-kpi-value">{v3}</div>
        <div className="cc-kpi-sub up">+2 crescendo · 1 reativado essa semana</div>
      </div>
    </div>
  );
};

// ============ Heatmap (SVG estilizado de SP) ============
// Coordenadas SP capital + região: lat -23.96..-22.90, lng -47.06..-46.33
// Projeção simples linear pra viewbox 1000x520

const projectMap = (lat, lng) => {
  const minLat = -23.99, maxLat = -22.85;
  const minLng = -47.10, maxLng = -46.25;
  const x = ((lng - minLng) / (maxLng - minLng)) * 1000;
  const y = ((maxLat - lat) / (maxLat - minLat)) * 520;
  return { x, y };
};

// Google Maps real — usado quando /api/cc/clientes-geo retorna dados.
// Cor por status: red (critico), amber (atencao), green (oportunidade), gray (saudavel).
const CCHeatmapReal = ({ clientesGeo, onClienteClick, mode }) => {
  const ref = cUseRef(null);
  const mapRef = cUseRef(null);
  const markersRef = cUseRef([]);

  cUseState(() => {}); // placeholder pra alinhar imports (cUseState declarado por outros)

  // Inicializa o mapa quando o ref ficar disponível
  React.useEffect(() => {
    if (!ref.current || !window._loadGmapsSdk) return;
    let cancelled = false;
    window._loadGmapsSdk().then(google => {
      if (cancelled || !ref.current) return;
      const sp = { lat: -23.55, lng: -46.63 }; // SP capital centro
      mapRef.current = new google.maps.Map(ref.current, {
        center: sp,
        zoom: 9,
        disableDefaultUI: false,
        mapTypeControl: false,
        streetViewControl: false,
        fullscreenControl: true,
        styles: [
          // Dark theme leve
          { elementType: 'geometry', stylers: [{ color: '#1a1f2e' }] },
          { elementType: 'labels.text.stroke', stylers: [{ color: '#1a1f2e' }] },
          { elementType: 'labels.text.fill', stylers: [{ color: '#9ca3af' }] },
          { featureType: 'water', elementType: 'geometry', stylers: [{ color: '#0f1729' }] },
          { featureType: 'road', elementType: 'geometry', stylers: [{ color: '#252b3d' }] },
          { featureType: 'poi', stylers: [{ visibility: 'off' }] },
          { featureType: 'transit', stylers: [{ visibility: 'off' }] },
        ],
      });
    });
    return () => { cancelled = true; };
  }, []);

  // (Re)renderiza markers quando clientesGeo muda
  React.useEffect(() => {
    if (!mapRef.current || !window.google) return;
    const google = window.google;
    // Limpa markers antigos
    markersRef.current.forEach(m => m.setMap(null));
    markersRef.current = [];
    const bounds = new google.maps.LatLngBounds();
    const colorMap = {
      critico: '#ef4444',
      atencao: '#fbbf24',
      oportunidade: '#22c55e',
      saudavel: '#9ca3af',
    };
    const sizeMap = { critico: 11, atencao: 9, oportunidade: 9, saudavel: 6 };
    (clientesGeo || []).forEach(c => {
      if (!c.lat || !c.lng) return;
      const pos = { lat: c.lat, lng: c.lng };
      const marker = new google.maps.Marker({
        position: pos,
        map: mapRef.current,
        icon: {
          path: google.maps.SymbolPath.CIRCLE,
          scale: sizeMap[c.status] || 6,
          fillColor: colorMap[c.status] || '#9ca3af',
          fillOpacity: 0.85,
          strokeColor: '#fff',
          strokeWeight: 1.5,
        },
        title: `${c.nome} · ${c.cidade || ''}${c.uf ? '/' + c.uf : ''}`,
      });
      marker.addListener('click', () => onClienteClick && onClienteClick(c));
      markersRef.current.push(marker);
      bounds.extend(pos);
    });
    if (markersRef.current.length > 0) {
      mapRef.current.fitBounds(bounds, 60);
    }
  }, [clientesGeo, onClienteClick]);

  const counts = (clientesGeo || []).reduce((acc, c) => { acc[c.status] = (acc[c.status] || 0) + 1; return acc; }, {});

  return (
    <div className="cc-map-body" style={{ position: 'relative', minHeight: 460 }}>
      <div ref={ref} style={{ width: '100%', height: 460, borderRadius: 12, overflow: 'hidden' }}/>
      <div style={{ position: 'absolute', top: 12, left: 12, background: 'rgba(15,23,41,.75)', backdropFilter: 'blur(8px)', padding: '8px 12px', borderRadius: 8, fontSize: 11, color: '#e5e7eb', pointerEvents: 'none' }}>
        <b>{(clientesGeo || []).length} clientes geocoded</b>{' '}
        <span style={{ marginLeft: 8 }}>
          <span style={{ color: '#ef4444' }}>● {counts.critico || 0}</span>{' '}
          <span style={{ color: '#fbbf24' }}>● {counts.atencao || 0}</span>{' '}
          <span style={{ color: '#22c55e' }}>● {counts.oportunidade || 0}</span>{' '}
          <span style={{ color: '#9ca3af' }}>● {counts.saudavel || 0}</span>
        </span>
        <div style={{ fontSize: 10, color: '#9ca3af', marginTop: 2 }}>
          {mode === 'concentracao' && 'Densidade · clique num cliente'}
          {mode === 'receita'      && 'Receita · clique num cliente'}
          {mode === 'vencidos'     && 'Cobrança · clique num cliente'}
          {mode === 'dormindo'     && 'Reativação · clique num cliente'}
        </div>
      </div>
    </div>
  );
};

const CCHeatmap = ({ heatmapBairros, mode, clientes, onClienteClick }) => {
  const [tooltip, setTooltip] = cUseState(null);

  // valor de cada bairro depende do mode
  const items = heatmapBairros.map(b => {
    let val, label, sub;
    if (mode === 'concentracao') {
      val = b.n;
      label = `${b.n} ${b.n === 1 ? 'cliente' : 'clientes'}`;
      sub = `Receita 90d: R$ ${(b.receita/1000).toFixed(0)}k`;
    } else if (mode === 'receita') {
      val = b.receita / 30000;
      label = `R$ ${(b.receita/1000).toFixed(0)}k`;
      sub = `${b.n} ${b.n === 1 ? 'cliente' : 'clientes'} · receita 90d`;
    } else if (mode === 'vencidos') {
      val = b.vencidos / 4000;
      label = b.vencidos > 0 ? `R$ ${(b.vencidos/1000).toFixed(1)}k venc.` : 'sem vencidos';
      sub = `${b.n} ${b.n === 1 ? 'cliente' : 'clientes'}`;
    } else { // dormindo
      val = b.dormindo * 4;
      label = b.dormindo > 0 ? `${b.dormindo} dormindo` : 'sem dormindo';
      sub = `${b.n} ${b.n === 1 ? 'cliente ativo' : 'clientes ativos'}`;
    }
    return { ...b, val, label, sub, _proj: projectMap(b.lat, b.lng) };
  });

  // Filtrar bairros com val > 0 só pra modos que precisam (vencidos / dormindo)
  const visible = (mode === 'vencidos' || mode === 'dormindo')
    ? items.filter(it => it.val > 0)
    : items;

  // Gradiente de cor por modo
  const colorFor = (val) => {
    if (mode === 'concentracao') {
      if (val >= 7) return { fill: '#ef4444', stroke: '#dc2626' };
      if (val >= 4) return { fill: '#f59e0b', stroke: '#d97706' };
      if (val >= 2) return { fill: '#84cc16', stroke: '#65a30d' };
      return { fill: '#22c55e', stroke: '#16a34a' };
    }
    if (mode === 'receita') {
      if (val >= 8) return { fill: '#ef4444', stroke: '#dc2626' };
      if (val >= 4) return { fill: '#f97316', stroke: '#ea580c' };
      if (val >= 2) return { fill: '#fbbf24', stroke: '#d97706' };
      return { fill: '#22c55e', stroke: '#16a34a' };
    }
    if (mode === 'vencidos') {
      return { fill: '#ef4444', stroke: '#dc2626' };
    }
    return { fill: '#a78bfa', stroke: '#8b5cf6' };
  };

  const radiusFor = (val) => {
    if (mode === 'concentracao') return Math.max(14, Math.min(48, 12 + val * 5));
    if (mode === 'receita')      return Math.max(14, Math.min(60, 12 + val * 5));
    if (mode === 'vencidos')     return Math.max(20, Math.min(60, 16 + val * 5));
    return Math.max(16, Math.min(40, 14 + val * 4));
  };

  return (
    <div className="cc-map-body">
      {/* SVG da base do mapa: silhueta estilizada de SP capital */}
      <svg className="cc-map-svg" viewBox="0 0 1000 520" preserveAspectRatio="xMidYMid slice">
        <defs>
          <radialGradient id="mapGlow" cx="50%" cy="40%" r="60%">
            <stop offset="0%" stopColor="#1a253f" stopOpacity="0.6"/>
            <stop offset="100%" stopColor="#0f1729" stopOpacity="0"/>
          </radialGradient>
          <pattern id="grid" x="0" y="0" width="40" height="40" patternUnits="userSpaceOnUse">
            <path d="M 40 0 L 0 0 0 40" fill="none" stroke="#1a253f" strokeWidth="0.5" opacity="0.5"/>
          </pattern>
          {/* Filter pra bubble glow */}
          <filter id="bubbleGlow" x="-50%" y="-50%" width="200%" height="200%">
            <feGaussianBlur stdDeviation="6" result="coloredBlur"/>
            <feMerge>
              <feMergeNode in="coloredBlur"/>
              <feMergeNode in="SourceGraphic"/>
            </feMerge>
          </filter>
        </defs>

        {/* Background */}
        <rect width="1000" height="520" fill="#0f1729"/>
        <rect width="1000" height="520" fill="url(#grid)"/>
        <rect width="1000" height="520" fill="url(#mapGlow)"/>

        {/* Rios e water bodies — Tietê + represas */}
        <path d="M 0 180 Q 200 150 380 200 T 720 220 Q 850 240 1000 230"
              stroke="#1e3a5f" strokeWidth="14" fill="none" opacity="0.5" strokeLinecap="round"/>
        <path d="M 0 180 Q 200 150 380 200 T 720 220 Q 850 240 1000 230"
              stroke="#2a4d7a" strokeWidth="6" fill="none" opacity="0.7" strokeLinecap="round"/>

        {/* Reservatório Guarapiranga (sul-oeste) */}
        <ellipse cx="380" cy="380" rx="60" ry="35" fill="#1e3a5f" opacity="0.5" transform="rotate(-15 380 380)"/>
        {/* Reservatório Billings */}
        <ellipse cx="510" cy="430" rx="80" ry="25" fill="#1e3a5f" opacity="0.5" transform="rotate(20 510 430)"/>

        {/* Marginais e principais avenidas — branco fino */}
        <g stroke="#fafafa" strokeWidth="1" fill="none" opacity="0.18" strokeLinecap="round">
          {/* Marginal Tietê (acompanha o rio) */}
          <path d="M 0 195 Q 200 165 380 215 T 720 235 Q 850 255 1000 245"/>
          {/* Marginal Pinheiros */}
          <path d="M 380 200 Q 400 280 420 360 Q 430 410 440 460"/>
          {/* Av Paulista / 23 de Maio */}
          <path d="M 470 240 L 510 290 L 530 330"/>
          {/* Av Faria Lima / Berrini */}
          <path d="M 410 265 L 440 320 L 470 360"/>
          {/* Av 9 de Julho */}
          <path d="M 490 250 L 520 305"/>
          {/* Bandeirantes / Imigrantes (sul) */}
          <path d="M 510 330 L 540 410 L 580 480"/>
          {/* Anchieta */}
          <path d="M 540 350 Q 600 420 660 490"/>
          {/* Castelo Branco (oeste) */}
          <path d="M 380 200 L 280 180 L 150 175"/>
          {/* Anhanguera */}
          <path d="M 380 200 L 320 140 L 220 100 L 100 80"/>
          {/* Dutra (leste) */}
          <path d="M 600 200 L 720 170 L 850 145"/>
          {/* Raposo Tavares (oeste-sul) */}
          <path d="M 410 270 L 300 290 L 200 320"/>
        </g>

        {/* Ruas secundárias — grade fina e quase invisível */}
        <g stroke="#fafafa" strokeWidth="0.4" fill="none" opacity="0.08" strokeLinecap="round">
          {Array.from({length: 24}).map((_, i) => (
            <line key={'h'+i} x1="0" y1={i*22 + 60} x2="1000" y2={i*22 + 60}/>
          ))}
          {Array.from({length: 30}).map((_, i) => (
            <line key={'v'+i} x1={i*34 + 100} y1="0" x2={i*34 + 100} y2="520"/>
          ))}
        </g>

        {/* Heatmap underlay (radial gradients) */}
        <g opacity="0.55" filter="url(#bubbleGlow)">
          {visible.map(item => {
            const c = colorFor(item.val);
            const r = radiusFor(item.val);
            return (
              <circle key={'g-'+item.bairro} cx={item._proj.x} cy={item._proj.y} r={r * 1.6}
                      fill={c.fill} opacity="0.4"/>
            );
          })}
        </g>

        {/* Bubbles com label */}
        <g>
          {visible.map(item => {
            const c = colorFor(item.val);
            const r = radiusFor(item.val);
            const showLbl = r >= 18;
            return (
              <g key={item.bairro}
                 className="cc-bubble"
                 onMouseEnter={(e) => setTooltip({ ...item, x: item._proj.x, y: item._proj.y })}
                 onMouseLeave={() => setTooltip(null)}>
                <circle cx={item._proj.x} cy={item._proj.y} r={r}
                        fill={c.fill} stroke={c.stroke} strokeWidth="2"
                        opacity="0.92"/>
                {showLbl && (
                  <text className="cc-bubble-label" x={item._proj.x} y={item._proj.y}>
                    {item.n}
                  </text>
                )}
              </g>
            );
          })}
        </g>

        {/* Labels de bairros importantes (apenas alguns, em branco fantasma) */}
        <g fill="#fafafa" opacity="0.35" fontSize="10" fontFamily="DM Sans" fontWeight="500" textAnchor="middle">
          <text x="500" y="270">PAULISTA</text>
          <text x="430" y="280">PINHEIROS</text>
          <text x="490" y="120">SANTANA</text>
          <text x="620" y="290">TATUAPÉ</text>
          <text x="560" y="450">SANTO ANDRÉ</text>
          <text x="320" y="430">GUARULHOS</text>
        </g>
      </svg>

      {tooltip && (
        <div className="cc-tooltip" style={{
          left: `${(tooltip.x / 1000) * 100}%`,
          top: `${(tooltip.y / 520) * 100 - 8}%`,
          transform: 'translate(-50%, -100%)',
        }}>
          <div className="t">{tooltip.bairro}</div>
          <div className="r"><b>{tooltip.label}</b></div>
          <div className="r" style={{ opacity: 0.75, marginTop: 2 }}>{tooltip.sub}</div>
        </div>
      )}

      {/* Overlay de legenda */}
      <div className="cc-map-overlay">
        <div className="k">
          {mode === 'concentracao' && 'Concentração de clientes'}
          {mode === 'receita' && 'Receita por bairro · 90d'}
          {mode === 'vencidos' && 'Saldo vencido por região'}
          {mode === 'dormindo' && 'Clientes dormindo · +180d'}
        </div>
        <div className="v">
          {mode === 'concentracao' && `${visible.reduce((s,b)=>s+b.n,0)} clientes em ${visible.length} bairros`}
          {mode === 'receita' && `R$ ${(visible.reduce((s,b)=>s+b.receita,0)/1000).toFixed(0)}k total`}
          {mode === 'vencidos' && `R$ ${(visible.reduce((s,b)=>s+b.vencidos,0)/1000).toFixed(0)}k em ${visible.length} bairro${visible.length>1?'s':''}`}
          {mode === 'dormindo' && `${visible.reduce((s,b)=>s+b.dormindo,0)} clientes adormecidos`}
        </div>
        <div className="legend">
          <span className="lbl">menos</span>
          <div className="grad" style={{
            background: mode === 'vencidos'
              ? 'linear-gradient(90deg, #fecaca, #dc2626)'
              : mode === 'dormindo'
              ? 'linear-gradient(90deg, #ddd6fe, #7c3aed)'
              : 'linear-gradient(90deg, #16a34a, #f59e0b, #dc2626)'
          }}/>
          <span className="lbl">mais</span>
        </div>
      </div>

      {/* Controles de zoom (fakes — só visual) */}
      <div className="cc-map-controls">
        <button title="Zoom in"><CCIcon name="plus" size={15}/></button>
        <button title="Zoom out"><CCIcon name="minus" size={15}/></button>
        <button title="Reset"><CCIcon name="reset" size={15}/></button>
        <button title="Layers"><CCIcon name="layers" size={15}/></button>
      </div>
    </div>
  );
};

// ============ Sinal individual (card) ============
const CCSignal = ({ s, onClick }) => (
  <button className={'cc-signal ' + s.severity + (s.pulso ? ' pulso' : '')} onClick={() => onClick(s)}>
    <div className="cc-signal-head">
      <span className="cc-signal-tag">{s.label}</span>
      <span className="cc-signal-when">{s.detectadoEm}</span>
    </div>
    <div className="cc-signal-titulo">{s.titulo}</div>
    <div className="cc-signal-sub">{s.sub}</div>
    {s.cliente && (
      <div className="cc-signal-foot">
        <span className="who"><CCIcon name="building" size={11}/> {s.cliente.cidade}</span>
        <span style={{ color: 'var(--g300)' }}>·</span>
        <span className="who"><CCIcon name="reps" size={11}/> {s.cliente.rep}</span>
      </div>
    )}
  </button>
);

// ============ Tela completa de Análise de Clientes ============
const CCClientes = ({ data, onOpenSignal, onOpenCliente }) => {
  const [mapMode, setMapMode] = cUseState('concentracao');
  const [filter, setFilter] = cUseState('todos');
  const [clientesGeo, setClientesGeo] = cUseState(null);

  React.useEffect(() => {
    ccFetch('/api/cc/clientes-geo?limit=1000').then(r => {
      if (r && r.ok) setClientesGeo(r.clientes);
    }).catch(() => setClientesGeo([])); // [] = sinal pra cair no fallback mock
  }, []);

  const sigClientes = data.signals.filter(s => s.area === 'clientes');
  const sigFiltered = sigClientes.filter(s => {
    if (filter === 'todos') return true;
    if (filter === 'criticos') return s.severity === 'red';
    if (filter === 'atencao') return s.severity === 'amber';
    if (filter === 'oport') return s.severity === 'green';
    return true;
  });

  // Lista clientes ranked por score de risco (descendente)
  const cliRanked = [...data.clientes]
    .filter(c => ['churn-iminente','churn-provavel','inadimplente','desaceleracao','mix-degradado','dormindo'].includes(c.status))
    .sort((a, b) => b.score - a.score)
    .slice(0, 10);

  return (
    <div className="cc-clientes cc-stagger">
      <CCClientesKPIs clientes={data.clientes}/>

      <div className="cc-map">
        <div className="cc-map-head">
          <h3>
            <CCIcon name="pin" size={16}/>
            Heatmap geográfico
          </h3>
          <div className="cc-mode-rail">
            <button className={mapMode==='concentracao' ? 'active' : ''} onClick={() => setMapMode('concentracao')}>
              <span className="swatch" style={{ background: 'linear-gradient(90deg, #16a34a, #f59e0b, #dc2626)' }}/>
              Concentração
            </button>
            <button className={mapMode==='receita' ? 'active' : ''} onClick={() => setMapMode('receita')}>
              <span className="swatch" style={{ background: 'linear-gradient(90deg, #16a34a, #fbbf24, #ef4444)' }}/>
              Receita
            </button>
            <button className={mapMode==='vencidos' ? 'active' : ''} onClick={() => setMapMode('vencidos')}>
              <span className="swatch" style={{ background: 'linear-gradient(90deg, #fecaca, #dc2626)' }}/>
              Vencidos
            </button>
            <button className={mapMode==='dormindo' ? 'active' : ''} onClick={() => setMapMode('dormindo')}>
              <span className="swatch" style={{ background: 'linear-gradient(90deg, #ddd6fe, #7c3aed)' }}/>
              Dormindo
            </button>
          </div>
        </div>
        {clientesGeo && clientesGeo.length > 0
          ? <CCHeatmapReal clientesGeo={clientesGeo} mode={mapMode} onClienteClick={(c) => onOpenCliente({ id: c.cli_cod, nome: c.nome, cidade: c.cidade ? `${c.cidade}/${c.uf}` : '', bairro: '', status: c.status, ticketMed: 0, freq30d: 0, ult: '', receita90d: 0, vencidos: 0, rep: '', segmento: '', deltaPct: 0, lat: c.lat, lng: c.lng })}/>
          : <CCHeatmap heatmapBairros={data.heatmapBairros} mode={mapMode} clientes={data.clientes} onClienteClick={onOpenCliente}/>}
      </div>

      <div className="cc-signals-bar">
        <h4>Radar de sinais</h4>
        <div className="cc-mode-rail">
          <button className={filter==='todos' ? 'active' : ''} onClick={() => setFilter('todos')}>Todos · {sigClientes.length}</button>
          <button className={filter==='criticos' ? 'active' : ''} onClick={() => setFilter('criticos')}>Críticos · {sigClientes.filter(s=>s.severity==='red').length}</button>
          <button className={filter==='atencao' ? 'active' : ''} onClick={() => setFilter('atencao')}>Atenção · {sigClientes.filter(s=>s.severity==='amber').length}</button>
          <button className={filter==='oport' ? 'active' : ''} onClick={() => setFilter('oport')}>Oportunidades · {sigClientes.filter(s=>s.severity==='green').length}</button>
        </div>
        <div className="grow"/>
        <button className="btn sm ghost"><CCIcon name="filter" size={13}/> Mais filtros</button>
      </div>

      <div className="cc-signals-grid">
        {sigFiltered.map(s => (
          <CCSignal key={s.id} s={s} onClick={onOpenSignal}/>
        ))}
      </div>

      <div className="cc-map" style={{ marginTop: 4 }}>
        <div className="cc-map-head">
          <h3><CCIcon name="alert" size={16}/> Top 10 — clientes em risco (score)</h3>
          <span className="badge gray" style={{ marginLeft: 'auto' }}>ordenado por score de churn</span>
        </div>
        <div className="cc-cli-list">
          {cliRanked.map(c => {
            const sevKind = c.score >= 80 ? 'red' : c.score >= 50 ? 'amber' : c.score >= 30 ? 'green' : 'green';
            const deltaDir = c.deltaPct < 0 ? 'down' : 'up';
            return (
              <div key={c.id} className="cc-cli-row" onClick={() => onOpenCliente(c)}>
                <div className={'cc-cli-score ' + sevKind}>{c.score}</div>
                <div>
                  <div className="nome">{c.nome}</div>
                  <div className="meta">{c.cidade} · {c.bairro} · última: {c.ult}{c.vencidos > 0 ? ` · R$ ${(c.vencidos/1000).toFixed(1)}k vencidos` : ''}</div>
                </div>
                <div className="ticket">R$ {c.ticketMed.toLocaleString('pt-BR')}</div>
                <div className={'delta ' + deltaDir}>
                  {c.deltaPct > 0 ? '+' : ''}{c.deltaPct === 999 ? 'novo' : c.deltaPct + '%'}
                </div>
                <CCIcon name="arrow-r" size={14} className=""/>
              </div>
            );
          })}
        </div>
      </div>
    </div>
  );
};

Object.assign(window, { CCClientesKPIs, CCHeatmap, CCSignal, CCClientes });
// Drawers (drill cliente / sinal / anotar AI), Tweaks, App principal


// ============ Drawer: Drill de Sinal ============
const CCSignalDrawer = ({ signal, data, onClose, onOpenAnnot }) => {
  const [chatOpen, setChatOpen] = aUseState(false);
  const [chatInput, setChatInput] = aUseState('');
  const [chatMsgs, setChatMsgs] = aUseState([]);

  if (!signal) return null;
  const cliente = signal.cliente
    ? data.clientes.find(c => c.nome === signal.cliente.nome)
    : null;
  const knowledge = data.aiKnowledge.filter(k =>
    (k.escopo === 'cliente' && cliente && k.ref === cliente.id) ||
    (k.escopo === 'segmento' && cliente && k.ref === cliente.segmento)
  );

  const maxHist = signal.historico ? Math.max(...signal.historico.map(h => h.val)) : 0;

  const sugestoes = [
    'Snooze 7 dias',
    'Ignorar — sazonalidade conhecida',
    'Marcar como resolvido',
    'Por que esse sinal apareceu?',
  ];

  const sendChat = async (txt) => {
    if (!txt.trim()) return;
    const userMsg = { from: 'user', text: txt };
    setChatMsgs(prev => [...prev, userMsg, { from: 'ai', text: '⏳ pensando...', loading: true }]);
    setChatInput('');
    try {
      // Comandos rápidos: snooze/resolver/ignorar viram action no backend.
      const lower = txt.toLowerCase();
      if (signal.id && (lower.includes('snooze') || lower.startsWith('silenc'))) {
        const dias = parseInt((lower.match(/(\d+)\s*d/) || [])[1] || '7');
        const r = await fetch('/api/cc/signals/' + signal.id + '/snooze', {
          method: 'POST', headers: { 'Content-Type':'application/json', 'Authorization':'Bearer '+(localStorage.getItem('nexus_token')||'') },
          body: JSON.stringify({ dias })
        });
        const d = await r.json();
        setChatMsgs(prev => prev.slice(0,-1).concat({ from: 'ai', text: d.ok ? `Silenciado por ${dias} dias. Reativa automático em ${new Date(d.snoozed_until).toLocaleDateString('pt-BR')}.` : 'Erro: '+(d.error||'falha') }));
        return;
      }
      if (signal.id && (lower.includes('resolv') || lower.includes('marcar como resolv'))) {
        const r = await fetch('/api/cc/signals/' + signal.id + '/resolve', {
          method: 'POST', headers: { 'Content-Type':'application/json', 'Authorization':'Bearer '+(localStorage.getItem('nexus_token')||'') },
          body: JSON.stringify({ comment: txt })
        });
        const d = await r.json();
        setChatMsgs(prev => prev.slice(0,-1).concat({ from: 'ai', text: d.ok ? 'Sinal marcado como resolvido. Pode me contar o que aconteceu? Anotação ajuda a calibrar.' : 'Erro: '+(d.error||'falha') }));
        return;
      }
      if (signal.id && lower.includes('ignor')) {
        const r = await fetch('/api/cc/signals/' + signal.id + '/ignore', {
          method: 'POST', headers: { 'Content-Type':'application/json', 'Authorization':'Bearer '+(localStorage.getItem('nexus_token')||'') },
          body: JSON.stringify({ motivo: txt })
        });
        const d = await r.json();
        setChatMsgs(prev => prev.slice(0,-1).concat({ from: 'ai', text: d.ok ? 'Sinal ignorado. Não vou trazer de volta com mesmo padrão.' : 'Erro: '+(d.error||'falha') }));
        return;
      }
      // Fallback: pergunta livre via Claude. Endpoint /api/ai/admin-chat com contexto do sinal.
      const ctx = `Contexto do sinal:
- Tipo: ${signal.label||signal.tipo}
- Título: ${signal.titulo}
- Descrição: ${signal.sub}
${cliente ? '- Cliente: ' + cliente.nome + ' ('+cliente.cnpj+', '+cliente.cidade+')' : ''}
${signal.metadata ? '- Metadados: ' + JSON.stringify(signal.metadata) : ''}`;
      const r = await fetch('/api/ai/admin-chat', {
        method: 'POST', headers: { 'Content-Type':'application/json', 'Authorization':'Bearer '+(localStorage.getItem('nexus_token')||'') },
        body: JSON.stringify({ message: ctx + '\n\nPergunta: ' + txt, no_tool_use: true })
      });
      const d = await r.json();
      const aiText = d.text || d.response || (d.error ? 'Erro: '+d.error : 'Não consegui responder agora.');
      setChatMsgs(prev => prev.slice(0,-1).concat({ from: 'ai', text: aiText }));
    } catch (e) {
      setChatMsgs(prev => prev.slice(0,-1).concat({ from: 'ai', text: 'Erro: '+e.message }));
    }
  };

  return (
    <>
      <div className="cc-drawer-overlay" onClick={onClose}/>
      <div className="cc-drawer">
        <div className="cc-drawer-head">
          <div style={{ flex: 1 }}>
            <div className="crumb">{signal.label}</div>
            <h2>{signal.titulo}</h2>
          </div>
          <button className="close" onClick={onClose}><CCIcon name="x" size={18}/></button>
        </div>
        <div className="cc-drawer-body">
          {signal.cliente && (
            <div className="cc-drawer-section">
              <h4>Cliente</h4>
              <div style={{ fontSize: 14, fontWeight: 600, color: 'var(--g900)', marginBottom: 4 }}>{signal.cliente.nome}</div>
              <div style={{ fontSize: 12, color: 'var(--g500)', display: 'flex', gap: 12, flexWrap: 'wrap' }}>
                <span style={{ fontFamily: 'var(--mono)' }}>{signal.cliente.cnpj}</span>
                <span>·</span>
                <span>{signal.cliente.cidade}</span>
                <span>·</span>
                <span>Rep: {signal.cliente.rep}</span>
              </div>
            </div>
          )}

          <div className="cc-drawer-section">
            <h4>O que aconteceu</h4>
            <p style={{ margin: 0, fontSize: 13.5, color: 'var(--g700)', lineHeight: 1.55 }}>{signal.sub}</p>
          </div>

          {signal.historico && (
            <div className="cc-drawer-section">
              <h4>Histórico de compras (6 meses)</h4>
              <div className="cc-sparkbar">
                {signal.historico.map((h, i) => {
                  const ratio = h.val / maxHist;
                  const last = i === signal.historico.length - 1;
                  const prevVal = i > 0 ? signal.historico[i-1].val : h.val;
                  const trending = h.val < prevVal * 0.75;
                  return (
                    <div key={i} className="cc-sparkbar-col">
                      <div className={'cc-sparkbar-bar' + (last ? ' crit' : trending ? ' warn' : '')}
                           style={{ height: `${ratio * 70}px` }}>
                        {last && <span className="val">R$ {(h.val/1000).toFixed(1)}k</span>}
                      </div>
                      <span className="lbl">{h.mes}</span>
                    </div>
                  );
                })}
              </div>
            </div>
          )}

          {signal.hipoteses && (
            <div className="cc-drawer-section">
              <h4>Hipóteses · AI</h4>
              <div className="cc-hipo">
                {signal.hipoteses.map((h, i) => (
                  <div key={i} className="cc-hipo-item">
                    <span className="cc-hipo-peso">{Math.round(h.peso * 100)}%</span>
                    <span>{h.txt}</span>
                  </div>
                ))}
              </div>
            </div>
          )}

          {knowledge.length > 0 && (
            <div className="cc-drawer-section">
              <h4>Anotações anteriores</h4>
              {knowledge.map(k => (
                <div key={k.id} className="cc-annot-existing">
                  <div className="meta">{k.autor} · {k.em} · escopo: {k.escopo}</div>
                  <div style={{ marginBottom: 6 }}>{k.conteudo}</div>
                  <div style={{ fontSize: 11, color: 'var(--g500)', fontStyle: 'italic' }}>↳ {k.racional}</div>
                </div>
              ))}
            </div>
          )}
        </div>
        <div className="cc-drawer-foot">
          <button className={'btn ' + (chatOpen ? 'primary' : '')} onClick={() => setChatOpen(v => !v)}>
            <CCIcon name="sparkles" size={14}/> Conversar com IA
          </button>
          <button className="btn" onClick={() => onOpenAnnot(signal, cliente)}>
            <CCIcon name="message" size={14}/> Anotar
          </button>
          <div style={{ flex: 1 }}/>
          <button className="btn ghost">Ver perfil</button>
        </div>
        {chatOpen && (
          <div className="cc-chat">
            <div className="cc-chat-msgs">
              <div className="cc-chat-bubble ai">
                <div className="cc-chat-from"><CCIcon name="sparkles" size={11}/> AI</div>
                Posso fazer snooze, ignorar, marcar resolvido ou explicar por que detectei. O que você quer fazer com esse sinal?
              </div>
              {chatMsgs.map((m, i) => (
                <div key={i} className={'cc-chat-bubble ' + m.from}>
                  {m.from === 'ai' && <div className="cc-chat-from"><CCIcon name="sparkles" size={11}/> AI</div>}
                  {m.text}
                </div>
              ))}
            </div>
            {chatMsgs.length === 0 && (
              <div className="cc-chat-sugs">
                {sugestoes.map((s, i) => (
                  <button key={i} className="cc-chat-sug" onClick={() => sendChat(s)}>{s}</button>
                ))}
              </div>
            )}
            <div className="cc-chat-input">
              <input
                className="input"
                placeholder="Pergunte ou peça uma ação..."
                value={chatInput}
                onChange={(e) => setChatInput(e.target.value)}
                onKeyDown={(e) => e.key === 'Enter' && sendChat(chatInput)}
                style={{ flex: 1 }}
              />
              <button className="btn primary" onClick={() => sendChat(chatInput)}>Enviar</button>
            </div>
          </div>
        )}
      </div>
    </>
  );
};

// ============ Drawer: Drill de Cliente ============
const CCClienteDrawer = ({ cliente, data, onClose, onOpenAnnot }) => {
  if (!cliente) return null;
  const sigs = data.signals.filter(s => s.cliente && s.cliente.nome === cliente.nome);
  const knowledge = data.aiKnowledge.filter(k =>
    (k.escopo === 'cliente' && k.ref === cliente.id) ||
    (k.escopo === 'segmento' && k.ref === cliente.segmento)
  );

  return (
    <>
      <div className="cc-drawer-overlay" onClick={onClose}/>
      <div className="cc-drawer">
        <div className="cc-drawer-head">
          <div style={{ flex: 1 }}>
            <div className="crumb">CLIENTE · score {cliente.score}/100</div>
            <h2>{cliente.nome}</h2>
          </div>
          <button className="close" onClick={onClose}><CCIcon name="x" size={18}/></button>
        </div>
        <div className="cc-drawer-body">
          <div className="cc-drawer-section">
            <div style={{ fontSize: 12, color: 'var(--g500)', display: 'flex', gap: 10, flexWrap: 'wrap' }}>
              <span>{cliente.cidade}</span>
              <span>·</span>
              <span>{cliente.bairro}</span>
              <span>·</span>
              <span>Segmento: {cliente.segmento}</span>
              <span>·</span>
              <span>Rep: {cliente.rep}</span>
            </div>
          </div>

          <div className="cc-drawer-section">
            <h4>Snapshot 90d</h4>
            <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3,1fr)', gap: 12 }}>
              <div>
                <div style={{ fontSize: 10.5, color: 'var(--g500)', fontWeight: 700, letterSpacing: 0.6, textTransform: 'uppercase', marginBottom: 4 }}>Receita 90d</div>
                <div style={{ fontFamily: 'var(--mono)', fontSize: 18, fontWeight: 600, color: 'var(--g900)' }}>R$ {(cliente.receita90d/1000).toFixed(1)}k</div>
              </div>
              <div>
                <div style={{ fontSize: 10.5, color: 'var(--g500)', fontWeight: 700, letterSpacing: 0.6, textTransform: 'uppercase', marginBottom: 4 }}>Ticket médio</div>
                <div style={{ fontFamily: 'var(--mono)', fontSize: 18, fontWeight: 600, color: 'var(--g900)' }}>R$ {(cliente.ticketMed/1000).toFixed(1)}k</div>
              </div>
              <div>
                <div style={{ fontSize: 10.5, color: 'var(--g500)', fontWeight: 700, letterSpacing: 0.6, textTransform: 'uppercase', marginBottom: 4 }}>Frequência 30d</div>
                <div style={{ fontFamily: 'var(--mono)', fontSize: 18, fontWeight: 600, color: 'var(--g900)' }}>{cliente.freq30d} pedido{cliente.freq30d !== 1 ? 's' : ''}</div>
              </div>
            </div>
            <div style={{ marginTop: 14, fontSize: 12, color: cliente.deltaPct < 0 ? 'var(--red)' : 'var(--green)', fontWeight: 600 }}>
              {cliente.deltaPct > 0 ? '+' : ''}{cliente.deltaPct}% vs período anterior · última compra há {cliente.ult}
            </div>
          </div>

          {sigs.length > 0 && (
            <div className="cc-drawer-section">
              <h4>Sinais ativos · {sigs.length}</h4>
              {sigs.map(s => (
                <div key={s.id} className={'cc-signal ' + s.severity} style={{ marginBottom: 8 }}>
                  <div className="cc-signal-head">
                    <span className="cc-signal-tag">{s.label}</span>
                    <span className="cc-signal-when">{s.detectadoEm}</span>
                  </div>
                  <div className="cc-signal-titulo">{s.titulo}</div>
                  <div className="cc-signal-sub">{s.sub}</div>
                </div>
              ))}
            </div>
          )}

          {knowledge.length > 0 && (
            <div className="cc-drawer-section">
              <h4>Conhecimento da AI sobre esse cliente</h4>
              {knowledge.map(k => (
                <div key={k.id} className="cc-annot-existing">
                  <div className="meta">{k.autor} · {k.em} · escopo: {k.escopo}</div>
                  <div style={{ marginBottom: 6 }}>{k.conteudo}</div>
                  <div style={{ fontSize: 11, color: 'var(--g500)', fontStyle: 'italic' }}>↳ {k.racional}</div>
                </div>
              ))}
            </div>
          )}
        </div>
        <div className="cc-drawer-foot">
          <button className="btn primary" onClick={() => onOpenAnnot(null, cliente)}>
            <CCIcon name="message" size={14}/> Anotar pra AI
          </button>
          <button className="btn">Ver perfil completo</button>
        </div>
      </div>
    </>
  );
};

// ============ Drawer: Anotar pra AI ============
const CCAnnotDrawer = ({ context, onClose }) => {
  const [scope, setScope] = aUseState(context && context.cliente ? 'cliente' : 'global');
  const [text, setText] = aUseState('');
  const [racional, setRacional] = aUseState('');
  const [saving, setSaving] = aUseState(false);
  const [savedMsg, setSavedMsg] = aUseState('');

  if (!context) return null;
  const { cliente, signal } = context;

  const salvar = async () => {
    if (!text.trim() || saving) return;
    setSaving(true); setSavedMsg('');
    try {
      // Mapeia scope da UI pro escopo de ai_knowledge.
      // - 'cliente': scope_type=cliente, scope_value=cli_cod
      // - 'segmento': scope_type=segmento, scope_value=segmento
      // - 'global': scope_type=global
      const body = { conteudo: text.trim(), racional: racional.trim() || null, tipo: 'nota' };
      if (scope === 'cliente' && cliente) {
        body.scope_type = 'cliente';
        body.scope_value = String(cliente.id || cliente.cli_cod || '');
      } else if (scope === 'segmento' && cliente && cliente.segmento) {
        body.scope_type = 'segmento';
        body.scope_value = cliente.segmento;
      } else {
        body.scope_type = 'global';
      }
      // Anotação confirmada (sem loop de interpretação) — Marcio é admin.
      body.interpretacao_confirmada = true;
      const r = await fetch('/api/ai-knowledge', {
        method: 'POST',
        headers: { 'Content-Type':'application/json', 'Authorization':'Bearer '+(localStorage.getItem('nexus_token')||'') },
        body: JSON.stringify(body)
      });
      if (!r.ok) {
        const e = await r.text();
        throw new Error(e.slice(0,200));
      }
      setSavedMsg('Salvo · AI vai usar nas próximas análises');
      setTimeout(() => onClose(), 1200);
    } catch (e) {
      setSavedMsg('Erro: ' + e.message);
    } finally {
      setSaving(false);
    }
  };

  return (
    <>
      <div className="cc-drawer-overlay" onClick={onClose}/>
      <div className="cc-drawer">
        <div className="cc-drawer-head">
          <div style={{ flex: 1 }}>
            <div className="crumb">ANOTAR PRA AI</div>
            <h2>Ensinar o sistema</h2>
          </div>
          <button className="close" onClick={onClose}><CCIcon name="x" size={18}/></button>
        </div>
        <div className="cc-drawer-body">
          <div className="cc-drawer-section">
            <h4>Contexto</h4>
            {cliente && <div style={{ fontSize: 13, color: 'var(--g700)', marginBottom: 4 }}><b>Cliente:</b> {cliente.nome}</div>}
            {signal && <div style={{ fontSize: 13, color: 'var(--g700)' }}><b>Sinal:</b> {signal.titulo}</div>}
            {!cliente && !signal && <div style={{ fontSize: 13, color: 'var(--g500)' }}>Anotação global · vai influenciar todo o radar</div>}
          </div>

          <div className="cc-drawer-section">
            <h4>Escopo da anotação</h4>
            <div className="cc-annot-meta" style={{ marginBottom: 12 }}>
              {cliente && <span className={'scope-pill' + (scope==='cliente' ? ' active':'')} onClick={() => setScope('cliente')}>Só este cliente</span>}
              {cliente && <span className={'scope-pill' + (scope==='segmento' ? ' active':'')} onClick={() => setScope('segmento')}>Segmento: {cliente.segmento}</span>}
              <span className={'scope-pill' + (scope==='global' ? ' active':'')} onClick={() => setScope('global')}>Global</span>
            </div>
            <textarea
              className="cc-annot"
              placeholder="Escreva o que você sabe e a AI ainda não sabe. Ex: 'Salesmar tá comprando da Algarve há 2 meses, vi nota fiscal deles no Atacadão.'"
              value={text}
              onChange={(e) => setText(e.target.value)}
            />
          </div>

          <div className="cc-drawer-section">
            <h4>Racional (por que isso importa)</h4>
            <textarea
              className="cc-annot"
              style={{ minHeight: 70 }}
              placeholder="Explique como a AI deve usar isso. Ex: 'Confirma migração competitiva, não sazonalidade.'"
              value={racional}
              onChange={(e) => setRacional(e.target.value)}
            />
          </div>
        </div>
        <div className="cc-drawer-foot">
          {savedMsg && <div style={{ fontSize: 12, color: savedMsg.startsWith('Erro') ? 'var(--red)' : 'var(--green)', marginRight: 'auto' }}>{savedMsg}</div>}
          <button className="btn primary" disabled={!text.trim() || saving} onClick={salvar}>
            {saving ? 'Salvando...' : 'Salvar conhecimento'}
          </button>
          <button className="btn" onClick={onClose}>Cancelar</button>
        </div>
      </div>
    </>
  );
};

// ============ Tweaks panel ============
// ============ Helpers de formatação ============
const fmtBRL = (v) => 'R$ ' + (v || 0).toLocaleString('pt-BR', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
const fmtBRLk = (v) => v >= 1e6 ? 'R$ ' + (v/1e6).toFixed(1) + 'M' : 'R$ ' + (v/1e3).toFixed(0) + 'k';
const fmtInt = (v) => (v || 0).toLocaleString('pt-BR');
const fmtKg = (v) => (v || 0).toLocaleString('pt-BR', { maximumFractionDigits: 0 }) + ' kg';
const fmtPct = (v) => v == null ? '—' : (v > 0 ? '+' : '') + v.toFixed(1) + '%';

// KPI inline simples (não confundir com cc-tier do clientes)
const Kpi = ({ label, value, sub }) => (
  <div style={{ background: 'var(--card)', padding: '14px 16px', borderRadius: 10, border: '1px solid var(--g200)' }}>
    <div style={{ fontSize: 10, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '.08em', color: 'var(--g500)', marginBottom: 6 }}>{label}</div>
    <div className="mono" style={{ fontSize: 20, fontWeight: 700, color: 'var(--g900)', lineHeight: 1.1 }}>{value}</div>
    {sub && <div style={{ fontSize: 11, color: 'var(--g600)', marginTop: 4 }}>{sub}</div>}
  </div>
);

// ============ F2 — Análise de Negócio ============
const CCNegocio = () => {
  const [data, setData] = aUseState(null);
  aUseEffect(() => { ccFetch('/api/cc/negocio').then(r => { if (r && r.ok) setData(r); }); }, []);
  if (!data) return <div className="cc-loading" style={{ padding: 60 }}>Carregando análise de negócio…</div>;
  const r = data.receita, vol = data.volume;
  const total10 = data.top10_clientes.reduce((s,c)=>s+c.receita, 0);
  const maxMarca = Math.max(...data.mix_marcas.map(m=>m.receita), 1);
  return (
    <div className="cc-clientes">
      {/* KPIs principais */}
      <div className="cc-kpis-row" style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 12, marginBottom: 16 }}>
        <Kpi label="Receita do mês" value={fmtBRLk(r.mes_atual)} sub={r.delta_pct != null ? <span style={{ color: r.delta_pct >= 0 ? 'var(--green)' : 'var(--red)' }}>{fmtPct(r.delta_pct)} vs anterior</span> : '—'} />
        <Kpi label="Receita 90 dias" value={fmtBRLk(r.d90)} sub={`${fmtInt(r.nfs_mes)} NFs no mês · ${fmtInt(r.clientes_mes)} clientes`} />
        <Kpi label="YTD (ano)" value={fmtBRLk(r.ytd)} sub="acumulado do ano" />
        <Kpi label="Margem média" value={<span style={{ color: 'var(--g400)' }}>—</span>} sub={<span style={{ color: 'var(--g400)' }}>custo incompleto</span>} />
      </div>
      <div className="cc-kpis-row" style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 12, marginBottom: 16 }}>
        <Kpi label="Volume do mês" value={fmtKg(vol.peso_kg_mes)} sub={`mês ant. ${fmtKg(vol.peso_kg_mes_ant)}`} />
        <Kpi label="Ticket / kg" value={vol.ticket_kg ? 'R$ ' + vol.ticket_kg.toFixed(2) : '—'} sub="receita / peso líquido" />
        <Kpi label="Concentração top 10" value={data.concentracao_top10_pct != null ? data.concentracao_top10_pct + '%' : '—'} sub="dos clientes geram X% da receita 90d" />
        <Kpi label="Cotações abertas" value={<span style={{ color: 'var(--g400)' }}>—</span>} sub={<span style={{ color: 'var(--g400)' }}>não rastreado</span>} />
      </div>

      {/* Mix por marca + Top produtos */}
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16, marginBottom: 16 }}>
        <div className="cc-card">
          <div className="cc-section-title" style={{ marginBottom: 12 }}>Mix por marca · 90d</div>
          {data.mix_marcas.map(m => (
            <div key={m.marca} style={{ marginBottom: 8 }}>
              <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 12, marginBottom: 3 }}>
                <span style={{ fontWeight: 600 }}>{m.marca}</span>
                <span className="mono" style={{ color: 'var(--g700)' }}>{fmtBRLk(m.receita)}</span>
              </div>
              <div style={{ height: 6, background: 'var(--g100)', borderRadius: 3, overflow: 'hidden' }}>
                <div style={{ height: '100%', width: ((m.receita/maxMarca)*100)+'%', background: 'linear-gradient(90deg, var(--blue), var(--blue-t))' }}/>
              </div>
            </div>
          ))}
        </div>
        <div className="cc-card">
          <div className="cc-section-title" style={{ marginBottom: 12 }}>Top 10 produtos · 90d</div>
          {data.mix_categorias.slice(0, 10).map((c, i) => (
            <div key={i} style={{ display: 'flex', justifyContent: 'space-between', padding: '5px 0', borderBottom: '1px dashed var(--g100)', fontSize: 12 }}>
              <span style={{ flex: 1, marginRight: 8, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{c.categoria}</span>
              <span className="mono" style={{ color: 'var(--g700)', fontWeight: 600 }}>{fmtBRLk(c.receita)}</span>
            </div>
          ))}
        </div>
      </div>

      {/* Geo por cidade + Top 10 clientes */}
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16 }}>
        <div className="cc-card">
          <div className="cc-section-title" style={{ marginBottom: 12 }}>Top cidades · 90d</div>
          {data.geo_cidades.slice(0, 10).map(c => (
            <div key={c.cidade+c.uf} style={{ display: 'flex', justifyContent: 'space-between', padding: '5px 0', borderBottom: '1px dashed var(--g100)', fontSize: 12 }}>
              <span>{c.cidade}<span style={{ color: 'var(--g500)', marginLeft: 4 }}>/{c.uf}</span></span>
              <span><span style={{ color: 'var(--g500)' }}>{c.clientes} cli</span> <span className="mono" style={{ color: 'var(--g700)', fontWeight: 600, marginLeft: 8 }}>{fmtBRLk(c.receita)}</span></span>
            </div>
          ))}
        </div>
        <div className="cc-card">
          <div className="cc-section-title" style={{ marginBottom: 12 }}>Top 10 clientes · 90d</div>
          {data.top10_clientes.map((c, i) => (
            <div key={c.cli_cod} style={{ display: 'flex', justifyContent: 'space-between', padding: '5px 0', borderBottom: '1px dashed var(--g100)', fontSize: 12 }}>
              <span>{i+1}. {c.cli_nome}</span>
              <span className="mono" style={{ color: 'var(--g700)', fontWeight: 600 }}>{fmtBRLk(c.receita)}</span>
            </div>
          ))}
          {total10 > 0 && data.concentracao_top10_pct != null && (
            <div style={{ marginTop: 10, padding: 8, background: 'var(--amber-bg)', borderRadius: 6, fontSize: 11, color: 'var(--amber-t)' }}>
              ⚠️ Top 10 = <b>{data.concentracao_top10_pct}%</b> da receita 90d. Risco de concentração.
            </div>
          )}
        </div>
      </div>
    </div>
  );
};

// ============ F3 — Análise de Reps ============
const CCReps = () => {
  const [data, setData] = aUseState(null);
  aUseEffect(() => { ccFetch('/api/cc/reps').then(r => { if (r && r.ok) setData(r); }); }, []);
  if (!data) return <div className="cc-loading" style={{ padding: 60 }}>Carregando análise de reps…</div>;
  const reps = data.reps || [];
  const totalReceita = reps.reduce((s,r)=>s+r.receita_30d, 0);
  return (
    <div className="cc-clientes">
      <div className="cc-kpis-row" style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 12, marginBottom: 16 }}>
        <Kpi label="Reps ativos (30d)" value={data.total_reps} sub={`R$ ${(totalReceita/1e6).toFixed(2)}M total`} />
        <Kpi label="Receita média / rep" value={data.total_reps ? fmtBRLk(totalReceita/data.total_reps) : '—'} sub="média 30d" />
        <Kpi label="Top rep" value={reps[0] ? reps[0].nome.split(' ')[0] : '—'} sub={reps[0] ? fmtBRLk(reps[0].receita_30d) : ''} />
        <Kpi label="Cumprimento meta" value={<span style={{ color: 'var(--g400)' }}>—</span>} sub={<span style={{ color: 'var(--g400)' }}>sem meta cadastrada</span>} />
      </div>
      <div className="cc-card">
        <div className="cc-section-title" style={{ marginBottom: 12 }}>Ranking · últimos 30 dias</div>
        <table style={{ width: '100%', fontSize: 13, borderCollapse: 'collapse' }}>
          <thead>
            <tr style={{ background: 'var(--g50)', textAlign: 'left' }}>
              <th style={{ padding: '8px 12px', fontSize: 10, textTransform: 'uppercase', letterSpacing: '.06em', color: 'var(--g500)', fontWeight: 600 }}>#</th>
              <th style={{ padding: '8px 12px', fontSize: 10, textTransform: 'uppercase', letterSpacing: '.06em', color: 'var(--g500)', fontWeight: 600 }}>Rep</th>
              <th style={{ padding: '8px 12px', fontSize: 10, textTransform: 'uppercase', letterSpacing: '.06em', color: 'var(--g500)', fontWeight: 600, textAlign: 'right' }}>Receita 30d</th>
              <th style={{ padding: '8px 12px', fontSize: 10, textTransform: 'uppercase', letterSpacing: '.06em', color: 'var(--g500)', fontWeight: 600, textAlign: 'right' }}>Δ vs ant.</th>
              <th style={{ padding: '8px 12px', fontSize: 10, textTransform: 'uppercase', letterSpacing: '.06em', color: 'var(--g500)', fontWeight: 600, textAlign: 'right' }}>NFs</th>
              <th style={{ padding: '8px 12px', fontSize: 10, textTransform: 'uppercase', letterSpacing: '.06em', color: 'var(--g500)', fontWeight: 600, textAlign: 'right' }}>Clientes</th>
              <th style={{ padding: '8px 12px', fontSize: 10, textTransform: 'uppercase', letterSpacing: '.06em', color: 'var(--g500)', fontWeight: 600, textAlign: 'right' }}>Ticket méd.</th>
              <th style={{ padding: '8px 12px', fontSize: 10, textTransform: 'uppercase', letterSpacing: '.06em', color: 'var(--g500)', fontWeight: 600 }}>UFs</th>
            </tr>
          </thead>
          <tbody>
            {reps.map((rep, i) => (
              <tr key={rep.ven_cod} style={{ borderBottom: '1px solid var(--g100)' }}>
                <td className="mono" style={{ padding: '8px 12px', color: 'var(--g500)', fontWeight: 600 }}>{i+1}</td>
                <td style={{ padding: '8px 12px' }}>
                  <div style={{ fontWeight: 600 }}>{rep.nome}</div>
                  <div style={{ fontSize: 10, color: 'var(--g500)' }} className="mono">ven_cod {rep.ven_cod}</div>
                </td>
                <td className="mono" style={{ padding: '8px 12px', textAlign: 'right', fontWeight: 600 }}>{fmtBRLk(rep.receita_30d)}</td>
                <td className="mono" style={{ padding: '8px 12px', textAlign: 'right', color: rep.delta_pct == null ? 'var(--g400)' : rep.delta_pct >= 0 ? 'var(--green)' : 'var(--red)' }}>
                  {rep.delta_pct == null ? '—' : fmtPct(rep.delta_pct)}
                </td>
                <td className="mono" style={{ padding: '8px 12px', textAlign: 'right' }}>{fmtInt(rep.nfs)}</td>
                <td className="mono" style={{ padding: '8px 12px', textAlign: 'right' }}>{fmtInt(rep.clientes)}</td>
                <td className="mono" style={{ padding: '8px 12px', textAlign: 'right' }}>{fmtBRLk(rep.ticket_medio)}</td>
                <td style={{ padding: '8px 12px', fontSize: 11, color: 'var(--g600)' }}>{(rep.ufs_atendidas || []).join(', ') || '—'}</td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
};

// ============ F4 — Inteligência de Mercado ============
const CCMercado = () => {
  const [data, setData] = aUseState(null);
  aUseEffect(() => { ccFetch('/api/cc/inteligencia').then(r => { if (r && r.ok) setData(r); }); }, []);
  if (!data) return <div className="cc-loading" style={{ padding: 60 }}>Carregando inteligência de mercado…</div>;
  const noticias = data.noticias || [];
  const sevColor = (s) => s === 'critica' ? 'var(--red)' : s === 'alerta' ? 'var(--amber)' : 'var(--g500)';
  return (
    <div className="cc-clientes">
      {/* Macro indicators */}
      <div className="cc-card" style={{ marginBottom: 16 }}>
        <div className="cc-section-title" style={{ marginBottom: 12 }}>Indicadores macro</div>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 12 }}>
          {(data.macro || []).map(m => (
            <div key={m.label} style={{ padding: 12, background: 'var(--g50)', borderRadius: 8 }}>
              <div style={{ fontSize: 10, textTransform: 'uppercase', letterSpacing: '.06em', color: 'var(--g500)', fontWeight: 600 }}>{m.label}</div>
              <div className="mono" style={{ fontSize: 18, fontWeight: 700, color: 'var(--g900)', marginTop: 4 }}>{m.value}</div>
              <div style={{ fontSize: 11, color: 'var(--g600)', marginTop: 2 }}>{m.delta}</div>
            </div>
          ))}
        </div>
      </div>

      {/* Notícias */}
      <div className="cc-card" style={{ marginBottom: 16 }}>
        <div className="cc-section-title" style={{ marginBottom: 12 }}>📰 Notícias do setor ({noticias.length})</div>
        {noticias.length === 0 && (
          <div style={{ padding: 24, textAlign: 'center', color: 'var(--g500)', fontSize: 13 }}>
            Nenhuma notícia carregada ainda — RSS roda a cada 1h e Claude search 1×/dia. Aguarde próximo ciclo.
          </div>
        )}
        {noticias.map(n => (
          <a key={n.id} href={n.link_externo} target="_blank" rel="noopener" style={{ display: 'block', padding: '10px 0', borderBottom: '1px solid var(--g100)', textDecoration: 'none', color: 'inherit' }}>
            <div style={{ display: 'flex', alignItems: 'baseline', gap: 8 }}>
              <span style={{ fontSize: 9, fontWeight: 700, letterSpacing: '.08em', textTransform: 'uppercase', color: sevColor(n.severidade), flexShrink: 0 }}>{n.severidade || 'info'}</span>
              <span style={{ fontSize: 11, color: 'var(--g500)', flexShrink: 0 }}>{n.fonte}</span>
              <span style={{ fontSize: 11, color: 'var(--g400)', marginLeft: 'auto', flexShrink: 0 }}>{n.publicado ? new Date(n.publicado).toLocaleDateString('pt-BR') : ''}</span>
            </div>
            <div style={{ fontSize: 13, fontWeight: 600, color: 'var(--g900)', marginTop: 2, lineHeight: 1.3 }}>{n.titulo}</div>
            {n.resumo && <div style={{ fontSize: 11, color: 'var(--g600)', marginTop: 3, lineHeight: 1.4 }}>{n.resumo.slice(0, 220)}{n.resumo.length > 220 ? '…' : ''}</div>}
          </a>
        ))}
      </div>

      <CCCacadorBacalhau/>
    </div>
  );
};

const CCCacadorBacalhau = () => {
  const [cep, setCep] = aUseState('');
  const [raio, setRaio] = aUseState(5);
  const [loading, setLoading] = aUseState(false);
  const [data, setData] = aUseState(null);
  const [error, setError] = aUseState(null);
  const buscar = async () => {
    setLoading(true); setError(null);
    try {
      const r = await fetch('/api/cc/cacador-bacalhau', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', Authorization: 'Bearer ' + (localStorage.getItem('nexus_token')||'') },
        body: JSON.stringify({ cep, raio_km: raio })
      }).then(r => r.json());
      if (!r.ok) { setError(r.error || 'falha'); }
      else { setData(r); }
    } catch (e) { setError(e.message); }
    setLoading(false);
  };
  const colorBucket = (b) => b === 'prospect_quente' ? '#dc2626' : b === 'reativacao' ? '#d97706' : b === 'cliente_lento' ? '#facc15' : '#16a34a';
  const labelBucket = (b) => b === 'prospect_quente' ? 'Prospect quente' : b === 'reativacao' ? 'Reativação (>180d)' : b === 'cliente_lento' ? 'Cliente lento' : 'Ativo';
  return (
    <div className="cc-card" style={{ background: 'linear-gradient(135deg, rgba(124, 58, 237, .04), rgba(124, 58, 237, .01))', border: '1px solid rgba(124, 58, 237, .2)' }}>
      <div className="cc-section-title" style={{ marginBottom: 6 }}>🐟 Caçador de Bacalhau</div>
      <div style={{ fontSize: 12, color: 'var(--g600)', marginBottom: 12 }}>
        Busca restaurantes/peixarias num raio do CEP, classifica em <b>prospect quente</b> / <b>reativação</b> / <b>ativo</b> baseado em base Brumar.
      </div>
      <div style={{ display: 'flex', gap: 8, alignItems: 'center', marginBottom: 12 }}>
        <input value={cep} onChange={e => setCep(e.target.value)} placeholder="CEP (ex: 06454-070)" style={{ padding: '6px 10px', borderRadius: 6, border: '1px solid var(--g300)', fontSize: 13, width: 160 }}/>
        <select value={raio} onChange={e => setRaio(Number(e.target.value))} style={{ padding: '6px 8px', borderRadius: 6, border: '1px solid var(--g300)', fontSize: 13 }}>
          <option value={1}>1 km</option><option value={3}>3 km</option><option value={5}>5 km</option><option value={10}>10 km</option><option value={15}>15 km</option>
        </select>
        <button onClick={buscar} disabled={!cep || loading} style={{ padding: '6px 14px', background: '#7c3aed', color: '#fff', border: 0, borderRadius: 6, fontSize: 13, cursor: 'pointer', fontWeight: 600 }}>
          {loading ? 'Buscando…' : 'Buscar'}
        </button>
      </div>
      {error && <div style={{ background: 'var(--red-l)', color: 'var(--red-d)', padding: '6px 10px', borderRadius: 6, fontSize: 12, marginBottom: 8 }}>Erro: {error}</div>}
      {data && (
        <div>
          <div style={{ display: 'flex', gap: 12, marginBottom: 12, fontSize: 12 }}>
            <span><b>{data.total}</b> lugares</span>
            <span style={{ color: '#dc2626' }}><b>{data.por_bucket.prospect_quente}</b> prospects quentes</span>
            <span style={{ color: '#d97706' }}><b>{data.por_bucket.reativacao}</b> reativação</span>
            <span style={{ color: '#16a34a' }}><b>{data.por_bucket.ativo}</b> ativos</span>
          </div>
          <div style={{ maxHeight: 400, overflowY: 'auto', border: '1px solid var(--g200)', borderRadius: 6 }}>
            {data.lugares.map(p => (
              <div key={p.place_id} style={{ padding: '8px 10px', borderBottom: '1px solid var(--g100)', fontSize: 12, display: 'flex', alignItems: 'center', gap: 8 }}>
                <span style={{ width: 10, height: 10, borderRadius: '50%', background: colorBucket(p.bucket), flexShrink: 0 }}/>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontWeight: 600, color: 'var(--g900)' }}>{p.nome} {p.cli_cod_brumar && <span style={{ background: '#dcfce7', color: '#166534', padding: '1px 6px', borderRadius: 4, fontSize: 10, fontWeight: 600, marginLeft: 4 }}>cli #{p.cli_cod_brumar}</span>}</div>
                  <div style={{ fontSize: 11, color: 'var(--g500)' }}>{p.endereco}</div>
                </div>
                <div style={{ fontSize: 11, color: 'var(--g600)', textAlign: 'right' }}>
                  <div>★ {p.rating ? p.rating.toFixed(1) : '—'} <span style={{ color: 'var(--g400)' }}>({p.user_rating_count || 0})</span></div>
                  <div style={{ fontWeight: 600, color: colorBucket(p.bucket) }}>{labelBucket(p.bucket)}</div>
                  {p.dias_ultima_compra != null && <div style={{ fontSize: 10, color: 'var(--g500)' }}>última: {p.dias_ultima_compra}d</div>}
                </div>
              </div>
            ))}
          </div>
          <div style={{ fontSize: 10, color: 'var(--g400)', marginTop: 8, fontStyle: 'italic' }}>{data.hint}</div>
        </div>
      )}
    </div>
  );
};

// Defaults fixos (modo de produção, sem painel Tweaks).
const CC_DEFAULTS = { layout: 'side', density: 'comfortable', anim: 'on', ticker: 'on' };

// Helper de fetch autenticado (token do localStorage do legacy: 'nexus_token').
async function ccFetch(path) {
  const token = localStorage.getItem('nexus_token') || localStorage.getItem('token') || '';
  const r = await fetch(path, { headers: token ? { Authorization: 'Bearer ' + token } : {} });
  if (!r.ok) throw new Error('HTTP ' + r.status);
  return r.json();
}

// Hook: carrega data real do backend (signals/insight/ticker) e merja com mock
// pra preservar partes ainda não-backed (clientes, mensagens, heatmapBairros).
function useCCData() {
  const [data, setData] = aUseState(window.CC_DATA);
  aUseEffect(() => {
    let live = true;
    Promise.all([
      ccFetch('/api/cc/signals?status=ativo&limit=50').catch(() => null),
      ccFetch('/api/cc/insight').catch(() => null),
      ccFetch('/api/cc/ticker').catch(() => null),
      ccFetch('/api/lembretes').catch(() => null),
    ]).then(([signalsR, insightR, tickerR, lembretesR]) => {
      if (!live) return;
      const next = { ...window.CC_DATA };
      if (signalsR && signalsR.ok && Array.isArray(signalsR.signals)) {
        // Backend retorna shape diferente do mock — transforma pro shape esperado pela UI
        next.signals = signalsR.signals.map(s => ({
          id: s.id,
          severity: s.severity,
          area: s.area,
          tipo: s.tipo,
          label: s.label,
          titulo: s.titulo,
          sub: s.sub,
          cliente: s.cli_cod ? { nome: (s.titulo || '').split(' reduziu')[0].split(' —')[0].split(' cresceu')[0], cnpj: s.cnpj || '', cidade: s.cidade || '', rep: s.rep || '' } : undefined,
          detectadoEm: relTime(s.detected_at),
          pulso: !!s.pulso,
          historico: s.historico || undefined,
          hipoteses: s.hipoteses || undefined,
          metadata: s.metadata || {},
        }));
      }
      if (insightR && insightR.ok && insightR.insight) {
        next.insight = insightR.insight;
      }
      if (tickerR && tickerR.ok && Array.isArray(tickerR.ticker)) {
        next.ticker = tickerR.ticker;
      }
      if (lembretesR && Array.isArray(lembretesR)) {
        next.lembretes = lembretesR;
      } else if (lembretesR && lembretesR.lembretes) {
        next.lembretes = lembretesR.lembretes;
      }
      // Sistema de mensagens ainda não definido — limpa mock pra mostrar placeholder
      next.mensagens = [];
      setData(next);
    }).catch(e => console.warn('[cc] fallback to mock:', e.message));
    return () => { live = false; };
  }, []);
  return data;
}

function relTime(iso) {
  if (!iso) return '—';
  const ms = Date.now() - new Date(iso).getTime();
  const h = Math.floor(ms / 3600000);
  if (h < 1) return 'agora';
  if (h < 24) return h + 'h atrás';
  return Math.floor(h / 24) + ' dias atrás';
}

const CCApp = () => {
  const data = useCCData();
  const [tab, setTab] = aUseState('overview');
  const [drillSignal, setDrillSignal] = aUseState(null);
  const [drillCliente, setDrillCliente] = aUseState(null);
  const [annotCtx, setAnnotCtx] = aUseState(null);
  const tweaks = CC_DEFAULTS; // sem painel de tweaks no legacy

  // Open helpers
  const openSignal = (s) => setDrillSignal(s);
  const openCliente = (c) => setDrillCliente(c);
  const openAnnot = (signal, cliente) => {
    setDrillSignal(null);
    setDrillCliente(null);
    setAnnotCtx({ signal, cliente });
  };

  return (
    <div className={tweaks.anim === 'off' ? 'no-anim' : ''} data-density={tweaks.density}>
      <div className="cc" data-screen-label="Command Center">
        <CCHeader tab={tab} onTab={setTab} ticker={tweaks.ticker === 'on' ? data.ticker : []}/>
        <div className="cc-body">
          {tab === 'overview' && (
            <CCOverview data={data} layout={tweaks.layout} onTab={setTab} onOpenSignal={openSignal}/>
          )}
          {tab === 'clientes' && (
            <CCClientes data={data} onOpenSignal={openSignal} onOpenCliente={openCliente}/>
          )}
          {tab === 'negocio' && <CCNegocio/>}
          {tab === 'reps'    && <CCReps/>}
          {tab === 'mercado' && <CCMercado/>}
        </div>
      </div>

      {drillSignal && (
        <CCSignalDrawer signal={drillSignal} data={data}
          onClose={() => setDrillSignal(null)}
          onOpenAnnot={(s, c) => openAnnot(s, c)}/>
      )}
      {drillCliente && (
        <CCClienteDrawer cliente={drillCliente} data={data}
          onClose={() => setDrillCliente(null)}
          onOpenAnnot={(s, c) => openAnnot(s, c)}/>
      )}
      {annotCtx && (
        <CCAnnotDrawer context={annotCtx} onClose={() => setAnnotCtx(null)}/>
      )}
    </div>
  );
};

// === Bridge pro legacy: expõe mountCommandCenter no window. ===
window.mountCommandCenter = function(el) { return ReactDOM.createRoot(el).render(<CCApp/>); };

})();
