"use client";

import { useRef, useState } from "react";
import { cn } from "./cn";

const BRAND = "#1A3C6E";

/* ------------------------------------------------ Area / line (time series)
   Single series → no legend; the card title names it. Thin 2px line, soft
   area, recessive grid, hover crosshair + tooltip. */
export function AreaChart({
  data,
  height = 220,
  format = (n) => String(n),
  color = BRAND,
}: {
  data: { label: string; value: number }[];
  height?: number;
  format?: (n: number) => string;
  color?: string;
}) {
  const wrapRef = useRef<HTMLDivElement>(null);
  const [hover, setHover] = useState<number | null>(null);
  const W = 640;
  const H = height;
  const padL = 8;
  const padR = 8;
  const padT = 12;
  const padB = 26;
  const n = data.length;
  const max = Math.max(1, ...data.map((d) => d.value));
  const x = (i: number) => padL + (i * (W - padL - padR)) / Math.max(1, n - 1);
  const y = (v: number) => H - padB - (v / max) * (H - padT - padB);

  const line = data.map((d, i) => `${i === 0 ? "M" : "L"}${x(i)},${y(d.value)}`).join(" ");
  const area = `${line} L${x(n - 1)},${H - padB} L${x(0)},${H - padB} Z`;
  const grid = [0.25, 0.5, 0.75, 1].map((f) => H - padB - f * (H - padT - padB));

  const onMove = (e: React.MouseEvent) => {
    const rect = wrapRef.current?.getBoundingClientRect();
    if (!rect) return;
    const ratio = Math.min(1, Math.max(0, (e.clientX - rect.left) / rect.width));
    setHover(Math.round(ratio * (n - 1)));
  };

  const tickIdx = [0, Math.floor(n / 3), Math.floor((2 * n) / 3), n - 1];

  return (
    <div ref={wrapRef} className="relative" onMouseMove={onMove} onMouseLeave={() => setHover(null)}>
      <svg viewBox={`0 0 ${W} ${H}`} width="100%" height={H} preserveAspectRatio="none" className="overflow-visible">
        <defs>
          <linearGradient id="pnArea" x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%" stopColor={color} stopOpacity="0.18" />
            <stop offset="100%" stopColor={color} stopOpacity="0" />
          </linearGradient>
        </defs>
        {grid.map((gy, i) => (
          <line key={i} x1={padL} x2={W - padR} y1={gy} y2={gy} stroke="#eef1f5" strokeWidth={1} />
        ))}
        <path d={area} fill="url(#pnArea)" />
        <path d={line} fill="none" stroke={color} strokeWidth={2} strokeLinejoin="round" strokeLinecap="round" />
        {hover != null && (
          <>
            <line x1={x(hover)} x2={x(hover)} y1={padT} y2={H - padB} stroke={color} strokeOpacity={0.3} strokeWidth={1} />
            <circle cx={x(hover)} cy={y(data[hover].value)} r={4} fill="#fff" stroke={color} strokeWidth={2} />
          </>
        )}
      </svg>
      {/* x labels */}
      <div className="mt-1 flex justify-between px-1 text-[10px] text-gray-400">
        {tickIdx.map((i) => (
          <span key={i}>{data[i]?.label}</span>
        ))}
      </div>
      {/* tooltip */}
      {hover != null && (
        <div
          className="pointer-events-none absolute top-0 z-10 -translate-x-1/2 rounded-lg border border-gray-200 bg-white px-2.5 py-1.5 text-xs shadow-md"
          style={{ left: `${(hover / Math.max(1, n - 1)) * 100}%` }}
        >
          <div className="font-medium text-gray-900">{format(data[hover].value)}</div>
          <div className="text-gray-400">{data[hover].label}</div>
        </div>
      )}
    </div>
  );
}

/* -------------------------------------------- Horizontal bars (ranking) */
export function BarList({
  data,
  format = (n) => String(n),
  color = BRAND,
}: {
  data: { label: string; value: number; sub?: string }[];
  format?: (n: number) => string;
  color?: string;
}) {
  const max = Math.max(1, ...data.map((d) => d.value));
  return (
    <div className="space-y-3">
      {data.map((d, i) => (
        <div key={i} className="flex items-center gap-3">
          <div className="w-28 shrink-0 truncate text-sm text-gray-700" title={d.label}>
            {d.label}
          </div>
          <div className="h-2.5 flex-1 overflow-hidden rounded-full bg-gray-100">
            <div
              className="h-full rounded-full transition-all"
              style={{ width: `${Math.max(4, (d.value / max) * 100)}%`, backgroundColor: color }}
            />
          </div>
          <div className="w-20 shrink-0 text-right text-sm font-medium text-gray-900">{format(d.value)}</div>
        </div>
      ))}
    </div>
  );
}

/* ---------------------------------------------------- Donut (status split)
   Status colours (reserved) + a labelled legend → identity is never colour
   alone. */
export function Donut({
  data,
  size = 150,
  centerLabel,
  centerValue,
}: {
  data: { label: string; value: number; color: string }[];
  size?: number;
  centerLabel?: string;
  centerValue?: string | number;
}) {
  const total = data.reduce((s, d) => s + d.value, 0);
  const r = size / 2 - 12;
  const c = 2 * Math.PI * r;
  let offset = 0;

  return (
    <div className="flex flex-col items-center gap-4 sm:flex-row sm:justify-center">
      <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
        <g transform={`rotate(-90 ${size / 2} ${size / 2})`}>
          <circle cx={size / 2} cy={size / 2} r={r} fill="none" stroke="#eef1f5" strokeWidth={14} />
          {total > 0 &&
            data.map((d, i) => {
              const frac = d.value / total;
              const dash = frac * c;
              const seg = (
                <circle
                  key={i}
                  cx={size / 2}
                  cy={size / 2}
                  r={r}
                  fill="none"
                  stroke={d.color}
                  strokeWidth={14}
                  strokeDasharray={`${Math.max(0, dash - 2)} ${c - Math.max(0, dash - 2)}`}
                  strokeDashoffset={-offset}
                  strokeLinecap="round"
                />
              );
              offset += dash;
              return seg;
            })}
        </g>
        <text x="50%" y="46%" textAnchor="middle" className="fill-gray-900 text-lg font-bold">
          {centerValue ?? total}
        </text>
        <text x="50%" y="60%" textAnchor="middle" className="fill-gray-400 text-[10px] uppercase tracking-wide">
          {centerLabel ?? "Total"}
        </text>
      </svg>
      <div className="space-y-1.5">
        {data.map((d, i) => (
          <div key={i} className="flex items-center gap-2 text-sm">
            <span className={cn("h-2.5 w-2.5 rounded-sm")} style={{ backgroundColor: d.color }} />
            <span className="text-gray-600">{d.label}</span>
            <span className="ml-auto font-medium text-gray-900">{d.value}</span>
          </div>
        ))}
      </div>
    </div>
  );
}
