// gm-dataviz.jsx — Dados & Gráficos. Metodologia + gráficos em paleta + right/wrong.
// Exports: GMDataviz.

/* ── chart primitives (SVG, paleta da marca) ─────────────────────────────── */
function BarChart({ data, h = 172, fmt = (v) => v, baseline = 0 }) {
  const vbW = 320, vbH = h, padB = 26, padT = 22, padX = 12;
  const max = Math.max(...data.map((d) => d.value));
  const span = max - baseline;
  const n = data.length, gap = (vbW - padX * 2) / n, bw = gap * 0.58;
  return (
    <svg viewBox={`0 0 ${vbW} ${vbH}`} width="100%" style={{ display: "block" }}>
      {data.map((d, i) => {
        const bh = ((d.value - baseline) / span) * (vbH - padT - padB);
        const x = padX + gap * i + (gap - bw) / 2, y = vbH - padB - bh;
        const col = d.hl ? T.coral : T.taupe;
        return (
          <g key={i}>
            <rect x={x} y={y} width={bw} height={Math.max(bh, 1)} rx="3" fill={col} />
            <text x={x + bw / 2} y={y - 6} textAnchor="middle" fontFamily={F.mono} fontSize="10.5" fill={d.hl ? T.coral : T.sub} fontWeight="600">{fmt(d.value)}</text>
            <text x={x + bw / 2} y={vbH - padB + 14} textAnchor="middle" fontFamily={F.text} fontSize="10.5" fill={T.sub}>{d.label}</text>
          </g>
        );
      })}
      <line x1={padX} y1={vbH - padB} x2={vbW - padX} y2={vbH - padB} stroke={T.line2} strokeWidth="1" />
    </svg>
  );
}

function LineChart({ series, labels, h = 180, color = T.coral, area = true }) {
  const vbW = 320, vbH = h, padX = 16, padT = 18, padB = 24;
  const max = Math.max(...series), min = Math.min(...series, 0);
  const n = series.length;
  const X = (i) => padX + (i / (n - 1)) * (vbW - padX * 2);
  const Y = (v) => padT + (1 - (v - min) / (max - min)) * (vbH - padT - padB);
  const pts = series.map((v, i) => `${X(i)},${Y(v)}`).join(" ");
  const areaPts = `${padX},${vbH - padB} ${pts} ${vbW - padX},${vbH - padB}`;
  return (
    <svg viewBox={`0 0 ${vbW} ${vbH}`} width="100%" style={{ display: "block" }}>
      {[0.25, 0.5, 0.75].map((f, i) => <line key={i} x1={padX} y1={padT + f * (vbH - padT - padB)} x2={vbW - padX} y2={padT + f * (vbH - padT - padB)} stroke={T.line} strokeWidth="0.8" />)}
      <line x1={padX} y1={vbH - padB} x2={vbW - padX} y2={vbH - padB} stroke={T.line2} strokeWidth="1" />
      {area && <polygon points={areaPts} fill={color} opacity="0.1" />}
      <polyline points={pts} fill="none" stroke={color} strokeWidth="2.5" strokeLinejoin="round" strokeLinecap="round" />
      <circle cx={X(n - 1)} cy={Y(series[n - 1])} r="4" fill={color} />
      <text x={X(n - 1)} y={Y(series[n - 1]) - 9} textAnchor="end" fontFamily={F.mono} fontSize="11" fontWeight="600" fill={color}>{series[n - 1]}</text>
      {labels && labels.map((l, i) => <text key={i} x={X(i)} y={vbH - padB + 14} textAnchor="middle" fontFamily={F.text} fontSize="10" fill={T.sub}>{l}</text>)}
    </svg>
  );
}

function Donut({ segs, size = 150 }) {
  const total = segs.reduce((a, s) => a + s.value, 0);
  const r = 52, C = 2 * Math.PI * r;
  let acc = 0;
  const top = segs.reduce((a, b) => (b.value > a.value ? b : a), segs[0]);
  return (
    <svg viewBox="0 0 140 140" width={size} height={size} style={{ display: "block" }}>
      <g transform="translate(70,70) rotate(-90)">
        <circle r={r} fill="none" stroke={T.panel} strokeWidth="20" />
        {segs.map((s, i) => {
          const frac = s.value / total, dash = frac * C;
          const el = <circle key={i} r={r} fill="none" stroke={s.color} strokeWidth="20" strokeDasharray={`${dash} ${C - dash}`} strokeDashoffset={-acc} />;
          acc += dash; return el;
        })}
      </g>
      <text x="70" y="66" textAnchor="middle" fontFamily={F.display} fontWeight="800" fontSize="26" fill={T.ink}>{Math.round((top.value / total) * 100)}%</text>
      <text x="70" y="84" textAnchor="middle" fontFamily={F.mono} fontSize="9" fill={T.sub} letterSpacing="0.5">{top.label.toUpperCase()}</text>
    </svg>
  );
}

function Scatter({ points, h = 180 }) {
  const vbW = 300, vbH = h, p = 22;
  const X = (x) => p + x * (vbW - p * 2), Y = (y) => (vbH - p) - y * (vbH - p * 2);
  return (
    <svg viewBox={`0 0 ${vbW} ${vbH}`} width="100%" style={{ display: "block" }}>
      <line x1={p} y1={p} x2={p} y2={vbH - p} stroke={T.line2} strokeWidth="1" />
      <line x1={p} y1={vbH - p} x2={vbW - p} y2={vbH - p} stroke={T.line2} strokeWidth="1" />
      {points.map((pt, i) => <circle key={i} cx={X(pt.x)} cy={Y(pt.y)} r={pt.hl ? 7 : 5} fill={pt.hl ? T.coral : T.cyan} opacity={pt.hl ? 1 : 0.55} />)}
    </svg>
  );
}

function Pipeline({ stages }) {
  const max = stages[0].value;
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 9, width: "100%" }}>
      {stages.map((s, i) => (
        <div key={i} style={{ display: "flex", alignItems: "center", gap: 12 }}>
          <div style={{ width: 76, fontFamily: F.text, fontWeight: 600, fontSize: 12.5, textAlign: "right", flexShrink: 0, color: T.ink }}>{s.label}</div>
          <div style={{ flex: 1, height: 26, background: T.panel, borderRadius: 6, overflow: "hidden" }}>
            <div style={{ width: `${(s.value / max) * 100}%`, height: "100%", background: i === stages.length - 1 ? T.coral : T.clay, borderRadius: 6, display: "flex", alignItems: "center", paddingLeft: 9 }}>
              <span style={{ fontFamily: F.mono, fontSize: 10.5, color: T.card, fontWeight: 600 }}>{s.value.toLocaleString("pt-BR")}</span>
            </div>
          </div>
        </div>
      ))}
    </div>
  );
}

function DataTable() {
  const rows = [["Ingestão", "1,2 M", "+8%", true], ["Embeddings", "980 k", "+4%", false], ["Falhas", "320", "−12%", false]];
  return (
    <table style={{ width: "100%", borderCollapse: "collapse", fontFamily: F.text }}>
      <thead>
        <tr style={{ borderBottom: `2px solid ${T.ink}` }}>
          {["Etapa", "Volume", "Δ semana"].map((h, i) => (
            <th key={i} style={{ textAlign: i === 0 ? "left" : "right", padding: "8px 10px", fontFamily: F.mono, fontSize: 10, letterSpacing: 1, textTransform: "uppercase", color: T.sub, fontWeight: 600 }}>{h}</th>
          ))}
        </tr>
      </thead>
      <tbody>
        {rows.map(([etapa, vol, delta, hl], i) => (
          <tr key={i} style={{ borderBottom: `1px solid ${T.line}`, background: hl ? "rgba(232,85,58,0.06)" : "transparent" }}>
            <td style={{ padding: "9px 10px", fontWeight: hl ? 700 : 500, fontSize: 13.5 }}>{etapa}</td>
            <td style={{ padding: "9px 10px", textAlign: "right", fontFamily: F.mono, fontSize: 13, fontVariantNumeric: "tabular-nums" }}>{vol}</td>
            <td style={{ padding: "9px 10px", textAlign: "right", fontFamily: F.mono, fontSize: 13, color: delta.startsWith("−") ? T.teal : T.clay, fontVariantNumeric: "tabular-nums" }}>{delta}</td>
          </tr>
        ))}
      </tbody>
    </table>
  );
}

/* ── section ─────────────────────────────────────────────────────────────── */
function GMDataviz() {
  const Principle = ({ n, t, d }) => (
    <Card>
      <div style={{ fontFamily: F.display, fontWeight: 800, fontSize: 34, color: T.coral, letterSpacing: -1, lineHeight: 1 }}>{n}</div>
      <div style={{ fontFamily: F.display, fontWeight: 700, fontSize: 17, marginTop: 12 }}>{t}</div>
      <div style={{ fontSize: 13.5, color: T.sub, lineHeight: 1.5, marginTop: 7 }}>{d}</div>
    </Card>
  );
  const Chart = ({ intent, title, rule, children, h = 200 }) => (
    <Card>
      <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 4 }}>
        <Pill color={T.cyan}>{intent}</Pill>
        <span style={{ fontFamily: F.display, fontWeight: 700, fontSize: 15 }}>{title}</span>
      </div>
      <div style={{ minHeight: h, display: "flex", alignItems: "center", justifyContent: "center", padding: "12px 0" }}>{children}</div>
      <div style={{ fontSize: 12.5, color: T.sub, lineHeight: 1.45, borderTop: `1px solid ${T.line}`, paddingTop: 12 }}>{rule}</div>
    </Card>
  );
  const Sin = ({ t, children }) => (
    <div style={{ background: T.card, border: `1px solid ${T.line}`, borderRadius: 12, padding: 16 }}>
      <div style={{ height: 64, display: "flex", alignItems: "center", justifyContent: "center", marginBottom: 10 }}>{children}</div>
      <div style={{ display: "flex", gap: 7, alignItems: "flex-start" }}>
        <span style={{ color: T.rust, fontWeight: 700, fontSize: 13, flexShrink: 0 }}>✕</span>
        <span style={{ fontSize: 12, color: T.sub, lineHeight: 1.4 }}>{t}</span>
      </div>
    </div>
  );
  const chooser = [
    ["Comparar valores", "Barras / colunas", T.coral],
    ["Tendência no tempo", "Linha / área", T.amber],
    ["Um número-chave", "KPI / big number", T.cyan],
    ["Composição do todo", "Barra empilhada > pizza", T.clay],
    ["Relação entre 2 vars", "Dispersão", T.teal],
    ["Volume que se afunila", "Funil / pipeline", T.olive],
    ["Detalhe exato", "Tabela", T.stone],
  ];
  return (
    <Section id="dados">
      <SecHead n="05" kicker="Dados & Gráficos" title="Mostrar dados sem mentir nem confundir."
        lead="A seção mais importante do guia. A maioria dos gráficos ruins não é feia — é desonesta ou ilegível. Aqui tem método: uma forma certa de escolher, montar e colorir cada gráfico." />

      {/* methodology */}
      <div style={{ fontFamily: F.display, fontWeight: 800, fontSize: 20, marginBottom: 18 }}>Três princípios inegociáveis</div>
      <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 22, marginBottom: 26 }}>
        <Principle n="01" t="Hierarquia perceptual" d="O olho compara posição e comprimento com precisão; ângulo, área e cor, mal. Prefira barras e linhas a pizzas e bolhas. (Cleveland & McGill)" />
        <Principle n="02" t="Razão dado-tinta" d="Cada pixel deve carregar informação. Apague grade pesada, bordas, sombras, fundos e 3D. O dado é o herói. (Tufte)" />
        <Principle n="03" t="Diga a verdade" d="Eixo de valor começa no zero. Escala proporcional. Rótulo direto no dado. Sem distorção que exagere a diferença." />
      </div>
      <Note title="Por que a IA erra gráfico" >
        Modelos tendem a empilhar enfeite (3D, gradiente, cor em tudo, legenda solta) porque "parece dashboard". Mas legibilidade vem de <strong>subtrair</strong>, não somar. Quando em dúvida: menos tinta, rótulo direto, uma cor de destaque.
      </Note>

      {/* chooser */}
      <div style={{ fontFamily: F.display, fontWeight: 800, fontSize: 20, margin: "44px 0 18px" }}>Qual gráfico usar?</div>
      <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(220px, 1fr))", gap: 12, marginBottom: 12 }}>
        {chooser.map(([intent, chart, c]) => (
          <div key={intent} style={{ display: "flex", alignItems: "center", gap: 12, background: T.card, border: `1px solid ${T.line}`, borderRadius: 10, padding: "13px 15px" }}>
            <span style={{ width: 10, height: 10, borderRadius: "50%", background: c, flexShrink: 0 }}></span>
            <div>
              <div style={{ fontFamily: F.mono, fontSize: 10, letterSpacing: 0.5, textTransform: "uppercase", color: T.sub }}>{intent}</div>
              <div style={{ fontFamily: F.display, fontWeight: 700, fontSize: 14.5, marginTop: 2 }}>{chart}</div>
            </div>
          </div>
        ))}
      </div>

      {/* gallery */}
      <div style={{ fontFamily: F.display, fontWeight: 800, fontSize: 20, margin: "44px 0 18px" }}>A galeria, feita do jeito certo</div>
      <div style={{ display: "grid", gridTemplateColumns: "repeat(2, 1fr)", gap: 22 }}>
        <Chart intent="Comparar" title="Barras" rule="Ordenadas por valor, cinza no contexto e coral só no que importa. Rótulo direto na barra — sem eixo Y poluído.">
          <BarChart data={[{ label: "Jan", value: 38 }, { label: "Fev", value: 52 }, { label: "Mar", value: 47 }, { label: "Abr", value: 71, hl: true }, { label: "Mai", value: 60 }]} fmt={(v) => v + "k"} />
        </Chart>
        <Chart intent="Tendência" title="Linha / área" rule="Série temporal contínua. Uma linha, área leve (não gradiente), e o último ponto rotulado. Grade discreta.">
          <LineChart series={[12, 18, 16, 24, 30, 28, 41]} labels={["S1", "S2", "S3", "S4", "S5", "S6", "S7"]} />
        </Chart>
        <Chart intent="Valor único" title="KPI / big number" rule="Um número que importa, grande. Contexto (delta vs período) pequeno e colorido por significado.">
          <div style={{ display: "flex", gap: 30, flexWrap: "wrap", justifyContent: "center" }}>
            <div style={{ textAlign: "center" }}>
              <div style={{ fontFamily: F.display, fontWeight: 800, fontSize: 52, color: T.ink, letterSpacing: -2, lineHeight: 0.9 }}>98,7%</div>
              <div style={{ fontFamily: F.mono, fontSize: 10.5, color: T.sub, letterSpacing: 1, textTransform: "uppercase", marginTop: 8 }}>uptime</div>
              <div style={{ fontSize: 12.5, color: T.teal, fontWeight: 600, marginTop: 4 }}>▲ 0,3 pp</div>
            </div>
            <div style={{ textAlign: "center" }}>
              <div style={{ fontFamily: F.display, fontWeight: 800, fontSize: 52, color: T.coral, letterSpacing: -2, lineHeight: 0.9 }}>1,2M</div>
              <div style={{ fontFamily: F.mono, fontSize: 10.5, color: T.sub, letterSpacing: 1, textTransform: "uppercase", marginTop: 8 }}>eventos/dia</div>
              <div style={{ fontSize: 12.5, color: T.clay, fontWeight: 600, marginTop: 4 }}>▲ 8%</div>
            </div>
          </div>
        </Chart>
        <Chart intent="Composição" title="Donut — com ressalvas" rule="Só para 2–4 fatias e quando o todo importa. Sempre com % direto. Para mais categorias, prefira barras.">
          <div style={{ display: "flex", alignItems: "center", gap: 22 }}>
            <Donut segs={[{ label: "Retrieval", value: 58, color: T.coral }, { label: "LLM", value: 30, color: T.amber }, { label: "Outros", value: 12, color: T.taupe }]} />
            <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
              {[["Retrieval", "58%", T.coral], ["LLM", "30%", T.amber], ["Outros", "12%", T.taupe]].map(([l, v, c]) => (
                <div key={l} style={{ display: "flex", alignItems: "center", gap: 8, fontSize: 12.5 }}>
                  <span style={{ width: 10, height: 10, borderRadius: 3, background: c }}></span>
                  <span style={{ fontWeight: 600 }}>{l}</span><span style={{ fontFamily: F.mono, color: T.sub }}>{v}</span>
                </div>
              ))}
            </div>
          </div>
        </Chart>
        <Chart intent="Relação" title="Dispersão" rule="Duas variáveis numéricas. Contexto em ciano translúcido, outlier de interesse destacado em coral.">
          <Scatter points={[{ x: 0.15, y: 0.2 }, { x: 0.3, y: 0.35 }, { x: 0.42, y: 0.3 }, { x: 0.55, y: 0.6 }, { x: 0.6, y: 0.52 }, { x: 0.78, y: 0.85, hl: true }, { x: 0.7, y: 0.66 }, { x: 0.35, y: 0.5 }]} />
        </Chart>
        <Chart intent="Funil" title="Pipeline" rule="Volume que decai por etapa. Barras proporcionais, valor absoluto em cada uma, destaque no gargalo ou na saída.">
          <Pipeline stages={[{ label: "Capturado", value: 12000 }, { label: "Válido", value: 9800 }, { label: "Embedado", value: 9100 }, { label: "Servido", value: 8700 }]} />
        </Chart>
        <Chart intent="Detalhe" title="Tabela bem feita" rule="Números à direita, mono tabular, alinhados. Cabeçalho discreto, uma linha de destaque. Sem grade vertical." h={170}>
          <DataTable />
        </Chart>
        <Chart intent="Cor = sentido" title="Codificação de cor" rule="Categórica: hues distintos (máx ~5). Sequencial: um tom claro→escuro. Destaque: tudo cinza + 1 coral." h={200}>
          <div style={{ display: "flex", flexDirection: "column", gap: 16, width: "100%" }}>
            {[["Categórica", [T.coral, T.cyan, T.amber, T.olive, T.teal]], ["Sequencial", [T.sand, "#D9B98A", T.clay, "#A8512F", T.rust]], ["Destaque", [T.taupe, T.taupe, T.coral, T.taupe, T.taupe]]].map(([l, cols]) => (
              <div key={l}>
                <div style={{ fontFamily: F.mono, fontSize: 10, letterSpacing: 0.5, textTransform: "uppercase", color: T.sub, marginBottom: 6 }}>{l}</div>
                <div style={{ display: "flex", gap: 6 }}>{cols.map((c, i) => <div key={i} style={{ flex: 1, height: 22, borderRadius: 5, background: c }}></div>)}</div>
              </div>
            ))}
          </div>
        </Chart>
      </div>

      {/* right vs wrong — truncated axis */}
      <div style={{ fontFamily: F.display, fontWeight: 800, fontSize: 20, margin: "44px 0 18px" }}>O erro que mais engana: eixo cortado</div>
      <RightWrong h={180}
        wrongCap="Eixo começando em 90 faz uma diferença de 4% parecer enorme. Distorção — mesmo sem querer."
        rightCap="Eixo no zero mostra a diferença real. Honesto. Se a variação é pequena, o gráfico deve mostrar isso."
        wrong={<BarChart h={150} baseline={90} data={[{ label: "A", value: 94 }, { label: "B", value: 96 }, { label: "C", value: 98, hl: true }]} fmt={(v) => v + "%"} />}
        right={<BarChart h={150} baseline={0} data={[{ label: "A", value: 94 }, { label: "B", value: 96 }, { label: "C", value: 98, hl: true }]} fmt={(v) => v + "%"} />}
      />

      {/* pecados */}
      <div style={{ fontFamily: F.display, fontWeight: 800, fontSize: 20, margin: "44px 0 18px" }}>Pecados capitais dos gráficos</div>
      <div style={{ display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 16 }}>
        <Sin t="3D: distorce área e esconde dado atrás de dado.">
          <div style={{ display: "flex", gap: 6, alignItems: "flex-end", transform: "perspective(200px) rotateX(35deg)" }}>
            {[26, 40, 32].map((h, i) => <div key={i} style={{ width: 16, height: h, background: T.clay }}></div>)}
          </div>
        </Sin>
        <Sin t="Arco-íris: cor sem significado vira ruído.">
          <div style={{ display: "flex", gap: 4 }}>{["#E8553A", "#E8A33D", "#7F8B45", "#16786E", "#0E9AAC", "#9E3E2B"].map((c, i) => <div key={i} style={{ width: 13, height: 40, background: c }}></div>)}</div>
        </Sin>
        <Sin t="Pizza com 8 fatias: impossível comparar ângulos.">
          <svg width="56" height="56" viewBox="0 0 56 56"><g transform="translate(28,28)">{[0, 45, 80, 130, 180, 230, 290, 330].map((a, i, arr) => { const a2 = arr[i + 1] || 360; const rad = (x) => (x - 90) * Math.PI / 180; const x1 = 24 * Math.cos(rad(a)), y1 = 24 * Math.sin(rad(a)), x2 = 24 * Math.cos(rad(a2)), y2 = 24 * Math.sin(rad(a2)); const cols = ["#E8553A", "#E8A33D", "#7F8B45", "#16786E", "#0E9AAC", "#9E3E2B", "#C2683E", "#EBC14E"]; return <path key={i} d={`M0 0 L${x1} ${y1} A24 24 0 0 1 ${x2} ${y2} Z`} fill={cols[i]} stroke="#FBF6EA" strokeWidth="0.6" />; })}</g></svg>
        </Sin>
        <Sin t="Sem rótulo: obriga o leitor a adivinhar o valor.">
          <svg width="80" height="44" viewBox="0 0 80 44"><polyline points="4,38 20,24 36,30 52,12 76,18" fill="none" stroke={T.taupe} strokeWidth="2" /></svg>
        </Sin>
      </div>
      <div style={{ marginTop: 24 }}>
        <Note title="O checklist antes de publicar um gráfico">
          1) O eixo começa no zero? 2) Dá pra entender sem legenda? 3) A cor significa algo? 4) Apaguei toda tinta que não informa? 5) O título diz a conclusão, não só o assunto? Se passou nos cinco, pode publicar.
        </Note>
      </div>
    </Section>
  );
}

Object.assign(window, { GMDataviz });
