// ui/charts.jsx — the SVG charts (donut, trend, bars, sparkline).
/* ====================================================== CHARTS (svg) */

/* Donut — severity distribution */
function Donut({ data, total, size = 168, thickness = 22 }) {
  const r = (size - thickness) / 2;
  const c = 2 * Math.PI * r;
  let offset = 0;
  const cx = size / 2;
  // `total` is the real count shown in the centre (may be 0); use a non-zero
  // denominator only for the arc geometry so an empty set renders a clean ring.
  const denom = total || 1;
  return (
    <div className="donut-wrap">
      <svg width={size} height={size} className="donut">
        <circle cx={cx} cy={cx} r={r} fill="none" stroke="var(--line)" strokeWidth={thickness} opacity="0.5" />
        {data.map((d, i) => {
          const frac = d.value / denom;
          const dash = frac * c;
          const el = (
            <circle key={i} cx={cx} cy={cx} r={r} fill="none"
              stroke={d.color} strokeWidth={thickness}
              strokeDasharray={`${dash} ${c - dash}`}
              strokeDashoffset={-offset}
              transform={`rotate(-90 ${cx} ${cx})`}
              style={{ transition: "stroke-dasharray .6s ease" }} />
          );
          offset += dash;
          return el;
        })}
      </svg>
      <div className="donut-center">
        <span className="donut-num">{total}</span>
        <span className="donut-lab">tracked</span>
      </div>
    </div>
  );
}

/* Area trend — total vulnerabilities ingested over weeks */
function TrendChart({ trend, width = 560, height = 180 }) {
  const pad = { l: 8, r: 8, t: 14, b: 22 };
  const w = width - pad.l - pad.r, h = height - pad.t - pad.b;
  const tot = (d) => d.auto + d.iot;
  const max = Math.max(...trend.map(tot)) * 1.1;
  const x = (i) => pad.l + (i / (trend.length - 1)) * w;
  const y = (v) => pad.t + h - (v / max) * h;
  const areaPath = (key, base) => {
    const top = trend.map((d, i) => `${x(i)},${y(base(d) + d[key])}`);
    const bot = trend.map((d, i) => `${x(i)},${y(base(d))}`).reverse();
    return `M${top.join(" L")} L${bot.join(" L")} Z`;
  };
  const linePath = (fn) => "M" + trend.map((d, i) => `${x(i)},${y(fn(d))}`).join(" L");
  return (
    <svg width="100%" viewBox={`0 0 ${width} ${height}`} className="trend" preserveAspectRatio="none">
      {[0.25, 0.5, 0.75, 1].map((g, i) => (
        <line key={i} x1={pad.l} x2={width - pad.r} y1={pad.t + h - g * h} y2={pad.t + h - g * h}
          stroke="var(--line)" strokeWidth="1" opacity="0.5" />
      ))}
      <path d={`M${trend.map((d, i) => `${x(i)},${y(tot(d))}`).join(" L")} L${x(trend.length - 1)},${pad.t + h} L${x(0)},${pad.t + h} Z`} fill="var(--trend-line)" opacity="0.28" />
      <path d={linePath(tot)} fill="none" stroke="var(--trend-line)" strokeWidth="2.5" />
      {trend.map((d, i) => (
        i % 2 === 0 ? <text key={i} x={x(i)} y={height - 6} className="trend-x">{d.week}</text> : null
      ))}
    </svg>
  );
}

/* Horizontal bars — top ECUs */
function BarChart({ data, accent = "var(--viz)" }) {
  if (!data || !data.length) {
    return (
      <div className="card-empty">
        <Icon name="layers" size={22} />
        <span className="card-empty-title">No components yet</span>
        <span className="card-empty-sub">Upload an SBOM to see your most affected ECUs.</span>
      </div>
    );
  }
  const max = Math.max(...data.map(d => d.count));
  return (
    <div className="barchart">
      {data.map((d, i) => (
        <div className="barrow" key={i}>
          <span className="barrow-lab">{d.name}</span>
          <div className="barrow-track">
            <div className="barrow-fill" style={{ width: (d.count / max * 100) + "%", background: accent }} />
          </div>
          <span className="barrow-val">{d.count}</span>
        </div>
      ))}
    </div>
  );
}

/* Sparkline */
function Sparkline({ values, width = 88, height = 28, color = "var(--accent)" }) {
  const max = Math.max(...values), min = Math.min(...values);
  const x = (i) => (i / (values.length - 1)) * width;
  const y = (v) => height - ((v - min) / (max - min || 1)) * (height - 4) - 2;
  const d = "M" + values.map((v, i) => `${x(i).toFixed(1)},${y(v).toFixed(1)}`).join(" L");
  return (
    <svg width={width} height={height} className="spark">
      <path d={d} fill="none" stroke={color} strokeWidth="1.6" strokeLinecap="round" />
      <circle cx={x(values.length - 1)} cy={y(values[values.length - 1])} r="2.2" fill={color} />
    </svg>
  );
}

Object.assign(window, { Donut, TrendChart, BarChart, Sparkline });
