/* ─── SVG-based Chart Components ─────────────────────────────────── */
/* No Chart.js dependency — pure React SVG for a lightweight bundle. */

const CHART_COLORS = {
  ELA: "#06b6d4",
  Math: "#f59e0b",
  Science: "#f43f5e",
  "Spanish Language Arts": "#6366f1",
};

/* ─── Sparkline ──────────────────────────────────────────────────── */
function Sparkline({ values, width = 64, height = 20, color = "var(--teal)" }) {
  const filtered = values.filter(v => v != null);
  if (filtered.length < 2) return <span className="suppressed">—</span>;
  const min = Math.min(...filtered);
  const max = Math.max(...filtered);
  const range = max - min || 1;
  const pts = filtered.map((v, i) => {
    const x = (i / (filtered.length - 1)) * (width - 4) + 2;
    const y = height - 2 - ((v - min) / range) * (height - 4);
    return `${x},${y}`;
  });
  return (
    <svg className="sparkline" width={width} height={height} viewBox={`0 0 ${width} ${height}`}>
      <polyline points={pts.join(" ")} fill="none" stroke={color} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
      <circle cx={pts[pts.length-1].split(",")[0]} cy={pts[pts.length-1].split(",")[1]} r="2" fill={color} />
    </svg>
  );
}

/* ─── Line Chart (statewide trends) ──────────────────────────────── */
function LineChart({ datasets, labels, width = 580, height = 260, yLabel = "%" }) {
  const pad = { top: 20, right: 20, bottom: 30, left: 50 };
  const w = width - pad.left - pad.right;
  const h = height - pad.top - pad.bottom;

  // Flatten all values to find min/max
  const allVals = datasets.flatMap(ds => ds.values.filter(v => v != null));
  if (allVals.length === 0) return <div style={{ color: "var(--text3)", padding: 20 }}>No data available</div>;

  let yMin = Math.floor(Math.min(...allVals) / 5) * 5;
  let yMax = Math.ceil(Math.max(...allVals) / 5) * 5;
  if (yMin === yMax) { yMin -= 5; yMax += 5; }
  const yRange = yMax - yMin;
  const yTicks = [];
  for (let v = yMin; v <= yMax; v += Math.max(5, Math.round(yRange / 5 / 5) * 5)) yTicks.push(v);

  function toX(i) { return pad.left + (i / Math.max(labels.length - 1, 1)) * w; }
  function toY(v) { return pad.top + h - ((v - yMin) / yRange) * h; }

  return (
    <svg width="100%" viewBox={`0 0 ${width} ${height}`} style={{ overflow: "visible" }}>
      {/* Grid */}
      {yTicks.map(v => (
        <g key={v}>
          <line x1={pad.left} y1={toY(v)} x2={pad.left + w} y2={toY(v)} stroke="rgba(255,255,255,0.06)" />
          <text x={pad.left - 8} y={toY(v) + 4} textAnchor="end" fill="var(--text3)" fontSize="11">{v}{yLabel === "%" ? "%" : ""}</text>
        </g>
      ))}
      {/* X labels */}
      {labels.map((l, i) => (
        <text key={l} x={toX(i)} y={height - 6} textAnchor="middle" fill="var(--text3)" fontSize="11">{l}</text>
      ))}
      {/* Lines */}
      {datasets.map((ds, di) => {
        const pts = ds.values.map((v, i) => v != null ? { x: toX(i), y: toY(v) } : null).filter(Boolean);
        if (pts.length < 2) return null;
        const pathD = pts.map((p, i) => (i === 0 ? "M" : "L") + p.x + "," + p.y).join(" ");
        return (
          <g key={di}>
            <path d={pathD} fill="none" stroke={ds.color || "var(--teal)"} strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" />
            {pts.map((p, i) => (
              <circle key={i} cx={p.x} cy={p.y} r="3.5" fill={ds.color || "var(--teal)"} stroke="var(--bg2)" strokeWidth="2">
                <title>{ds.label}: {ds.values[i] != null ? ds.values[i].toFixed(1) + "%" : "—"}</title>
              </circle>
            ))}
          </g>
        );
      })}
    </svg>
  );
}

/* ─── Grouped Bar Chart ──────────────────────────────────────────── */
function GroupedBarChart({ groups, series, width = 580, height = 260, refLine = null }) {
  // groups: ["2022","2023","2024","2025"]
  // series: [{ label: "ELA", color: "#06b6d4", values: [43.2, 43.7, 44.1, 44.8] }, ...]
  // refLine: { value: 44.8, label: "State Avg" }
  const pad = { top: 20, right: 20, bottom: 30, left: 50 };
  const w = width - pad.left - pad.right;
  const h = height - pad.top - pad.bottom;

  const allVals = series.flatMap(s => s.values.filter(v => v != null));
  if (refLine) allVals.push(refLine.value);
  if (allVals.length === 0) return <div style={{ color: "var(--text3)", padding: 20 }}>No data</div>;

  let yMax = Math.ceil(Math.max(...allVals) / 10) * 10;
  const yRange = yMax;
  const yTicks = [];
  const step = Math.max(10, Math.round(yMax / 5 / 10) * 10);
  for (let v = 0; v <= yMax; v += step) yTicks.push(v);

  const nGroups = groups.length;
  const nSeries = series.length;
  const groupW = w / nGroups;
  const barW = Math.min(24, (groupW - 12) / nSeries);
  const clusterW = barW * nSeries + (nSeries - 1) * 2;

  function toY(v) { return pad.top + h - (v / yRange) * h; }

  return (
    <svg width="100%" viewBox={`0 0 ${width} ${height}`}>
      {yTicks.map(v => (
        <g key={v}>
          <line x1={pad.left} y1={toY(v)} x2={pad.left + w} y2={toY(v)} stroke="rgba(255,255,255,0.06)" />
          <text x={pad.left - 8} y={toY(v) + 4} textAnchor="end" fill="var(--text3)" fontSize="11">{v}%</text>
        </g>
      ))}
      {groups.map((g, gi) => {
        const gx = pad.left + gi * groupW + groupW / 2;
        return (
          <g key={gi}>
            <text x={gx} y={height - 6} textAnchor="middle" fill="var(--text3)" fontSize="11">{g}</text>
            {series.map((s, si) => {
              const v = s.values[gi];
              if (v == null) return null;
              const bx = gx - clusterW / 2 + si * (barW + 2);
              const by = toY(v);
              const bh = toY(0) - by;
              return (
                <g key={si}>
                  <rect x={bx} y={by} width={barW} height={bh} rx="3" fill={s.color} opacity="0.85">
                    <title>{s.label} {g}: {v.toFixed(1)}%</title>
                  </rect>
                  {bh > 16 && (
                    <text x={bx + barW / 2} y={by + 14} textAnchor="middle" fill="#fff" fontSize="10" fontWeight="600">
                      {v.toFixed(1)}
                    </text>
                  )}
                </g>
              );
            })}
          </g>
        );
      })}
      {refLine && (
        <g>
          <line x1={pad.left} y1={toY(refLine.value)} x2={pad.left + w} y2={toY(refLine.value)}
                stroke="var(--text3)" strokeWidth="1" strokeDasharray="6 3" />
          <text x={pad.left + w + 4} y={toY(refLine.value) + 4} fill="var(--text3)" fontSize="10">
            {refLine.label} {refLine.value.toFixed(1)}%
          </text>
        </g>
      )}
    </svg>
  );
}

/* ─── Horizontal Bar Chart (for district rankings) ────────────────── */
function HBarChart({ items, highlightIdx = null, width = 500, maxHeight = 600 }) {
  // items: [{ label, value, subLabel }]
  const barH = 28;
  const gap = 3;
  const pad = { top: 10, right: 60, bottom: 10, left: 180 };
  const maxVal = Math.max(...items.map(i => i.value || 0), 1);
  const chartH = pad.top + items.length * (barH + gap) + pad.bottom;
  const w = width;
  const barAreaW = w - pad.left - pad.right;

  return (
    <div style={{ maxHeight, overflowY: "auto", overflowX: "hidden" }}>
      <svg width="100%" viewBox={`0 0 ${w} ${chartH}`}>
        {items.map((item, i) => {
          const y = pad.top + i * (barH + gap);
          const bw = item.value != null ? (item.value / maxVal) * barAreaW : 0;
          const isHl = i === highlightIdx;
          return (
            <g key={i}>
              <text x={16} y={y + barH / 2 + 1} dominantBaseline="middle" fill={isHl ? "var(--teal)" : "var(--text2)"} fontSize="12" fontWeight={isHl ? "700" : "400"}>
                #{i + 1}
              </text>
              <text x={40} y={y + barH / 2 + 1} dominantBaseline="middle" fill={isHl ? "var(--text)" : "var(--text2)"} fontSize="12" fontWeight={isHl ? "600" : "400"}>
                {item.label.length > 22 ? item.label.slice(0, 20) + "…" : item.label}
              </text>
              <rect x={pad.left} y={y + 2} width={bw} height={barH - 4} rx="4"
                    fill={isHl ? "var(--teal)" : "var(--bg4)"} opacity={isHl ? 1 : 0.7} />
              <text x={pad.left + bw + 6} y={y + barH / 2 + 1} dominantBaseline="middle"
                    fill={isHl ? "var(--teal)" : "var(--text3)"} fontSize="12" fontWeight="600">
                {item.value != null ? item.value.toFixed(1) + "%" : "—"}
              </text>
            </g>
          );
        })}
      </svg>
    </div>
  );
}

/* ─── Histogram ──────────────────────────────────────────────────── */
function Histogram({ values, highlightValue = null, bins = 20, width = 580, height = 220, label = "" }) {
  const valid = values.filter(v => v != null);
  if (valid.length === 0) return <div style={{ color: "var(--text3)", padding: 20 }}>No data</div>;
  const min = 0;
  const max = 100;
  const binW = (max - min) / bins;
  const counts = new Array(bins).fill(0);
  valid.forEach(v => {
    let b = Math.floor((v - min) / binW);
    if (b >= bins) b = bins - 1;
    if (b < 0) b = 0;
    counts[b]++;
  });
  const maxCount = Math.max(...counts);
  const pad = { top: 20, right: 20, bottom: 30, left: 40 };
  const w = width - pad.left - pad.right;
  const h = height - pad.top - pad.bottom;

  return (
    <svg width="100%" viewBox={`0 0 ${width} ${height}`}>
      {counts.map((c, i) => {
        const x = pad.left + (i / bins) * w;
        const bw = w / bins - 1;
        const bh = (c / maxCount) * h;
        const y = pad.top + h - bh;
        return (
          <rect key={i} x={x} y={y} width={bw} height={bh} rx="2" fill="var(--bg4)" opacity="0.8">
            <title>{(min + i * binW).toFixed(0)}–{(min + (i+1) * binW).toFixed(0)}%: {c} schools</title>
          </rect>
        );
      })}
      {highlightValue != null && (
        <g>
          <line x1={pad.left + ((highlightValue - min) / (max - min)) * w}
                y1={pad.top} x2={pad.left + ((highlightValue - min) / (max - min)) * w}
                y2={pad.top + h} stroke="var(--teal)" strokeWidth="2.5" />
          <text x={pad.left + ((highlightValue - min) / (max - min)) * w}
                y={pad.top - 4} textAnchor="middle" fill="var(--teal)" fontSize="11" fontWeight="700">
            {highlightValue.toFixed(1)}%
          </text>
        </g>
      )}
      {[0, 20, 40, 60, 80, 100].map(v => (
        <text key={v} x={pad.left + (v / 100) * w} y={height - 6}
              textAnchor="middle" fill="var(--text3)" fontSize="10">{v}%</text>
      ))}
    </svg>
  );
}

/* ─── Scatter Plot ───────────────────────────────────────────────── */
function ScatterPlot({ points, highlightKeys = [], width = 580, height = 400, xLabel = "Math %", yLabel = "ELA %" }) {
  const pad = { top: 20, right: 20, bottom: 40, left: 50 };
  const w = width - pad.left - pad.right;
  const h = height - pad.top - pad.bottom;

  function toX(v) { return pad.left + (v / 100) * w; }
  function toY(v) { return pad.top + h - (v / 100) * h; }

  return (
    <svg width="100%" viewBox={`0 0 ${width} ${height}`}>
      {[0, 20, 40, 60, 80, 100].map(v => (
        <g key={v}>
          <line x1={pad.left} y1={toY(v)} x2={pad.left + w} y2={toY(v)} stroke="rgba(255,255,255,0.04)" />
          <line x1={toX(v)} y1={pad.top} x2={toX(v)} y2={pad.top + h} stroke="rgba(255,255,255,0.04)" />
          <text x={pad.left - 8} y={toY(v) + 4} textAnchor="end" fill="var(--text3)" fontSize="10">{v}%</text>
          <text x={toX(v)} y={height - 16} textAnchor="middle" fill="var(--text3)" fontSize="10">{v}%</text>
        </g>
      ))}
      <text x={pad.left + w / 2} y={height - 2} textAnchor="middle" fill="var(--text3)" fontSize="11">{xLabel}</text>
      {points.map((p, i) => {
        const hl = highlightKeys.includes(p.key);
        return (
          <circle key={i} className="scatter-dot" cx={toX(p.x)} cy={toY(p.y)} r={hl ? 6 : 3}
                  fill={hl ? "var(--teal)" : "var(--bg4)"} stroke={hl ? "var(--teal)" : "none"} strokeWidth={hl ? 2 : 0}
                  opacity={hl ? 1 : 0.5}>
            <title>{p.label}: Math {p.x.toFixed(1)}%, ELA {p.y.toFixed(1)}%</title>
          </circle>
        );
      })}
    </svg>
  );
}

/* ─── Radar Chart ────────────────────────────────────────────────── */
function RadarChart({ datasets, labels, width = 300, height = 300 }) {
  const cx = width / 2;
  const cy = height / 2;
  const r = Math.min(cx, cy) - 40;
  const n = labels.length;
  if (n < 3) return null;

  function angle(i) { return (Math.PI * 2 * i) / n - Math.PI / 2; }
  function toXY(i, v) {
    const a = angle(i);
    const d = (v / 100) * r;
    return { x: cx + d * Math.cos(a), y: cy + d * Math.sin(a) };
  }

  const rings = [20, 40, 60, 80, 100];

  return (
    <svg className="radar-svg" width="100%" viewBox={`0 0 ${width} ${height}`}>
      {rings.map(rv => {
        const pts = labels.map((_, i) => toXY(i, rv));
        return <polygon key={rv} points={pts.map(p => `${p.x},${p.y}`).join(" ")}
                        fill="none" stroke="rgba(255,255,255,0.06)" strokeWidth="1" />;
      })}
      {labels.map((l, i) => {
        const p = toXY(i, 110);
        return <text key={i} x={p.x} y={p.y} textAnchor="middle" dominantBaseline="middle"
                     fill="var(--text3)" fontSize="11">{l}</text>;
      })}
      {datasets.map((ds, di) => {
        const pts = ds.values.map((v, i) => v != null ? toXY(i, v) : null);
        const validPts = pts.filter(Boolean);
        if (validPts.length < 3) return null;
        return (
          <g key={di}>
            <polygon points={validPts.map(p => `${p.x},${p.y}`).join(" ")}
                     fill={ds.color} fillOpacity="0.1" stroke={ds.color} strokeWidth="2" />
            {validPts.map((p, i) => (
              <circle key={i} cx={p.x} cy={p.y} r="3" fill={ds.color} />
            ))}
          </g>
        );
      })}
    </svg>
  );
}

/* ─── Heatmap (grades × years) ───────────────────────────────────── */
function GradeHeatmap({ schoolData, subject }) {
  const grades = ["03", "04", "05", "06", "07", "08", "11"];
  const years = ["2022", "2023", "2024", "2025"];
  const cellW = 64;
  const cellH = 36;
  const labelW = 50;
  const headerH = 24;

  function heatColor(v) {
    if (v == null) return "var(--bg4)";
    // Red → Yellow → Green
    const t = Math.min(Math.max(v / 100, 0), 1);
    if (t < 0.35) return `rgba(244,63,94,${0.3 + t * 0.5})`;
    if (t < 0.55) return `rgba(245,158,11,${0.3 + (t - 0.35) * 2})`;
    return `rgba(16,185,129,${0.3 + (t - 0.55) * 1.2})`;
  }

  return (
    <div style={{ overflowX: "auto" }}>
      <div style={{ display: "grid", gridTemplateColumns: `${labelW}px repeat(${years.length}, ${cellW}px)`, gap: 3 }}>
        <div />
        {years.map(y => (
          <div key={y} style={{ textAlign: "center", fontSize: 11, color: "var(--text3)", fontWeight: 600, height: headerH, lineHeight: headerH + "px" }}>{y}</div>
        ))}
        {grades.map(g => (
          <React.Fragment key={g}>
            <div style={{ fontSize: 12, color: "var(--text2)", fontWeight: 500, lineHeight: cellH + "px" }}>Grade {parseInt(g)}</div>
            {years.map(yr => {
              const v = schoolData?.years?.[yr]?.[subject]?.grades?.[g]?.pct;
              return (
                <div key={yr} className="heatmap-cell" style={{
                  background: heatColor(v),
                  height: cellH,
                  color: v != null ? "#fff" : "var(--text3)",
                }}>
                  {v != null ? v.toFixed(1) : "—"}
                </div>
              );
            })}
          </React.Fragment>
        ))}
      </div>
    </div>
  );
}

/* ─── Progress Bar Inline ────────────────────────────────────────── */
function ProgressBar({ value, max = 100, color = "var(--teal)", width = 80 }) {
  const pct = value != null ? Math.min(value / max * 100, 100) : 0;
  return (
    <div className="progress-bar" style={{ width }}>
      <div className="progress-fill" style={{ width: pct + "%", background: color }} />
    </div>
  );
}
