// charts.jsx — hand-built SVG charts (no external dep)
(function () {
  const { useState } = React;
  const BLUE = "#2f7fe0", BLUE2 = "#5aa2f5", GREEN = "#12a877", VIOLET = "#6f5be6", AMBER = "#d98a12";
  const GRID = "rgba(17,28,48,0.07)", AXIS = "#93a0b2", DOTBG = "#ffffff", TRACK = "rgba(17,28,48,0.08)";

  // ---- smooth path from points ----
  function smooth(pts) {
    if (!pts.length) return "";
    if (pts.length === 1) return `M ${pts[0][0]} ${pts[0][1]}`;
    let d = `M ${pts[0][0]} ${pts[0][1]}`;
    for (let i = 0; i < pts.length - 1; i++) {
      const [x0, y0] = pts[i], [x1, y1] = pts[i + 1];
      const cx = (x0 + x1) / 2;
      d += ` C ${cx} ${y0}, ${cx} ${y1}, ${x1} ${y1}`;
    }
    return d;
  }

  // ===== Area / Line chart =====
  function AreaChart({ data, labels, height = 220, color = BLUE, color2 = BLUE2, format = (v) => v, yTicks = 4 }) {
    const [hi, setHi] = useState(null);
    const W = 760, H = height, padL = 44, padR = 12, padT = 14, padB = 28;
    const max = ((data.length ? Math.max(...data) : 0) * 1.12) || 1, min = 0; // guards empty/all-zero (Day-0) data -> no NaN
    const iw = W - padL - padR, ih = H - padT - padB;
    const x = (i) => padL + (i / ((data.length - 1) || 1)) * iw;
    const y = (v) => padT + ih - ((v - min) / (max - min)) * ih;
    const pts = data.map((v, i) => [x(i), y(v)]);
    const line = smooth(pts);
    const area = line ? `${line} L ${x(data.length - 1)} ${padT + ih} L ${x(0)} ${padT + ih} Z` : "";
    const id = "ag" + color.replace("#", "");
    const ticks = Array.from({ length: yTicks + 1 }, (_, i) => min + (i / yTicks) * (max - min));
    function move(e) {
      if (!data.length) { setHi(null); return; }
      const r = e.currentTarget.getBoundingClientRect();
      const frac = (e.clientX - r.left) / r.width;
      setHi(Math.max(0, Math.min(data.length - 1, Math.round(frac * (data.length - 1)))));
    }
    return React.createElement("div", { style: { position: "relative" } },
      React.createElement("svg", { viewBox: `0 0 ${W} ${H}`, style: { width: "100%", height: "auto", display: "block" }, onMouseMove: move, onMouseLeave: () => setHi(null) },
      React.createElement("defs", null,
        React.createElement("linearGradient", { id, x1: 0, y1: 0, x2: 0, y2: 1 },
          React.createElement("stop", { offset: "0%", stopColor: color, stopOpacity: 0.34 }),
          React.createElement("stop", { offset: "100%", stopColor: color, stopOpacity: 0 }))),
      ticks.map((t, i) => React.createElement("g", { key: i },
        React.createElement("line", { x1: padL, x2: W - padR, y1: y(t), y2: y(t), stroke: GRID, strokeWidth: 1 }),
        React.createElement("text", { x: padL - 8, y: y(t) + 3.5, fill: AXIS, fontSize: 10.5, textAnchor: "end", fontFamily: "JetBrains Mono" }, format(Math.round(t))))),
      React.createElement("path", { d: area, fill: `url(#${id})` }),
      React.createElement("path", { d: line, fill: "none", stroke: color, strokeWidth: 2.4, strokeLinecap: "round" }),
      hi != null && React.createElement("line", { x1: x(hi), x2: x(hi), y1: padT, y2: padT + ih, stroke: color, strokeWidth: 1, strokeDasharray: "4 4", opacity: 0.5 }),
      pts.map((p, i) => React.createElement("circle", { key: i, cx: p[0], cy: p[1], r: hi === i ? 4.5 : 2.6, fill: hi === i ? color : DOTBG, stroke: color, strokeWidth: 2 })),
      labels.map((l, i) => React.createElement("text", { key: i, x: x(i), y: H - 8, fill: hi === i ? color : AXIS, fontSize: 10.5, fontWeight: hi === i ? 700 : 400, textAnchor: "middle", fontFamily: "JetBrains Mono" }, l))),
      hi != null && React.createElement("div", { style: { position: "absolute", left: `${(x(hi) / W) * 100}%`, top: `${(y(data[hi]) / H) * 100}%`, transform: "translate(-50%, -130%)", pointerEvents: "none",
        background: "var(--text)", color: "var(--bg-2)", padding: "5px 9px", borderRadius: 7, fontSize: 11.5, fontWeight: 600, whiteSpace: "nowrap", boxShadow: "var(--shadow-lg)", fontFamily: "var(--mono)" } },
        labels[hi] + " · " + format(data[hi])));
  }

  // ===== Multi-line chart =====
  function MultiLine({ series, labels, height = 220, format = (v) => v }) {
    const [hi, setHi] = useState(null);
    const W = 760, H = height, padL = 44, padR = 12, padT = 14, padB = 28;
    const all = series.flatMap((s) => s.data);
    const max = ((all.length ? Math.max(...all) : 0) * 1.12) || 1, min = Math.min(...all, 0); // guards empty/all-zero data -> no NaN
    const iw = W - padL - padR, ih = H - padT - padB;
    const n = labels.length;
    const x = (i, m) => padL + (i / ((((m || n) - 1) || 1))) * iw;
    const y = (v) => padT + ih - ((v - min) / (max - min)) * ih;
    const ticks = Array.from({ length: 5 }, (_, i) => min + (i / 4) * (max - min));
    function move(e) {
      if (!n) { setHi(null); return; }
      const r = e.currentTarget.getBoundingClientRect();
      const frac = (e.clientX - r.left) / r.width;
      setHi(Math.max(0, Math.min(n - 1, Math.round(frac * (n - 1)))));
    }
    return React.createElement("div", { style: { position: "relative" } },
      React.createElement("svg", { viewBox: `0 0 ${W} ${H}`, style: { width: "100%", height: "auto", display: "block" }, onMouseMove: move, onMouseLeave: () => setHi(null) },
      ticks.map((t, i) => React.createElement("g", { key: i },
        React.createElement("line", { x1: padL, x2: W - padR, y1: y(t), y2: y(t), stroke: GRID }),
        React.createElement("text", { x: padL - 8, y: y(t) + 3.5, fill: AXIS, fontSize: 10.5, textAnchor: "end", fontFamily: "JetBrains Mono" }, format(Math.round(t * 10) / 10)))),
      hi != null && React.createElement("line", { x1: x(hi), x2: x(hi), y1: padT, y2: padT + ih, stroke: AXIS, strokeWidth: 1, strokeDasharray: "4 4", opacity: 0.5 }),
      series.map((s, si) => {
        const pts = s.data.map((v, i) => [x(i, s.data.length), y(v)]);
        return React.createElement("g", { key: si },
          React.createElement("path", { d: smooth(pts), fill: "none", stroke: s.color, strokeWidth: 2.4, strokeLinecap: "round" }),
          pts.map((p, i) => React.createElement("circle", { key: i, cx: p[0], cy: p[1], r: hi === i ? 4.2 : 2.4, fill: hi === i ? s.color : DOTBG, stroke: s.color, strokeWidth: 2 })));
      }),
      labels.map((l, i) => React.createElement("text", { key: i, x: x(i, labels.length), y: H - 8, fill: hi === i ? "var(--text)" : AXIS, fontSize: 10.5, fontWeight: hi === i ? 700 : 400, textAnchor: "middle", fontFamily: "JetBrains Mono" }, l))),
      hi != null && React.createElement("div", { style: { position: "absolute", left: `${(x(hi) / W) * 100}%`, top: 8, transform: `translateX(${hi > n / 2 ? "-110%" : "10%"})`, pointerEvents: "none",
        background: "var(--text)", color: "var(--bg-2)", padding: "7px 10px", borderRadius: 8, fontSize: 11.5, whiteSpace: "nowrap", boxShadow: "var(--shadow-lg)" } },
        React.createElement("div", { style: { fontWeight: 700, marginBottom: 4, fontFamily: "var(--mono)" } }, labels[hi]),
        series.map((s, si) => React.createElement("div", { key: si, style: { display: "flex", alignItems: "center", gap: 6, fontFamily: "var(--mono)", fontWeight: 600 } },
          React.createElement("span", { style: { width: 8, height: 8, borderRadius: 2, background: s.color, display: "inline-block" } }), format(s.data[hi])))));
  }

  // ===== Vertical bars (optionally stacked 2-series) =====
  function BarChart({ data, labels, height = 220, color = BLUE, color2, format = (v) => v }) {
    const W = 760, H = height, padL = 44, padR = 12, padT = 14, padB = 28;
    const stacked = color2 && Array.isArray(data[0]);
    const totals = stacked ? data.map((d) => d[0] + d[1]) : data;
    const max = ((totals.length ? Math.max(...totals) : 0) * 1.15) || 1;
    const iw = W - padL - padR, ih = H - padT - padB;
    const n = Math.max(labels.length, 1), bw = (iw / n) * 0.52;
    const cx = (i) => padL + (i + 0.5) * (iw / n);
    const y = (v) => padT + ih - (v / max) * ih;
    const ticks = Array.from({ length: 5 }, (_, i) => (i / 4) * max);
    return React.createElement("svg", { viewBox: `0 0 ${W} ${H}`, style: { width: "100%", height: "auto", display: "block" } },
      React.createElement("defs", null,
        React.createElement("linearGradient", { id: "bg1", x1: 0, y1: 0, x2: 0, y2: 1 },
          React.createElement("stop", { offset: "0%", stopColor: color, stopOpacity: 0.95 }),
          React.createElement("stop", { offset: "100%", stopColor: color, stopOpacity: 0.5 }))),
      ticks.map((t, i) => React.createElement("g", { key: i },
        React.createElement("line", { x1: padL, x2: W - padR, y1: y(t), y2: y(t), stroke: GRID }),
        React.createElement("text", { x: padL - 8, y: y(t) + 3.5, fill: AXIS, fontSize: 10.5, textAnchor: "end", fontFamily: "JetBrains Mono" }, format(Math.round(t))))),
      labels.map((l, i) => {
        if (stacked) {
          const [a, b] = data[i];
          return React.createElement("g", { key: i },
            React.createElement("rect", { x: cx(i) - bw / 2, y: y(a), width: bw, height: (padT + ih) - y(a), fill: color, rx: 3 }),
            React.createElement("rect", { x: cx(i) - bw / 2, y: y(a + b), width: bw, height: y(a) - y(a + b), fill: color2, rx: 3 }));
        }
        const v = data[i];
        return React.createElement("rect", { key: i, x: cx(i) - bw / 2, y: y(v), width: bw, height: (padT + ih) - y(v), fill: "url(#bg1)", rx: 3 });
      }),
      labels.map((l, i) => React.createElement("text", { key: "l" + i, x: cx(i), y: H - 8, fill: AXIS, fontSize: 10.5, textAnchor: "middle", fontFamily: "JetBrains Mono" }, l)));
  }

  // ===== Horizontal bars =====
  function HBars({ items, format = (v) => v, color = BLUE, height }) {
    const values = items.map((i) => i.value);
    const max = ((values.length ? Math.max(...values) : 0) * 1.05) || 1;
    return React.createElement("div", { style: { display: "flex", flexDirection: "column", gap: 13 } },
      items.map((it, i) => React.createElement("div", { key: i },
        React.createElement("div", { style: { display: "flex", justifyContent: "space-between", marginBottom: 6, fontSize: 12.5 } },
          React.createElement("span", { style: { color: "var(--text-dim)" } }, it.label),
          React.createElement("span", { className: "mono", style: { color: "var(--text)", fontWeight: 600 } }, format(it.value))),
        React.createElement("div", { className: "bar", style: { height: 8 } },
          React.createElement("i", { style: { width: `${(it.value / max) * 100}%`, background: it.color ? it.color : undefined } })))));
  }

  // ===== Donut =====
  function Donut({ segments, size = 150, thickness = 18, center }) {
    const r = (size - thickness) / 2, c = size / 2, circ = 2 * Math.PI * r;
    const total = segments.reduce((s, x) => s + x.value, 0) || 1;
    let acc = 0;
    return React.createElement("div", { style: { position: "relative", width: size, height: size } },
      React.createElement("svg", { width: size, height: size, viewBox: `0 0 ${size} ${size}`, style: { transform: "rotate(-90deg)" } },
        React.createElement("circle", { cx: c, cy: c, r, fill: "none", stroke: TRACK, strokeWidth: thickness }),
        segments.map((s, i) => {
          const len = (s.value / total) * circ;
          const el = React.createElement("circle", { key: i, cx: c, cy: c, r, fill: "none", stroke: s.color, strokeWidth: thickness, strokeDasharray: `${len} ${circ - len}`, strokeDashoffset: -acc, strokeLinecap: "round" });
          acc += len; return el;
        })),
      center && React.createElement("div", { style: { position: "absolute", inset: 0, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center" } }, center));
  }

  // ===== Sparkline =====
  function Spark({ data, color = GREEN, width = 90, height = 30 }) {
    const max = data.length ? Math.max(...data) : 1, min = data.length ? Math.min(...data) : 0;
    const x = (i) => (i / ((data.length - 1) || 1)) * width;
    const y = (v) => height - 2 - ((v - min) / (max - min || 1)) * (height - 4);
    const pts = data.map((v, i) => [x(i), y(v)]);
    return React.createElement("svg", { width, height, viewBox: `0 0 ${width} ${height}` },
      React.createElement("path", { d: smooth(pts), fill: "none", stroke: color, strokeWidth: 1.8, strokeLinecap: "round" }));
  }

  // ===== Radial gauge (single value 0-100) =====
  function Gauge({ value, size = 120, color = GREEN, label }) {
    const r = size / 2 - 10, c = size / 2, circ = Math.PI * r; // half
    const len = (value / 100) * circ;
    return React.createElement("div", { style: { position: "relative", width: size, height: size / 2 + 14 } },
      React.createElement("svg", { width: size, height: size / 2 + 14, viewBox: `0 0 ${size} ${size / 2 + 14}` },
        React.createElement("path", { d: `M 10 ${c} A ${r} ${r} 0 0 1 ${size - 10} ${c}`, fill: "none", stroke: TRACK, strokeWidth: 9, strokeLinecap: "round" }),
        React.createElement("path", { d: `M 10 ${c} A ${r} ${r} 0 0 1 ${size - 10} ${c}`, fill: "none", stroke: color, strokeWidth: 9, strokeLinecap: "round", strokeDasharray: `${len} ${circ}` })),
      React.createElement("div", { style: { position: "absolute", bottom: 0, width: "100%", textAlign: "center" } },
        React.createElement("div", { className: "mono", style: { fontSize: 22, fontWeight: 700 } }, value + "%"),
        label && React.createElement("div", { style: { fontSize: 11, color: "var(--text-faint)" } }, label)));
  }

  Object.assign(window, { AreaChart, MultiLine, BarChart, HBars, Donut, Spark, Gauge, CHART_COLORS: { BLUE, BLUE2, GREEN, VIOLET, AMBER } });
})();
