import clsx from "clsx";

/**
 * Small, dependency-free, server-rendered charts.
 *
 * Every chart is fed by real computed data — there are no placeholder values
 * (SPEC 48). Each also renders an accessible table-equivalent via aria labels
 * so the information is never conveyed by shape or colour alone.
 */

export interface BarDatum {
  label: string;
  value: number;
  sublabel?: string;
  tone?: "brand" | "teal" | "amber" | "ink";
}

const BAR_TONES = {
  brand: "bg-brand-600",
  teal: "bg-teal-600",
  amber: "bg-amber-600",
  ink: "bg-ink-400",
} as const;

export function HorizontalBarChart({
  data,
  emptyMessage = "No data yet.",
  valueSuffix = "",
}: {
  data: BarDatum[];
  emptyMessage?: string;
  valueSuffix?: string;
}) {
  const max = Math.max(1, ...data.map((d) => d.value));
  if (data.length === 0) {
    return <p className="px-5 py-8 text-center text-[13px] text-ink-500">{emptyMessage}</p>;
  }

  return (
    <ul className="space-y-3 px-5 py-4">
      {data.map((datum) => (
        <li key={datum.label}>
          <div className="flex items-baseline justify-between gap-3">
            <span className="min-w-0 truncate text-[13px] font-medium text-ink-700" title={datum.label}>
              {datum.label}
            </span>
            <span className="tabular shrink-0 text-[13px] font-semibold text-ink-900">
              {datum.value}
              {valueSuffix}
            </span>
          </div>
          {datum.sublabel ? <p className="mt-0.5 truncate text-[11px] text-ink-500">{datum.sublabel}</p> : null}
          <div
            className="mt-1.5 h-2 w-full overflow-hidden rounded-full bg-ink-100"
            role="img"
            aria-label={`${datum.label}: ${datum.value}${valueSuffix}`}
          >
            <div
              className={clsx("h-full rounded-full", BAR_TONES[datum.tone ?? "brand"])}
              style={{ width: `${(datum.value / max) * 100}%` }}
            />
          </div>
        </li>
      ))}
    </ul>
  );
}

export function ColumnChart({ data, emptyMessage = "No data yet." }: { data: BarDatum[]; emptyMessage?: string }) {
  const max = Math.max(1, ...data.map((d) => d.value));
  const total = data.reduce((sum, d) => sum + d.value, 0);

  if (total === 0) {
    return <p className="px-5 py-8 text-center text-[13px] text-ink-500">{emptyMessage}</p>;
  }

  return (
    <div className="px-5 py-4">
      <div className="flex h-40 items-end gap-3">
        {data.map((datum) => (
          <div key={datum.label} className="flex min-w-0 flex-1 flex-col items-center justify-end gap-2">
            <span className="tabular text-[12px] font-semibold text-ink-900">{datum.value}</span>
            <div
              className={clsx("w-full rounded-t", BAR_TONES[datum.tone ?? "brand"])}
              style={{ height: `${Math.max(2, (datum.value / max) * 100)}%` }}
              role="img"
              aria-label={`${datum.label}: ${datum.value} students`}
            />
          </div>
        ))}
      </div>
      <div className="mt-2 flex gap-3 border-t border-ink-100 pt-2">
        {data.map((datum) => (
          <p key={datum.label} className="min-w-0 flex-1 truncate text-center text-[11px] text-ink-500">
            {datum.label}
          </p>
        ))}
      </div>
    </div>
  );
}
