// charts.jsx — lightweight SVG charts

function Sparkline({ data, color = "var(--accent)", height = 48, fill = true }) {
  const w = 200, h = height, pad = 2;
  const min = Math.min(...data), max = Math.max(...data);
  const rng = max - min || 1;
  const pts = data.map((v, i) => [
    pad + (i / (data.length - 1)) * (w - pad * 2),
    h - pad - ((v - min) / rng) * (h - pad * 2),
  ]);
  const d = pts.map((p, i) => (i ? "L" : "M") + p[0].toFixed(1) + "," + p[1].toFixed(1)).join(" ");
  const dFill = d + ` L${pts[pts.length-1][0]},${h} L${pts[0][0]},${h} Z`;
  return (
    <svg className="spark" viewBox={`0 0 ${w} ${h}`} width="100%" height={h} preserveAspectRatio="none">
      {fill && <path d={dFill} fill={color} opacity=".12" />}
      <path d={d} fill="none" stroke={color} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
    </svg>
  );
}

function AreaChart({ series, height = 220, labels }) {
  const w = 800, h = height, pad = { t: 10, r: 12, b: 24, l: 36 };
  const safeSeries = (series || []).filter(s => Array.isArray(s.data) && s.data.length > 0);
  const len = safeSeries[0]?.data.length || 0;

  if (!len) {
    return (
      <svg viewBox={`0 0 ${w} ${h}`} width="100%" height={h} style={{display:"block"}}>
        <text x={w/2} y={h/2} textAnchor="middle" fontSize="13" fill="var(--ink-4)">No data for this range</text>
      </svg>
    );
  }

  const allV = safeSeries.flatMap(s => s.data);
  const max = Math.max(...allV, 1) * 1.15;
  const xs = i => pad.l + (len === 1 ? (w - pad.l - pad.r) / 2 : (i / (len - 1)) * (w - pad.l - pad.r));
  const ys = v => h - pad.b - (v / max) * (h - pad.t - pad.b);

  const gridLines = [0, 0.25, 0.5, 0.75, 1].map(f => ({
    y: pad.t + f * (h - pad.t - pad.b),
    val: Math.round(max * (1 - f)),
  }));

  return (
    <svg viewBox={`0 0 ${w} ${h}`} width="100%" height={h} style={{display:"block"}}>
      {gridLines.map((g, i) => (
        <g key={i}>
          <line x1={pad.l} x2={w - pad.r} y1={g.y} y2={g.y} stroke="var(--line)" strokeDasharray={i === 4 ? "0" : "3 4"} />
          <text x={pad.l - 8} y={g.y + 3} textAnchor="end" fontSize="10" fill="var(--ink-4)">{g.val}</text>
        </g>
      ))}
      {labels && labels.map((lb, i) => {
        const step = Math.max(1, Math.floor((len - 1) / (labels.length - 1)));
        return <text key={i} x={xs(Math.min(i * step, len - 1))} y={h - 8} textAnchor="middle" fontSize="10" fill="var(--ink-4)">{lb}</text>;
      })}
      {safeSeries.map((s, si) => {
        const pts = s.data.map((v, i) => [xs(i), ys(v)]);
        const d = pts.map((p, i) => (i ? "L" : "M") + p[0].toFixed(1) + "," + p[1].toFixed(1)).join(" ");
        const dFill = d + ` L${pts[pts.length-1][0]},${ys(0)} L${pts[0][0]},${ys(0)} Z`;
        return (
          <g key={si}>
            <path d={dFill} fill={s.color} opacity={si === 0 ? ".10" : ".05"} />
            <path d={d} fill="none" stroke={s.color} strokeWidth="1.75" strokeLinecap="round" strokeLinejoin="round" />
          </g>
        );
      })}
    </svg>
  );
}

function BarPair({ data, height = 180 }) {
  const max = Math.max(...data.flatMap(d => [d.a, d.m])) || 1;
  return (
    <div className="bars" style={{height}}>
      {data.map((d, i) => (
        <div key={i} style={{display:"flex", flexDirection:"column", alignItems:"center", gap:4, flex:1}}>
          <div style={{display:"flex", gap:3, alignItems:"flex-end", height: height - 24, width:"100%", justifyContent:"center"}}>
            <div style={{width:"40%", background:"var(--accent)", borderRadius:"3px 3px 0 0", height: (d.a / max) * (height - 24) + "px"}} />
            <div style={{width:"40%", background:"color-mix(in oklab, var(--bad) 50%, var(--bg-sunken))", borderRadius:"3px 3px 0 0", height: (d.m / max) * (height - 24) + "px"}} />
          </div>
          <div style={{fontSize:10, color:"var(--ink-4)"}}>{d.label}</div>
        </div>
      ))}
    </div>
  );
}

function USMap({ dots }) {
  // Dot-matrix lower-48 — per-row horizontal spans approximate the real outline
  // (west coast diagonal, Gulf curve, Florida peninsula, NE hook, Great Lakes dent).
  const W = 800, H = 400;
  const cols = 52, rows = 26;
  // Each entry: [rowIndex, [startColFraction, endColFraction], ...more spans]
  // Fractions 0..1 across width. Multiple spans allow Great Lakes gap.
  const SPANS = {
    3:  [[.52,.68]],                       // ND/MN top
    4:  [[.30,.72]],                       // Montana → Great Lakes
    5:  [[.16,.78]],                       // WA → Maine top
    6:  [[.13,.54],[.60,.84]],             // gap = Great Lakes
    7:  [[.12,.52],[.62,.86]],             // Great Lakes continues
    8:  [[.11,.88]],                       // full band (OR→NY)
    9:  [[.11,.89]],                       // NorCal → VA
    10: [[.12,.90]],                       // NV/UT → DC
    11: [[.14,.90]],                       // CA→Carolinas
    12: [[.15,.88]],                       // SoCal → NC
    13: [[.17,.86]],                       // AZ→SC
    14: [[.20,.84]],                       // AZ→GA
    15: [[.24,.82]],                       // NM/TX→AL/GA
    16: [[.28,.80]],                       // TX panhandle curve
    17: [[.30,.60],[.74,.82]],             // TX body + FL start
    18: [[.32,.56],[.76,.84]],             // TX → FL peninsula
    19: [[.34,.52],[.77,.84]],             // S TX + FL
    20: [[.36,.48],[.78,.85]],             // tip of TX + FL
    21: [[.79,.85]],                       // FL only
    22: [[.80,.84]],                       // FL tip
  };

  const dotNodes = [];
  for (let r = 0; r < rows; r++) {
    const spans = SPANS[r];
    if (!spans) continue;
    for (let c = 0; c < cols; c++) {
      const f = c / (cols - 1);
      const inside = spans.some(([a, b]) => f >= a && f <= b);
      if (!inside) continue;
      const x = (c + 0.5) * (W / cols);
      const y = (r + 0.5) * (H / rows);
      dotNodes.push(<circle key={`${r}-${c}`} cx={x} cy={y} r="2.1" fill="var(--ink-5)" opacity="0.5" />);
    }
  }

  return (
    <svg viewBox={`0 0 ${W} ${H}`} width="100%" style={{display:"block"}}>
      {dotNodes}
      {dots.map((d, i) => (
        <g key={`dot-${i}`}>
          <circle cx={d.x * W} cy={d.y * H} r={4 + d.size * 6} fill="var(--accent)" opacity="0.18">
            <animate attributeName="r" values={`${4 + d.size * 6};${8 + d.size * 10};${4 + d.size * 6}`} dur={`${2 + i * 0.3}s`} repeatCount="indefinite" />
          </circle>
          <circle cx={d.x * W} cy={d.y * H} r={3 + d.size * 2} fill="var(--accent)" />
        </g>
      ))}
    </svg>
  );
}

Object.assign(window, { Sparkline, AreaChart, BarPair, USMap });
