// SVG chart primitives — no external libs.
// Uses CSS vars for colors so light/dark works automatically.

const Sparkline = ({ data, w = 120, h = 36, stroke = "var(--primary)", fill = "none", area = false, strokeWidth = 1.5 }) => {
  if (!data || data.length < 2) return null;
  const min = Math.min(...data), max = Math.max(...data), range = max - min || 1;
  const stepX = w / (data.length - 1);
  const pts = data.map((v, i) => [i * stepX, h - ((v - min) / range) * (h - 4) - 2]);
  const d = pts.map((p, i) => `${i === 0 ? 'M' : 'L'} ${p[0].toFixed(1)} ${p[1].toFixed(1)}`).join(" ");
  const areaD = area ? `${d} L ${w} ${h} L 0 ${h} Z` : null;
  return (
    <svg width={w} height={h} viewBox={`0 0 ${w} ${h}`} style={{ display: 'block' }}>
      {areaD && <path d={areaD} fill={fill} opacity=".15" />}
      <path d={d} fill="none" stroke={stroke} strokeWidth={strokeWidth} strokeLinecap="round" strokeLinejoin="round" />
      <circle cx={pts[pts.length - 1][0]} cy={pts[pts.length - 1][1]} r="2.5" fill={stroke} />
    </svg>
  );
};

const LineChart = ({ series, w = 600, h = 220, labels, colors = ["var(--primary)", "var(--accent)"], showGrid = true, showAxes = true, yFormat = (v) => v }) => {
  // series: [{name, data:[..]}, ...]
  const pad = { t: 12, r: 12, b: 24, l: 40 };
  const iw = w - pad.l - pad.r, ih = h - pad.t - pad.b;
  const allVals = series.flatMap(s => s.data);
  const min = Math.min(...allVals, 0), max = Math.max(...allVals);
  const range = max - min || 1;
  const len = series[0].data.length;
  const xStep = iw / (len - 1);
  const yTicks = 4;
  return (
    <svg width="100%" height={h} viewBox={`0 0 ${w} ${h}`} preserveAspectRatio="none" style={{ display: 'block', overflow: 'visible' }}>
      {showGrid && Array.from({ length: yTicks + 1 }).map((_, i) => {
        const y = pad.t + (ih / yTicks) * i;
        return <line key={i} x1={pad.l} x2={w - pad.r} y1={y} y2={y} stroke="var(--border)" strokeDasharray={i === yTicks ? "" : "2 3"} />;
      })}
      {showAxes && Array.from({ length: yTicks + 1 }).map((_, i) => {
        const y = pad.t + (ih / yTicks) * i;
        const v = max - (range / yTicks) * i;
        return <text key={i} x={pad.l - 6} y={y + 3} fontSize="10" fill="var(--ink-3)" textAnchor="end" fontFamily="JetBrains Mono">{yFormat(Math.round(v))}</text>;
      })}
      {showAxes && labels && labels.map((l, i) => {
        if (labels.length > 12 && i % 2 !== 0) return null;
        const x = pad.l + i * xStep;
        return <text key={i} x={x} y={h - 6} fontSize="10" fill="var(--ink-3)" textAnchor="middle">{l}</text>;
      })}
      {series.map((s, si) => {
        const color = colors[si % colors.length];
        const pts = s.data.map((v, i) => [pad.l + i * xStep, pad.t + ih - ((v - min) / range) * ih]);
        const d = pts.map((p, i) => `${i === 0 ? 'M' : 'L'} ${p[0].toFixed(1)} ${p[1].toFixed(1)}`).join(" ");
        const areaD = `${d} L ${pad.l + iw} ${pad.t + ih} L ${pad.l} ${pad.t + ih} Z`;
        return (
          <g key={si}>
            {si === 0 && <path d={areaD} fill={color} opacity=".08" />}
            <path d={d} fill="none" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
            {pts.map((p, i) => <circle key={i} cx={p[0]} cy={p[1]} r="2.5" fill="var(--panel)" stroke={color} strokeWidth="1.5" />)}
          </g>
        );
      })}
    </svg>
  );
};

const BarChart = ({ data, w = 600, h = 220, labels, color = "var(--primary)", accent, horizontal = false, showValue = false, format = (v) => v }) => {
  const pad = horizontal ? { t: 8, r: 40, b: 8, l: 120 } : { t: 12, r: 12, b: 26, l: 40 };
  const iw = w - pad.l - pad.r, ih = h - pad.t - pad.b;
  const max = Math.max(...data);
  if (horizontal) {
    const barH = Math.min(22, (ih / data.length) - 6);
    return (
      <svg width="100%" height={Math.max(h, data.length * (barH + 8) + pad.t + pad.b)} viewBox={`0 0 ${w} ${Math.max(h, data.length * (barH + 8) + pad.t + pad.b)}`} preserveAspectRatio="none" style={{ display: 'block' }}>
        {data.map((v, i) => {
          const y = pad.t + i * (barH + 8);
          const barW = (v / max) * iw;
          return (
            <g key={i}>
              <text x={pad.l - 8} y={y + barH / 2 + 3} fontSize="11" fill="var(--ink-2)" textAnchor="end">{labels[i]}</text>
              <rect x={pad.l} y={y} width={iw} height={barH} rx="3" fill="var(--panel-3)" />
              <rect x={pad.l} y={y} width={barW} height={barH} rx="3" fill={i === 0 && accent ? accent : color} />
              <text x={pad.l + barW + 6} y={y + barH / 2 + 3} fontSize="11" fill="var(--ink-2)" fontFamily="JetBrains Mono">{format(v)}</text>
            </g>
          );
        })}
      </svg>
    );
  }
  const barW = iw / data.length * 0.7;
  const gap = iw / data.length * 0.3;
  return (
    <svg width="100%" height={h} viewBox={`0 0 ${w} ${h}`} preserveAspectRatio="none" style={{ display: 'block' }}>
      {Array.from({ length: 5 }).map((_, i) => {
        const y = pad.t + (ih / 4) * i;
        return <line key={i} x1={pad.l} x2={w - pad.r} y1={y} y2={y} stroke="var(--border)" strokeDasharray={i === 4 ? "" : "2 3"} />;
      })}
      {data.map((v, i) => {
        const x = pad.l + i * (barW + gap) + gap / 2;
        const barHeight = (v / max) * ih;
        const y = pad.t + ih - barHeight;
        return (
          <g key={i}>
            <rect x={x} y={y} width={barW} height={barHeight} rx="3" fill={color} />
            {labels && <text x={x + barW / 2} y={h - 8} fontSize="10" fill="var(--ink-3)" textAnchor="middle">{labels[i]}</text>}
            {showValue && <text x={x + barW / 2} y={y - 4} fontSize="10" fill="var(--ink-2)" fontFamily="JetBrains Mono" textAnchor="middle">{format(v)}</text>}
          </g>
        );
      })}
    </svg>
  );
};

const Donut = ({ data, w = 160, colors = ["var(--primary)", "var(--accent)", "var(--info)", "var(--ok)", "oklch(0.55 0.14 300)"], thickness = 22, centerLabel, centerSub }) => {
  const r = w / 2 - 4;
  const inner = r - thickness;
  const cx = w / 2, cy = w / 2;
  const total = data.reduce((s, d) => s + d.value, 0);
  let angle = -Math.PI / 2;
  const arcs = data.map((d, i) => {
    const frac = d.value / total;
    const nextAngle = angle + frac * Math.PI * 2;
    const large = frac > 0.5 ? 1 : 0;
    const x1 = cx + r * Math.cos(angle), y1 = cy + r * Math.sin(angle);
    const x2 = cx + r * Math.cos(nextAngle), y2 = cy + r * Math.sin(nextAngle);
    const x3 = cx + inner * Math.cos(nextAngle), y3 = cy + inner * Math.sin(nextAngle);
    const x4 = cx + inner * Math.cos(angle), y4 = cy + inner * Math.sin(angle);
    const path = `M ${x1} ${y1} A ${r} ${r} 0 ${large} 1 ${x2} ${y2} L ${x3} ${y3} A ${inner} ${inner} 0 ${large} 0 ${x4} ${y4} Z`;
    angle = nextAngle;
    return { path, color: colors[i % colors.length], label: d.label, value: d.value };
  });
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 16 }}>
      <svg width={w} height={w} style={{ flexShrink: 0 }}>
        {arcs.map((a, i) => <path key={i} d={a.path} fill={a.color} />)}
        {centerLabel && <text x={cx} y={cy - 2} fontSize="18" fontFamily="JetBrains Mono" fill="var(--ink)" textAnchor="middle" fontWeight="600">{centerLabel}</text>}
        {centerSub && <text x={cx} y={cy + 14} fontSize="10" fill="var(--ink-3)" textAnchor="middle">{centerSub}</text>}
      </svg>
      <div style={{ flex: 1, display: 'flex', flexDirection: 'column', gap: 6 }}>
        {arcs.map((a, i) => (
          <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 12 }}>
            <span style={{ width: 8, height: 8, borderRadius: 2, background: a.color, flexShrink: 0 }} />
            <span style={{ flex: 1, color: 'var(--ink-2)' }}>{a.label}</span>
            <span className="mono" style={{ color: 'var(--ink)', fontWeight: 500 }}>{((a.value / total) * 100).toFixed(1)}%</span>
          </div>
        ))}
      </div>
    </div>
  );
};

const Gauge = ({ value, max = 100, w = 160, label, sub, color = "var(--primary)" }) => {
  const r = 60;
  const cx = w / 2, cy = 80;
  const startA = Math.PI, endA = 2 * Math.PI;
  const arcAngle = startA + (value / max) * Math.PI;
  const p = (a) => [cx + r * Math.cos(a), cy + r * Math.sin(a)];
  const [x1, y1] = p(startA); const [x2, y2] = p(endA); const [xv, yv] = p(arcAngle);
  return (
    <svg width={w} height={100} viewBox={`0 0 ${w} 100`}>
      <path d={`M ${x1} ${y1} A ${r} ${r} 0 0 1 ${x2} ${y2}`} stroke="var(--panel-3)" strokeWidth="10" fill="none" strokeLinecap="round" />
      <path d={`M ${x1} ${y1} A ${r} ${r} 0 0 1 ${xv} ${yv}`} stroke={color} strokeWidth="10" fill="none" strokeLinecap="round" />
      <text x={cx} y={72} fontSize="22" fontFamily="JetBrains Mono" fontWeight="600" fill="var(--ink)" textAnchor="middle">{value}{typeof value === 'number' ? '%' : ''}</text>
      <text x={cx} y={92} fontSize="10" fill="var(--ink-3)" textAnchor="middle">{sub}</text>
    </svg>
  );
};

const Heatmap = ({ rows, cols, data, w = 600, cellH = 22, rowLabels, colLabels, format = (v) => v }) => {
  // data: 2d array [rows][cols]
  const max = Math.max(...data.flat());
  const min = Math.min(...data.flat());
  const cellW = (w - 90) / cols;
  return (
    <svg width="100%" height={rows * cellH + 30} viewBox={`0 0 ${w} ${rows * cellH + 30}`} preserveAspectRatio="none">
      {colLabels && colLabels.map((l, i) => (
        <text key={i} x={90 + i * cellW + cellW / 2} y={16} fontSize="10" fill="var(--ink-3)" textAnchor="middle">{l}</text>
      ))}
      {data.map((row, ri) => (
        <g key={ri}>
          {rowLabels && <text x={82} y={30 + ri * cellH + cellH / 2 + 3} fontSize="11" fill="var(--ink-2)" textAnchor="end">{rowLabels[ri]}</text>}
          {row.map((v, ci) => {
            const intensity = (v - min) / (max - min || 1);
            const bg = `oklch(${0.98 - intensity * 0.55} ${0.04 + intensity * 0.12} 258)`;
            const txtColor = intensity > 0.55 ? 'white' : 'var(--ink-2)';
            return (
              <g key={ci}>
                <rect x={90 + ci * cellW + 1} y={22 + ri * cellH + 1} width={cellW - 2} height={cellH - 2} rx="2" fill={bg} />
                <text x={90 + ci * cellW + cellW / 2} y={22 + ri * cellH + cellH / 2 + 3} fontSize="10" fontFamily="JetBrains Mono" fill={txtColor} textAnchor="middle">{format(v)}</text>
              </g>
            );
          })}
        </g>
      ))}
    </svg>
  );
};

Object.assign(window, { Sparkline, LineChart, BarChart, Donut, Gauge, Heatmap });
