"use client";

import {
  animate,
  motion,
  useInView,
  useMotionTemplate,
  useMotionValue,
  useReducedMotion,
  useTransform,
} from "motion/react";
import { useEffect, useRef, type ReactNode } from "react";
import { cn } from "@/lib/utils";

type DonutChartProps = {
  /** Primary share, 0–100 (the ink wedge). */
  value: number;
  /** Big serif figure in the centre (e.g. a <Counter />). */
  centerValue?: ReactNode;
  /** Caption under the figure. */
  centerCaption?: string;
  /** Diameter in px. Default 320. */
  size?: number;
  className?: string;
};

/**
 * DonutChart — the event-deck conic donut (part / whole split).
 *
 * Two-phase build (matches the deck): the ink wedge grows 0 → value (950 ms),
 * then the accent fills value → 100 (750 ms), over a punched-out paper hole.
 * A `<Counter />` in `centerValue` should start on phase one (delay ~0.35 s).
 * See sd EVENT-DECK.md → donut.
 */
export function DonutChart({
  value,
  centerValue,
  centerCaption,
  size = 320,
  className,
}: DonutChartProps) {
  const ref = useRef<HTMLDivElement>(null);
  const inView = useInView(ref, { once: true, amount: 0.4 });
  const reduce = useReducedMotion();

  const pb = useMotionValue(reduce ? value : 0); // ink stop %
  const py = useMotionValue(reduce ? 100 : 0); // accent stop %
  const pbPct = useTransform(pb, (v) => `${v}%`);
  const pyPct = useTransform(py, (v) => `${v}%`);
  const background = useMotionTemplate`conic-gradient(var(--ink-900) 0 ${pbPct}, var(--accent-500) ${pbPct} ${pyPct}, var(--ink-100) ${pyPct} 100%)`;

  useEffect(() => {
    if (!inView || reduce) return;
    const ease = [0.22, 1, 0.36, 1] as const;
    const a = animate(pb, value, { duration: 0.95, delay: 0.35, ease });
    const b = animate(py, value, { duration: 0.95, delay: 0.35, ease });
    const c = animate(py, 100, { duration: 0.75, delay: 1.3, ease });
    return () => {
      a.stop();
      b.stop();
      c.stop();
    };
  }, [inView, reduce, value, pb, py]);

  return (
    <div
      ref={ref}
      className={cn(className)}
      style={{ width: size, height: size, position: "relative", display: "grid", placeItems: "center" }}
    >
      <motion.div style={{ background, position: "absolute", inset: 0, borderRadius: "50%" }} />
      <div style={{ position: "absolute", inset: "21%", borderRadius: "50%", background: "var(--paper)" }} />
      <div
        style={{
          position: "relative",
          zIndex: 1,
          display: "flex",
          flexDirection: "column",
          alignItems: "center",
          gap: "var(--space-1)",
        }}
      >
        {centerValue != null && (
          <div
            style={{
              fontFamily: "var(--font-display)",
              fontSize: `clamp(40px, ${Math.round(size * 0.18)}px, 98px)`,
              lineHeight: 1,
              color: "var(--ink-900)",
            }}
          >
            {centerValue}
          </div>
        )}
        {centerCaption && (
          <div
            style={{
              fontFamily: "var(--font-display)",
              fontSize: "clamp(16px, 1.6vw, 26px)",
              color: "var(--ink-800)",
            }}
          >
            {centerCaption}
          </div>
        )}
      </div>
    </div>
  );
}
