"use client";

// Dependency-free charts (SVG + CSS), sized to fill their container. Each is
// presentational and accessible (role="img" + an aria-label summary).

export type Segment = { label: string; value: number; color: string };

/** Donut chart with a centred total and a legend. */
export function DonutChart({ segments, centerLabel }: { segments: Segment[]; centerLabel?: string }) {
  const total = segments.reduce((s, x) => s + x.value, 0);
  const r = 15.915_494_31; // circumference = 100, so dasharray works in %
  const summary = segments.map((s) => `${s.label}: ${s.value}`).join(", ");

  let cumulative = 0;
  return (
    <div className="flex items-center gap-4">
      <svg viewBox="0 0 42 42" className="h-28 w-28 shrink-0" role="img" aria-label={`Donut chart — ${summary}`}>
        <circle cx="21" cy="21" r={r} fill="none" stroke="#e2e8f0" strokeWidth="5" />
        {total > 0 &&
          segments
            .filter((s) => s.value > 0)
            .map((s) => {
              const pct = (s.value / total) * 100;
              const el = (
                <circle
                  key={s.label}
                  cx="21"
                  cy="21"
                  r={r}
                  fill="none"
                  stroke={s.color}
                  strokeWidth="5"
                  strokeDasharray={`${pct} ${100 - pct}`}
                  strokeDashoffset={25 - cumulative}
                  transform="rotate(0 21 21)"
                />
              );
              cumulative += pct;
              return el;
            })}
        <text x="21" y="20.5" textAnchor="middle" className="fill-slate-900" style={{ fontSize: 8, fontWeight: 700 }}>
          {total}
        </text>
        <text x="21" y="26" textAnchor="middle" className="fill-slate-400" style={{ fontSize: 3 }}>
          {centerLabel ?? "total"}
        </text>
      </svg>
      <ul className="space-y-1 text-sm">
        {segments.map((s) => (
          <li key={s.label} className="flex items-center gap-2">
            <span className="inline-block h-3 w-3 shrink-0 rounded-xs" style={{ backgroundColor: s.color }} aria-hidden />
            <span className="text-slate-600">{s.label}</span>
            <span className="ml-auto pl-3 font-medium tabular-nums text-slate-800">{s.value}</span>
          </li>
        ))}
      </ul>
    </div>
  );
}

export type Point = { label: string; value: number };

/** Simple line chart with dots and an x-axis label row. */
export function LineChart({
  points,
  formatValue = (n) => String(n),
  color = "#1d4ed8",
}: {
  points: Point[];
  formatValue?: (n: number) => string;
  color?: string;
}) {
  if (points.length === 0) return <p className="py-8 text-center text-sm text-slate-500">No data yet.</p>;

  const W = 320;
  const H = 120;
  const padX = 10;
  const padTop = 12;
  const padBottom = 12;
  const max = Math.max(1, ...points.map((p) => p.value));
  const n = points.length;
  const x = (i: number) => (n === 1 ? W / 2 : padX + (i * (W - 2 * padX)) / (n - 1));
  const y = (v: number) => H - padBottom - (v / max) * (H - padTop - padBottom);
  const poly = points.map((p, i) => `${x(i).toFixed(1)},${y(p.value).toFixed(1)}`).join(" ");
  const summary = points.map((p) => `${p.label}: ${formatValue(p.value)}`).join(", ");

  return (
    <div>
      <svg viewBox={`0 0 ${W} ${H}`} className="w-full" role="img" aria-label={`Line chart — ${summary}`}>
        <line x1={padX} y1={H - padBottom} x2={W - padX} y2={H - padBottom} stroke="#e2e8f0" strokeWidth="1" />
        <polyline points={poly} fill="none" stroke={color} strokeWidth="2" strokeLinejoin="round" strokeLinecap="round" />
        {points.map((p, i) => (
          <circle key={i} cx={x(i)} cy={y(p.value)} r="2.5" fill={color}>
            <title>{`${p.label}: ${formatValue(p.value)}`}</title>
          </circle>
        ))}
        <text x={padX} y={padTop - 4} className="fill-slate-400" style={{ fontSize: 8 }}>
          {formatValue(max)}
        </text>
      </svg>
      <div className="mt-1 flex justify-between text-[10px] text-slate-400">
        {points.map((p, i) => (
          <span key={i}>{p.label}</span>
        ))}
      </div>
    </div>
  );
}

/** CSS column/bar chart (crisp at any width). */
export function BarChart({
  bars,
  formatValue = (n) => String(n),
  color = "#1d4ed8",
}: {
  bars: Point[];
  formatValue?: (n: number) => string;
  color?: string;
}) {
  if (bars.length === 0) return <p className="py-8 text-center text-sm text-slate-500">No data yet.</p>;
  const max = Math.max(1, ...bars.map((b) => b.value));
  const summary = bars.map((b) => `${b.label}: ${formatValue(b.value)}`).join(", ");

  return (
    <div className="flex h-32 items-end gap-2" role="img" aria-label={`Bar chart — ${summary}`}>
      {bars.map((b, i) => (
        <div key={i} className="flex h-full flex-1 flex-col items-center justify-end gap-1" title={`${b.label}: ${formatValue(b.value)}`}>
          <span className="text-[10px] tabular-nums text-slate-500">{b.value > 0 ? formatValue(b.value) : ""}</span>
          <div
            className="w-full rounded-t"
            style={{ height: `${Math.max(2, (b.value / max) * 100)}%`, backgroundColor: color, opacity: b.value > 0 ? 1 : 0.25 }}
          />
          <span className="text-[10px] text-slate-400">{b.label}</span>
        </div>
      ))}
    </div>
  );
}
