/* charts.jsx — SVG visualizations */

function LineChart({ series, height = 340, showClip = true, clipX = 0.66, yTicks = [0,25,50,75,100], xLabels, yLabelFormat }) {
  const W = 1000, H = 380, padL = 38, padR = 14, padT = 16, padB = 30;
  const innerW = W - padL - padR, innerH = H - padT - padB;
  const xs = xLabels || ["-20s","-18s","-16s","-14s","-12s","-10s","-8s","-6s","-4s","-2s","0s"];
  const toX = (i, n) => padL + (i / (n - 1)) * innerW;
  const toY = (v) => padT + (1 - v / 100) * innerH;
  function path(points) {
    const n = points.length;
    return points.map((v, i) => `${i === 0 ? "M" : "L"}${toX(i, n).toFixed(1)},${toY(v).toFixed(1)}`).join(" ");
  }
  const clipPx = padL + clipX * innerW;
  return (
    <svg viewBox={`0 0 ${W} ${H}`} style={{ width: "100%", height, display: "block" }} preserveAspectRatio="none">
      {yTicks.map(t => (
        <g key={t}>
          <line x1={padL} x2={W - padR} y1={toY(t)} y2={toY(t)} stroke="rgba(255,255,255,0.06)" strokeWidth="1" />
          <text x={padL - 8} y={toY(t) + 4} textAnchor="end" fontSize="11" fill="#5e6b7e" fontFamily="var(--mono)">{yLabelFormat ? yLabelFormat(t) : t}</text>
        </g>
      ))}
      {showClip && (
        <g>
          <line x1={clipPx} x2={clipPx} y1={padT} y2={H - padB} stroke="var(--c-clip)" strokeWidth="1.5" strokeDasharray="4 4" opacity="0.8" />
          <circle cx={clipPx} cy={padT + 2} r="3.5" fill="var(--c-clip)" />
          <text x={clipPx} y={padT - 4} textAnchor="middle" fontSize="11" fontWeight="700" fill="var(--c-clip)" fontFamily="var(--font)">CLIP</text>
        </g>
      )}
      {series.map((s, idx) => (
        <path key={idx} d={path(s.points)} fill="none" stroke={s.color} strokeWidth={s.width || 2.4}
          strokeLinejoin="round" strokeLinecap="round" opacity={s.opacity || 1}
          vectorEffect="non-scaling-stroke" />
      ))}
      {xs.map((lb, i) => (
        <text key={i} x={padL + (i / (xs.length - 1)) * innerW} y={H - 8} textAnchor="middle"
          fontSize="11" fill="#5e6b7e" fontFamily="var(--mono)">{lb}</text>
      ))}
    </svg>
  );
}

function SpectrumBars({ values, height = 200 }) {
  const W = 600, H = 240, padL = 34, padB = 26, padT = 8, padR = 4;
  const innerW = W - padL - padR, innerH = H - padB - padT;
  const n = values.length;
  const bw = innerW / n;
  const color = (f) => {
    if (f < 0.28) return "#3b82f6";
    if (f < 0.5) return "#22b8a6";
    if (f < 0.68) return "#2fb84d";
    return "#f59e0b";
  };
  const yLabels = [["-20", 0.18], ["-40", 0.42], ["-60", 0.66], ["-80", 0.9]];
  const xLabels = [["20Hz", 0.0], ["100Hz", 0.22], ["1kHz", 0.5], ["10kHz", 0.78], ["20kHz", 1.0]];
  return (
    <svg viewBox={`0 0 ${W} ${H}`} style={{ width: "100%", height, display: "block" }} preserveAspectRatio="none">
      {yLabels.map(([lb, p]) => (
        <text key={lb} x={padL - 6} y={padT + p * innerH + 4} textAnchor="end" fontSize="10" fill="#5e6b7e" fontFamily="var(--mono)">{lb}</text>
      ))}
      {values.map((v, i) => {
        const h = (v / 100) * innerH;
        const f = i / n;
        return <rect key={i} x={padL + i * bw + bw * 0.12} y={padT + innerH - h} width={bw * 0.76} height={Math.max(2, h)} rx="1.5" fill={color(f)} opacity="0.92" />;
      })}
      {xLabels.map(([lb, p]) => (
        <text key={lb} x={padL + p * innerW} y={H - 6}
          textAnchor={p === 0 ? "start" : p === 1 ? "end" : "middle"}
          fontSize="10" fill="#5e6b7e" fontFamily="var(--mono)">{lb}</text>
      ))}
    </svg>
  );
}

function ActivityMeter({ values, height = 64 }) {
  const color = (v) => v < 8 ? "#4a566a" : v < 35 ? "#f4503f" : v < 62 ? "#f59e0b" : "#2fb84d";
  return (
    <div style={{ display: "flex", alignItems: "flex-end", gap: 1.5, height, width: "100%" }}>
      {values.map((v, i) => (
        <div key={i} style={{ flex: 1, height: `${Math.max(6, v)}%`, background: color(v), borderRadius: 1, minWidth: 0, transition: "height .12s linear" }} />
      ))}
    </div>
  );
}

function RingGauge({ value, size = 132, stroke = 11, label, sub }) {
  const r = (size - stroke) / 2, c = 2 * Math.PI * r;
  const off = c * (1 - value / 100);
  const col = value >= 85 ? "var(--grade-good)" : value >= 70 ? "var(--grade-warn)" : "var(--grade-high)";
  return (
    <div style={{ position: "relative", width: size, height: size }}>
      <svg width={size} height={size} style={{ transform: "rotate(-90deg)" }}>
        <circle cx={size/2} cy={size/2} r={r} fill="none" stroke="rgba(255,255,255,0.08)" strokeWidth={stroke} />
        <circle cx={size/2} cy={size/2} r={r} fill="none" stroke={col} strokeWidth={stroke} strokeLinecap="round"
          strokeDasharray={c} strokeDashoffset={off} style={{ transition: "stroke-dashoffset .8s var(--ease)" }} />
      </svg>
      <div style={{ position: "absolute", inset: 0, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center" }}>
        <div style={{ fontFamily: "var(--mono)", fontWeight: 600, fontSize: size * 0.26, color: col, lineHeight: 1 }}>{value}</div>
        {sub && <div style={{ fontSize: 10, letterSpacing: ".1em", textTransform: "uppercase", color: "var(--fg-3)", marginTop: 5, fontWeight: 700 }}>{sub}</div>}
      </div>
    </div>
  );
}

function Sparkline({ points, color = "var(--accent)", width = 120, height = 34, fill = true }) {
  const min = Math.min(...points), max = Math.max(...points);
  const rng = max - min || 1;
  const pad = 3;
  const toX = (i) => pad + (i / (points.length - 1)) * (width - pad * 2);
  const toY = (v) => pad + (1 - (v - min) / rng) * (height - pad * 2);
  const d = points.map((v, i) => `${i === 0 ? "M" : "L"}${toX(i).toFixed(1)},${toY(v).toFixed(1)}`).join(" ");
  const area = `${d} L${toX(points.length-1)},${height} L${toX(0)},${height} Z`;
  const gid = "sg" + Math.round(toX(1) * 1000 + points[0]);
  return (
    <svg width={width} height={height} style={{ display: "block" }}>
      {fill && <defs><linearGradient id={gid} x1="0" y1="0" x2="0" y2="1">
        <stop offset="0" stopColor={color} stopOpacity="0.3" />
        <stop offset="1" stopColor={color} stopOpacity="0" />
      </linearGradient></defs>}
      {fill && <path d={area} fill={`url(#${gid})`} />}
      <path d={d} fill="none" stroke={color} strokeWidth="2" strokeLinejoin="round" strokeLinecap="round" />
    </svg>
  );
}

function MiniBars({ values, color = "var(--grade-good)", height = 40 }) {
  return (
    <div style={{ display: "flex", alignItems: "flex-end", gap: 2, height }}>
      {values.map((v, i) => (
        <div key={i} style={{ flex: 1, height: `${Math.max(8, v)}%`, background: color, opacity: 0.4 + (v/100)*0.6, borderRadius: 1 }} />
      ))}
    </div>
  );
}

function BalanceBar({ value }) {
  const pct = 50 + value * 50;
  return (
    <div style={{ position: "relative", height: 6, background: "var(--bg-3)", borderRadius: 999 }}>
      <div style={{ position: "absolute", left: "50%", top: -3, bottom: -3, width: 1, background: "var(--line-2)" }} />
      <div style={{ position: "absolute", top: 0, bottom: 0, left: `${Math.min(50, pct)}%`, width: `${Math.abs(pct - 50)}%`, background: "var(--accent)", borderRadius: 999 }} />
    </div>
  );
}

Object.assign(window, { LineChart, SpectrumBars, ActivityMeter, RingGauge, Sparkline, MiniBars, BalanceBar });
