/* ================================================================
   Tracker FMN — Funis v3
   Sala de controle do quiz Fotógrafo Protegido.
   Pizza padrão interativa, abandono e série refeitos, métricas e
   cruzamentos, comparação com período anterior e insight do dia.
   ================================================================ */
const { useState, useEffect } = React;
const { LucideIcon, CardKPI, SectionCard, TopBar } = window;

const nf = n => (n == null ? '—' : Number(n).toLocaleString('pt-BR'));
const pc = (a, b) => (b ? Math.round((a / b) * 100) : 0);
const PALETTE = ['#eaaa41', '#60a5fa', '#4ade80', '#f472b6', '#a78bfa', '#34d399', '#fbbf24', '#f87171'];
const DOW = ['Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sáb'];

const PERIODOS = [
  { id: 'tudo', label: 'Tudo', dias: null },
  { id: '12m', label: '12 meses', dias: 365 },
  { id: '30d', label: '30 dias', dias: 30 },
  { id: '7d', label: '7 dias', dias: 7 },
];
function rangeFromPeriodo(dias) {
  if (!dias) return { p_from: null, p_to: null };
  const to = new Date(); const from = new Date(); from.setDate(from.getDate() - dias);
  const iso = d => d.toISOString().slice(0, 10);
  return { p_from: iso(from), p_to: iso(to) };
}

/* ── arco de rosca ── */
function arcPath(cx, cy, R, r, a0, a1) {
  const p = (a, rad) => [cx + rad * Math.cos(a), cy + rad * Math.sin(a)];
  const large = (a1 - a0) > Math.PI ? 1 : 0;
  const [x0, y0] = p(a0, R), [x1, y1] = p(a1, R), [x2, y2] = p(a1, r), [x3, y3] = p(a0, r);
  return `M${x0},${y0} A${R},${R} 0 ${large} 1 ${x1},${y1} L${x2},${y2} A${r},${r} 0 ${large} 0 ${x3},${y3} Z`;
}

function Donut({ items, hov, setHov }) {
  const data = (items || []).slice(0, 8);
  const sum = data.reduce((a, b) => a + b.n, 0) || 1;
  const R = 92, r = 52, cx = 100, cy = 100;
  let ang = -Math.PI / 2;
  const slices = data.map((it, i) => {
    const frac = it.n / sum, a0 = ang, a1 = ang + frac * 2 * Math.PI; ang = a1;
    const mid = (a0 + a1) / 2, lr = (R + r) / 2;
    return { ...it, i, a0, a1, frac, lx: cx + lr * Math.cos(mid), ly: cy + lr * Math.sin(mid) };
  });
  return (
    <svg viewBox="0 0 200 200" style={{ width: 200, height: 200, flexShrink: 0 }}>
      {slices.map(s => {
        const dim = hov != null && hov !== s.i;
        return (
          <path key={s.i} d={arcPath(cx, cy, R, r, s.a0, s.a1)}
            fill={PALETTE[s.i % PALETTE.length]} opacity={dim ? 0.28 : 1}
            stroke="var(--app-surface)" strokeWidth="2" style={{ transition: 'opacity .15s', cursor: 'default' }}
            onMouseEnter={() => setHov(s.i)} onMouseLeave={() => setHov(null)} />
        );
      })}
      {slices.filter(s => s.frac >= 0.07).map(s => (
        <text key={'t' + s.i} x={s.lx} y={s.ly} textAnchor="middle" dominantBaseline="central"
          style={{ fontSize: 13, fontWeight: 800, fontFamily: 'Roboto,sans-serif', fill: '#1a1a1a', pointerEvents: 'none' }}>
          {Math.round(s.frac * 100)}%
        </text>
      ))}
      <text x={cx} y={cy - 6} textAnchor="middle" style={{ fontSize: 17, fontWeight: 900, fontFamily: 'Roboto,sans-serif', fill: 'var(--text-1)' }}>{nf(sum)}</text>
      <text x={cx} y={cy + 12} textAnchor="middle" style={{ fontSize: 9, fontFamily: 'Roboto,sans-serif', fill: 'var(--text-3)' }}>menções</text>
    </svg>
  );
}

/* ── card com troca pizza/barras (tamanho fixo, cores sincronizadas) ── */
function VizCard({ title, hint, items, total }) {
  const [view, setView] = useState('pizza');
  const [hov, setHov] = useState(null);
  const data = (items || []).slice(0, 8);
  const sum = data.reduce((a, b) => a + b.n, 0) || 1;
  const base = total || sum;
  const max = Math.max(1, ...data.map(i => i.n));
  const Toggle = ({ id, icon }) => (
    <button onClick={() => setView(id)} title={id === 'pizza' ? 'Pizza' : 'Barras'}
      style={{ width: 27, height: 24, borderRadius: 6, display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer',
        background: view === id ? 'rgba(234,170,65,.15)' : 'transparent',
        border: `1px solid ${view === id ? 'rgba(234,170,65,.3)' : 'var(--app-border)'}`,
        color: view === id ? 'var(--fmn-gold)' : 'var(--text-3)' }}>
      <LucideIcon icon={icon} size={13} /></button>
  );
  return (
    <SectionCard title={title}
      headerRight={<div style={{ display: 'flex', gap: 4 }}><Toggle id="pizza" icon="pie-chart" /><Toggle id="bar" icon="bar-chart-3" /></div>}>
      {hint && <div style={{ fontSize: 10.5, color: 'var(--text-3)', fontFamily: 'Roboto,sans-serif', marginTop: -4, marginBottom: 6 }}>{hint}</div>}
      <div style={{ minHeight: 212 }}>
        {!data.length ? <div style={{ padding: '40px 0', textAlign: 'center', color: 'var(--text-3)', fontSize: 11.5 }}>Sem dados no período.</div>
          : view === 'pizza' ? (
            <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
              <Donut items={data} hov={hov} setHov={setHov} />
              <div style={{ flex: 1, display: 'flex', flexDirection: 'column', gap: 4, minWidth: 0 }}>
                {data.map((it, i) => (
                  <div key={i} onMouseEnter={() => setHov(i)} onMouseLeave={() => setHov(null)}
                    style={{ display: 'flex', alignItems: 'center', gap: 7, fontSize: 11.5, opacity: hov != null && hov !== i ? 0.4 : 1, transition: 'opacity .15s' }}>
                    <span style={{ width: 10, height: 10, borderRadius: 3, background: PALETTE[i % PALETTE.length], flexShrink: 0 }} />
                    <span title={it.val} style={{ flex: 1, color: 'var(--text-2)', fontFamily: 'Roboto,sans-serif', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{it.val}</span>
                    <span style={{ fontWeight: 900, color: 'var(--text-1)', fontFamily: 'Roboto,sans-serif' }}>{Math.round(it.n / sum * 100)}%</span>
                  </div>
                ))}
              </div>
            </div>
          ) : (
            <div style={{ display: 'flex', flexDirection: 'column', justifyContent: 'center', height: '100%' }}>
              {data.map((it, i) => (
                <div key={i} onMouseEnter={() => setHov(i)} onMouseLeave={() => setHov(null)}
                  style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '4px 0', opacity: hov != null && hov !== i ? 0.4 : 1, transition: 'opacity .15s' }}>
                  <div style={{ width: 150, flexShrink: 0, fontSize: 11, color: 'var(--text-2)', fontFamily: 'Roboto,sans-serif', overflow: 'hidden', whiteSpace: 'nowrap', textOverflow: 'ellipsis' }} title={it.val}>{it.val}</div>
                  <div style={{ flex: 1, height: 16, background: 'rgba(255,255,255,.04)', borderRadius: 5, overflow: 'hidden' }}>
                    <div style={{ width: Math.max(3, it.n / max * 100) + '%', height: '100%', background: PALETTE[i % PALETTE.length], borderRadius: 5 }} /></div>
                  <div style={{ width: 78, textAlign: 'right' }}>
                    <span style={{ fontSize: 14, fontWeight: 900, color: 'var(--text-1)', fontFamily: 'Roboto,sans-serif' }}>{Math.round(it.n / base * 100)}%</span>
                    <span style={{ fontSize: 9.5, color: 'var(--text-3)', marginLeft: 4 }}>{nf(it.n)}</span>
                  </div>
                </div>
              ))}
            </div>
          )}
      </div>
    </SectionCard>
  );
}

/* ── barra simples com cor ── */
function Bar({ label, n, max, pctVal, color, sub }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '5px 0' }}>
      <div style={{ width: 160, flexShrink: 0, fontSize: 11.5, color: 'var(--text-2)', fontFamily: 'Roboto,sans-serif', lineHeight: 1.3, overflow: 'hidden', display: '-webkit-box', WebkitLineClamp: 2, WebkitBoxOrient: 'vertical' }}>{label}</div>
      <div style={{ flex: 1, height: 16, background: 'rgba(255,255,255,.04)', borderRadius: 5, overflow: 'hidden' }}>
        <div style={{ width: Math.max(3, (n / max) * 100) + '%', height: '100%', background: color || 'var(--fmn-gold)', borderRadius: 5 }} /></div>
      <div style={{ width: 84, textAlign: 'right', fontFamily: 'Roboto,sans-serif' }}>
        <span style={{ fontSize: 13, fontWeight: 900, color: 'var(--text-1)' }}>{pctVal != null ? pctVal + '%' : nf(n)}</span>
        {sub && <span style={{ fontSize: 9.5, color: 'var(--text-3)', marginLeft: 4 }}>{sub}</span>}
      </div>
    </div>
  );
}

/* ── abandono refeito ── */
function FunnelRow({ it, prev, max, biggest }) {
  const [hov, setHov] = useState(false);
  const retain = pc(it.n, max);
  const drop = prev ? prev.n - it.n : 0;
  const dropPct = prev ? pc(drop, prev.n) : 0;
  const isCap = it.etapa === 'Captura de e-mail';
  const isBig = biggest && it.etapa === biggest;
  return (
    <div style={{ position: 'relative' }} onMouseEnter={() => setHov(true)} onMouseLeave={() => setHov(false)}>
      {hov && (
        <div style={{ position: 'absolute', bottom: '100%', left: 0, zIndex: 50, marginBottom: 6, width: 340, background: '#0c0d11', border: '1px solid var(--app-border-2)', borderRadius: 10, padding: '11px 13px', boxShadow: '0 12px 40px rgba(0,0,0,.55)' }}>
          <div style={{ fontSize: 12.5, fontWeight: 700, color: 'var(--text-1)', fontFamily: 'Roboto,sans-serif', lineHeight: 1.4, marginBottom: 5 }}>{it.pergunta}</div>
          <div style={{ fontSize: 11, color: 'var(--text-2)', fontFamily: 'Roboto,sans-serif', lineHeight: 1.5 }}>
            {nf(it.n)} chegaram aqui · {retain}% do início{prev && drop > 0 && <span style={{ color: 'var(--clr-neg)' }}> · caíram {nf(drop)} ({dropPct}%) vindo de “{prev.etapa}”</span>}
          </div>
        </div>
      )}
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '4px 0' }}>
        <div style={{ width: 150, flexShrink: 0, fontSize: 12, fontFamily: 'Roboto,sans-serif', color: hov ? 'var(--fmn-gold)' : 'var(--text-2)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', cursor: 'help' }}>{it.etapa}</div>
        <div style={{ flex: 1, height: 20, background: 'rgba(255,255,255,.04)', borderRadius: 5, overflow: 'hidden', position: 'relative' }}>
          <div style={{ width: retain + '%', height: '100%', background: isCap ? 'var(--clr-teal)' : 'var(--fmn-gold)', borderRadius: 5, transition: 'width .4s' }} />
        </div>
        <div style={{ width: 42, textAlign: 'right', fontSize: 13, fontWeight: 900, color: 'var(--text-1)', fontFamily: 'Roboto,sans-serif' }}>{retain}%</div>
        <div style={{ width: 96, textAlign: 'right', fontSize: 10.5, fontFamily: 'Roboto,sans-serif', color: isBig ? 'var(--clr-neg)' : 'var(--text-3)', fontWeight: isBig ? 700 : 400 }}>
          {prev ? (drop > 0 ? `↓ ${dropPct}%${isBig ? ' ◀ maior' : ''}` : '—') : 'início'}
        </div>
      </div>
    </div>
  );
}
function FunnelChart({ items }) {
  if (!items || !items.length) return null;
  const max = items[0].n;
  let biggest = null, bd = -1;
  items.forEach((it, i) => { if (i > 0) { const d = items[i - 1].n - it.n; if (d > bd) { bd = d; biggest = it.etapa; } } });
  const lead = items[items.length - 1].n;
  return (
    <div style={{ background: 'var(--app-surface)', borderRadius: 14, padding: '12px 18px 16px', overflow: 'visible' }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 2 }}>
        <span style={{ fontSize: 12.5, fontFamily: 'Roboto,sans-serif', fontWeight: 700, color: 'var(--text-1)' }}>Abandono por etapa</span>
        <span style={{ fontSize: 11, color: 'var(--text-2)', fontFamily: 'Roboto,sans-serif' }}>do início até virar lead você retém <b style={{ color: 'var(--clr-teal)' }}>{pc(lead, max)}%</b></span>
      </div>
      <div style={{ fontSize: 10.5, color: 'var(--text-3)', fontFamily: 'Roboto,sans-serif', marginBottom: 8 }}>passe o mouse na etapa para ver a pergunta completa</div>
      {items.map((it, i) => <FunnelRow key={i} it={it} prev={items[i - 1]} max={max} biggest={biggest} />)}
    </div>
  );
}

/* ── série temporal em colunas ── */
function SeriesChart({ serie }) {
  const data = serie || [];
  const max = Math.max(1, ...data.map(d => d.leads));
  return (
    <SectionCard title="Leads ao longo do tempo">
      <div style={{ fontSize: 10.5, color: 'var(--text-3)', fontFamily: 'Roboto,sans-serif', marginTop: -4, marginBottom: 10 }}>barra cheia = respostas · parte dourada = viraram e-mail</div>
      <div style={{ display: 'flex', alignItems: 'flex-end', gap: data.length > 16 ? 2 : 6, height: 150, paddingTop: 8 }}>
        {data.map((d, i) => (
          <div key={i} title={`${d.rotulo}: ${nf(d.leads)} respostas, ${nf(d.com_email)} e-mails`}
            style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4, minWidth: 0 }}>
            <div style={{ width: '100%', maxWidth: 26, height: 120, display: 'flex', alignItems: 'flex-end', position: 'relative' }}>
              <div style={{ width: '100%', height: (d.leads / max * 100) + '%', background: 'rgba(96,165,250,.35)', borderRadius: '4px 4px 0 0', position: 'relative' }}>
                <div style={{ position: 'absolute', bottom: 0, width: '100%', height: pc(d.com_email, d.leads) + '%', background: 'var(--fmn-gold)', borderRadius: d.com_email === d.leads ? '4px 4px 0 0' : 0 }} />
              </div>
            </div>
            <span style={{ fontSize: 8.5, color: 'var(--text-3)', fontFamily: 'Roboto,sans-serif', whiteSpace: 'nowrap', transform: data.length > 12 ? 'rotate(-45deg)' : 'none', transformOrigin: 'center' }}>{d.rotulo}</span>
          </div>
        ))}
      </div>
    </SectionCard>
  );
}

/* ── insight do dia ── */
function InsightCard({ onNavigate }) {
  const [ins, setIns] = useState(null);
  const [busy, setBusy] = useState(false);
  useEffect(() => {
    if (!window.db) return;
    window.db.from('quiz_insights').select('*').order('dia', { ascending: false }).limit(1)
      .then(({ data }) => { if (data && data[0]) setIns(data[0]); });
  }, []);
  if (!ins) return null;
  const usar = async () => {
    setBusy(true);
    try {
      await window.db.from('ideias').insert({ title: ins.titulo, description: (ins.gancho || '') + (ins.detalhe ? '\n\n' + ins.detalhe : ''), status: 'Ideia', formats: ins.formato ? [ins.formato] : [] });
      await window.db.from('quiz_insights').update({ usado: true }).eq('id', ins.id);
    } catch (e) { console.warn(e); }
    setBusy(false);
    if (onNavigate) onNavigate('ideias');
  };
  return (
    <div style={{ background: 'linear-gradient(100deg, rgba(234,170,65,.14), rgba(234,170,65,.04))', border: '1px solid rgba(234,170,65,.3)', borderRadius: 14, padding: '14px 18px', display: 'flex', alignItems: 'center', gap: 16 }}>
      <div style={{ width: 38, height: 38, borderRadius: 10, background: 'rgba(234,170,65,.18)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}><LucideIcon icon="lightbulb" size={20} color="var(--fmn-gold)" /></div>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontSize: 10, fontWeight: 700, letterSpacing: '.12em', textTransform: 'uppercase', color: 'var(--fmn-gold)', fontFamily: 'Roboto,sans-serif' }}>Insight do dia</div>
        <div style={{ fontSize: 13.5, fontWeight: 700, color: 'var(--text-1)', fontFamily: 'Roboto,sans-serif', margin: '2px 0' }}>{ins.titulo}</div>
        <div style={{ fontSize: 11.5, color: 'var(--text-2)', fontFamily: 'Roboto,sans-serif', lineHeight: 1.45 }}>{ins.gancho}</div>
      </div>
      <button onClick={usar} disabled={busy}
        style={{ flexShrink: 0, background: 'var(--fmn-gold)', color: '#1a1a1a', border: 'none', borderRadius: 9, padding: '10px 16px', fontFamily: 'Roboto,sans-serif', fontWeight: 700, fontSize: 12, cursor: 'pointer', display: 'flex', alignItems: 'center', gap: 6 }}>
        <LucideIcon icon="arrow-right" size={14} />{ins.usado ? 'Enviar de novo' : 'Usar essa ideia'}
      </button>
    </div>
  );
}

/* ── tabela cruzada compacta ── */
function CrossList({ title, hint, rows, render, color }) {
  return (
    <SectionCard title={title}>
      {hint && <div style={{ fontSize: 10.5, color: 'var(--text-3)', fontFamily: 'Roboto,sans-serif', marginTop: -4, marginBottom: 6 }}>{hint}</div>}
      {(!rows || !rows.length) ? <div style={{ padding: '16px 0', textAlign: 'center', color: 'var(--text-3)', fontSize: 11.5 }}>Sem dados.</div> : rows.map(render)}
    </SectionCard>
  );
}

function FunisScreen({ onNavigate }) {
  const [periodo, setPeriodo] = useState('tudo');
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  useEffect(() => {
    if (!window.db) return;
    setLoading(true);
    const { p_from, p_to } = rangeFromPeriodo(PERIODOS.find(p => p.id === periodo).dias);
    window.db.rpc('quiz_funis_dashboard', { p_from, p_to }).then(({ data, error }) => { if (!error) setData(data); setLoading(false); });
  }, [periodo]);

  const k = data?.kpis || {};
  const total = k.total || 0;
  const taxa = pc(k.com_email, total);
  const periodoTxt = k.periodo_min ? `${k.periodo_min.slice(0, 10).split('-').reverse().join('/')} a ${k.periodo_max.slice(0, 10).split('-').reverse().join('/')}` : '—';
  const dTotal = k.prev_total ? total - k.prev_total : undefined;
  const dLeads = k.prev_com_email ? (k.com_email || 0) - k.prev_com_email : undefined;
  const secTitle = t => <div style={{ fontSize: 12.5, fontFamily: 'Roboto,sans-serif', fontWeight: 700, color: 'var(--text-1)', marginTop: 6 }}>{t}</div>;

  return (
    <div style={{ display: 'flex', flexDirection: 'column', height: '100%', overflow: 'hidden' }}>
      <TopBar title="Funis · Fotógrafo Protegido"
        actions={<div style={{ display: 'flex', gap: 4, padding: 3, borderRadius: 8, background: 'rgba(255,255,255,.04)', border: '1px solid var(--app-border)' }}>
          {PERIODOS.map(p => (<button key={p.id} onClick={() => setPeriodo(p.id)}
            style={{ padding: '5px 11px', borderRadius: 6, cursor: 'pointer', background: periodo === p.id ? 'rgba(234,170,65,.15)' : 'transparent', border: `1px solid ${periodo === p.id ? 'rgba(234,170,65,.2)' : 'transparent'}`, color: periodo === p.id ? 'var(--fmn-gold)' : 'rgba(255,255,255,.42)', fontFamily: 'Roboto,sans-serif', fontWeight: 700, fontSize: 11 }}>{p.label}</button>))}
        </div>} />

      <div style={{ flex: 1, overflowY: 'auto', padding: '18px 24px', display: 'flex', flexDirection: 'column', gap: 16, minHeight: 0 }}>
        {loading && <div style={{ padding: '60px 0', textAlign: 'center', color: 'var(--text-3)', fontSize: 13 }}><LucideIcon icon="loader" size={22} /><div style={{ marginTop: 8 }}>Carregando dados...</div></div>}
        {!loading && data && (<>
          <InsightCard onNavigate={onNavigate} />

          <div style={{ display: 'flex', gap: 12 }}>
            <CardKPI label="Total de respostas" value={nf(total)} icon="users" accent delta={dTotal} deltaLabel="vs período anterior" />
            <CardKPI label="Leads com e-mail" value={nf(k.com_email)} icon="mail" delta={dLeads} deltaLabel="vs período anterior" />
            <CardKPI label="Taxa de captura" value={taxa + '%'} icon="target" />
            <CardKPI label="Período" value={periodoTxt} icon="calendar" />
          </div>

          <div style={{ display: 'grid', gridTemplateColumns: '1.3fr 1fr', gap: 16, alignItems: 'start' }}>
            <FunnelChart items={data.abandono || []} />
            <SeriesChart serie={data.serie} />
          </div>

          {secTitle('Pesquisa de público (voz do cliente, troque entre pizza e barras no canto)')}
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16, alignItems: 'start' }}>
            <VizCard title="Dores mais vividas" hint="situações que já passaram" items={data.dores} total={total} />
            <VizCard title="Sentimentos" hint="o que sentem no dia a dia" items={data.sentimentos} total={total} />
            <VizCard title="Lacunas de conhecimento" hint="temas jurídicos que marcaram" items={data.temas} total={total} />
            <VizCard title="Percepção de custo de um processo" items={data.custo} total={total} />
            <VizCard title="Área de atuação" items={data.area} total={total} />
            <VizCard title="Usa contrato?" items={data.usa_contrato} total={total} />
          </div>

          {secTitle('Risco e intenção de compra')}
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16, alignItems: 'start' }}>
            <VizCard title="Nível de risco do público" items={data.risco} total={total} />
            <VizCard title="Intenção de compra" hint="o quão quente está o público" items={data.intencao} total={total} />
            <CrossList title="Conversão em lead por resposta-chave" hint="quem deixa e-mail conforme usa contrato"
              rows={(data.conversao_resposta || []).slice().sort((a, b) => pc(b.leads, b.total) - pc(a.leads, a.total))}
              render={(r, i) => <Bar key={i} label={r.val} n={pc(r.leads, r.total)} max={100} pctVal={pc(r.leads, r.total)} sub={`${nf(r.leads)}/${nf(r.total)}`} color="var(--clr-teal)" />} />
            <CrossList title="Risco × intenção de compra" hint="quem está em risco quer os modelos?"
              rows={(data.cross_risco_intencao || []).filter(r => r.intencao === 'Totalmente, manda logo pra cá!').sort((a, b) => b.n - a.n)}
              render={(r, i) => <Bar key={i} label={r.risco} n={r.n} max={Math.max(1, ...(data.cross_risco_intencao || []).map(x => x.n))} pctVal={null} sub="muito quentes" color="#f87171" />} />
          </div>

          {secTitle('Ângulos de copy (insights de venda)')}
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16, alignItems: 'start' }}>
            <SectionCard title="Contradição reveladora">
              <div style={{ fontSize: 10.5, color: 'var(--text-3)', marginTop: -4, marginBottom: 10 }}>dizem que usam contrato sempre, mas não dominam nada ou usam só Word</div>
              <div style={{ textAlign: 'center', padding: '6px 0 12px' }}>
                <div style={{ fontSize: 38, fontWeight: 900, color: 'var(--clr-neg)', fontFamily: 'Roboto,sans-serif', lineHeight: 1 }}>{pc(data.contradicao?.contradizem, data.contradicao?.total_usa_sempre)}%</div>
                <div style={{ fontSize: 12, color: 'var(--text-2)', marginTop: 6 }}>de {nf(data.contradicao?.total_usa_sempre)} que dizem "uso sempre" estão com falsa sensação de proteção</div>
              </div>
            </SectionCard>
            <CrossList title="Lacuna jurídica × profissionalização" hint="% que não domina nenhum tema, por grupo"
              rows={(data.lacuna_prof || [])}
              render={(r, i) => <Bar key={i} label={r.grupo} n={pc(r.nenhum, r.total)} max={100} pctVal={pc(r.nenhum, r.total)} sub={`${nf(r.nenhum)}/${nf(r.total)}`} color="var(--clr-warn)" />} />
            <CrossList title="Dor × sentimento mais comuns" hint="combinações que mais se repetem"
              rows={(data.cross_dor_sentimento || [])}
              render={(r, i) => <Bar key={i} label={`${r.dor} + ${r.sent}`} n={r.n} max={Math.max(1, ...(data.cross_dor_sentimento || []).map(x => x.n))} pctVal={null} sub={nf(r.n)} color="#a78bfa" />} />
            <CrossList title="Top dores por área" hint="o que mais dói em cada perfil"
              rows={(data.dores_por_area || [])}
              render={(r, i) => <Bar key={i} label={`[${r.area.split(' ')[0]}] ${r.dor}`} n={r.n} max={Math.max(1, ...(data.dores_por_area || []).map(x => x.n))} pctVal={null} sub={nf(r.n)} color="var(--clr-neg)" />} />
          </div>

          {secTitle('Aquisição e timing')}
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16, alignItems: 'start' }}>
            <VizCard title="Dispositivo" hint="de onde respondem" items={data.dispositivo} total={total} />
            <CrossList title="Quando os leads chegam (dia)" hint="respostas por dia da semana"
              rows={(data.chegada_dia || [])}
              render={(r, i) => <Bar key={i} label={DOW[r.dow]} n={r.n} max={Math.max(1, ...(data.chegada_dia || []).map(x => x.n))} pctVal={null} sub={nf(r.n)} color="var(--clr-info)" />} />
            <CrossList title="Horário de pico" hint="respostas por hora do dia"
              rows={(data.chegada_hora || []).slice().sort((a, b) => b.n - a.n).slice(0, 8)}
              render={(r, i) => <Bar key={i} label={`${String(r.hora).padStart(2, '0')}h`} n={r.n} max={Math.max(1, ...(data.chegada_hora || []).map(x => x.n))} pctVal={null} sub={nf(r.n)} color="var(--clr-info)" />} />
            <CrossList title="Campanhas por qualidade" hint="leads e % de alto risco (mais propensos a comprar)"
              rows={(data.campanha_qualidade || [])}
              render={(r, i) => <Bar key={i} label={r.campanha} n={r.leads} max={Math.max(1, ...(data.campanha_qualidade || []).map(x => x.leads))} pctVal={null} sub={`${nf(r.leads)} · ${pc(r.alto, r.leads)}% alto risco`} color="var(--fmn-gold)" />} />
          </div>

          <div style={{ fontSize: 10.5, color: 'var(--text-3)', fontFamily: 'Roboto,sans-serif', textAlign: 'center', padding: '4px 0 8px' }}>
            Base histórica do inLead + novos leads da vitrine própria. Todos os blocos respeitam o filtro de período acima.
          </div>
        </>)}
      </div>
    </div>
  );
}

window.FunisScreen = FunisScreen;
