import { cn } from "@/lib/cn";

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

export function adminPercent(value: number, total: number): number {
  if (total <= 0 || value <= 0) {
    return 0;
  }
  return Math.round((value / total) * 1000) / 10;
}

/** Horizontal distribution bars with count + percentage. */
export function AdminHorizontalBarChart({
  data,
  total,
  formatValue = (value) => String(value),
  className,
}: {
  data: AdminChartDatum[];
  total: number;
  formatValue?: (value: number) => string;
  className?: string;
}) {
  const max = Math.max(...data.map((item) => item.value), 1);

  return (
    <div className={cn("space-y-3", className)} role="img" aria-label="Distribution chart">
      {data.map((item) => {
        const pct = adminPercent(item.value, total);
        const widthPct = Math.max((item.value / max) * 100, item.value > 0 ? 2 : 0);

        return (
          <div key={item.key} className="space-y-1.5">
            <div className="flex items-baseline justify-between gap-3 text-[0.8125rem]">
              <span className="font-medium text-primary">{item.label}</span>
              <span className="shrink-0 tabular-nums text-ink-60">
                {formatValue(item.value)}
                <span className="ml-2 text-[0.75rem] text-ink-40">{pct}%</span>
              </span>
            </div>
            <div className="h-2 overflow-hidden rounded-full bg-line/50">
              <div
                className="h-full rounded-full transition-[width] duration-300 motion-reduce:transition-none"
                style={{ width: `${widthPct}%`, backgroundColor: item.color }}
              />
            </div>
          </div>
        );
      })}
    </div>
  );
}

/** Compact donut using stroke-dasharray segments. */
export function AdminDonutChart({
  data,
  total,
  centerLabel,
  centerValue,
  className,
}: {
  data: AdminChartDatum[];
  total: number;
  centerLabel: string;
  centerValue: string | number;
  className?: string;
}) {
  const size = 148;
  const stroke = 18;
  const radius = (size - stroke) / 2;
  const circumference = 2 * Math.PI * radius;
  let offset = 0;

  const segments =
    total > 0
      ? data
          .filter((item) => item.value > 0)
          .map((item) => {
            const length = (item.value / total) * circumference;
            const segment = { ...item, length, offset };
            offset += length;
            return segment;
          })
      : [];

  return (
    <div className={cn("flex flex-col items-center gap-4 sm:flex-row sm:items-center", className)}>
      <div className="relative shrink-0" style={{ width: size, height: size }}>
        <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`} aria-hidden="true">
          <circle
            cx={size / 2}
            cy={size / 2}
            r={radius}
            fill="none"
            stroke="rgba(23, 37, 84, 0.08)"
            strokeWidth={stroke}
          />
          {segments.map((segment) => (
            <circle
              key={segment.key}
              cx={size / 2}
              cy={size / 2}
              r={radius}
              fill="none"
              stroke={segment.color}
              strokeWidth={stroke}
              strokeDasharray={`${segment.length} ${circumference - segment.length}`}
              strokeDashoffset={-segment.offset}
              strokeLinecap="butt"
              transform={`rotate(-90 ${size / 2} ${size / 2})`}
            />
          ))}
        </svg>
        <div className="absolute inset-0 flex flex-col items-center justify-center text-center">
          <p className="text-[1.25rem] font-semibold tabular-nums tracking-[-0.02em] text-primary">
            {centerValue}
          </p>
          <p className="text-[0.6875rem] font-medium uppercase tracking-[0.06em] text-ink-40">
            {centerLabel}
          </p>
        </div>
      </div>

      <ul className="w-full min-w-0 space-y-2">
        {data.map((item) => (
          <li key={item.key} className="flex items-center justify-between gap-3 text-[0.8125rem]">
            <span className="flex min-w-0 items-center gap-2">
              <span
                className="size-2.5 shrink-0 rounded-full"
                style={{ backgroundColor: item.color }}
                aria-hidden="true"
              />
              <span className="truncate text-ink-60">{item.label}</span>
            </span>
            <span className="shrink-0 tabular-nums text-primary">
              {item.value}
              <span className="ml-1.5 text-[0.75rem] text-ink-40">
                {adminPercent(item.value, total)}%
              </span>
            </span>
          </li>
        ))}
      </ul>
    </div>
  );
}

/** Aggregate comparison bars for monetary (or numeric) totals — not a time series. */
export function AdminComparisonBarChart({
  data,
  formatValue,
  className,
}: {
  data: AdminChartDatum[];
  formatValue: (value: number) => string;
  className?: string;
}) {
  const max = Math.max(...data.map((item) => item.value), 1);

  return (
    <div className={cn("space-y-4", className)} role="img" aria-label="Aggregate comparison chart">
      {data.map((item) => {
        const heightPct = Math.max((item.value / max) * 100, item.value > 0 ? 4 : 0);

        return (
          <div key={item.key} className="grid grid-cols-[7.5rem_minmax(0,1fr)_auto] items-center gap-3">
            <span className="truncate text-[0.8125rem] font-medium text-primary">{item.label}</span>
            <div className="h-7 overflow-hidden rounded-[10px] bg-line/40">
              <div
                className="flex h-full items-center rounded-[10px] px-2 transition-[width] duration-300 motion-reduce:transition-none"
                style={{
                  width: `${heightPct}%`,
                  backgroundColor: item.color,
                  minWidth: item.value > 0 ? "0.5rem" : 0,
                }}
              />
            </div>
            <span className="min-w-[5.5rem] text-right text-[0.8125rem] font-semibold tabular-nums text-primary">
              {formatValue(item.value)}
            </span>
          </div>
        );
      })}
    </div>
  );
}
