"use client";

import { motion } from "motion/react";
import { ChartFrame } from "./chart-frame";
import { linearScale, niceTicks } from "@/lib/chart-utils";

export type BoxGroup = {
  label: string;
  min: number;
  q1: number;
  median: number;
  q3: number;
  max: number;
};

type BoxPlotProps = {
  data: BoxGroup[];
  width?: number;
  height?: number;
  className?: string;
};

const M = { top: 16, right: 18, bottom: 34, left: 44 };

/** BoxPlot — whiskers fade/draw, box grows scaleY from the median, median line lands last. */
export function BoxPlot({ data, width = 600, height = 360, className }: BoxPlotProps) {
  const lo = Math.min(...data.map((d) => d.min));
  const hi = Math.max(...data.map((d) => d.max));
  const sy = linearScale([lo, hi], [height - M.bottom, M.top]);
  const ticks = niceTicks(lo, hi, 4);
  const plotW = width - M.left - M.right;
  const step = plotW / data.length;
  const bw = Math.min(step * 0.5, 60);

  return (
    <ChartFrame width={width} height={height} label="Diagrama de caja" className={className}>
      {({ inView, reduce }) => (
        <>
          {ticks.map((t) => (
            <g key={t}>
              <line x1={M.left} x2={width - M.right} y1={sy(t)} y2={sy(t)} stroke="var(--ink-100)" />
              <text x={M.left - 8} y={sy(t)} textAnchor="end" dominantBaseline="middle" fontSize={11} fill="var(--ink-400)">{t}</text>
            </g>
          ))}
          {data.map((d, i) => {
            const cx = M.left + step * (i + 0.5);
            const yTop = sy(d.q3);
            const yBot = sy(d.q1);
            const yMed = sy(d.median);
            const delay = 0.1 + i * 0.12;
            return (
              <g key={d.label}>
                {/* whisker */}
                <motion.line
                  x1={cx} x2={cx} y1={sy(d.max)} y2={sy(d.min)}
                  stroke="var(--ink-400)" strokeWidth={1.5}
                  initial={reduce ? false : { pathLength: 0, opacity: 0 }}
                  animate={inView ? { pathLength: 1, opacity: 1 } : { pathLength: 0, opacity: 0 }}
                  transition={{ duration: 0.5, delay, ease: [0.22, 1, 0.36, 1] }}
                />
                <line x1={cx - bw / 4} x2={cx + bw / 4} y1={sy(d.max)} y2={sy(d.max)} stroke="var(--ink-400)" strokeWidth={1.5} />
                <line x1={cx - bw / 4} x2={cx + bw / 4} y1={sy(d.min)} y2={sy(d.min)} stroke="var(--ink-400)" strokeWidth={1.5} />
                {/* box */}
                <motion.rect
                  x={cx - bw / 2} y={yTop} width={bw} height={yBot - yTop}
                  fill="var(--accent-100)" stroke="var(--accent-600)" strokeWidth={1.5}
                  initial={reduce ? false : { scaleY: 0 }}
                  animate={inView ? { scaleY: 1 } : { scaleY: 0 }}
                  transition={{ duration: 0.5, delay: delay + 0.2, ease: [0.22, 1, 0.36, 1] }}
                  style={{ transformOrigin: `${cx}px ${yMed}px` }}
                />
                <motion.line
                  x1={cx - bw / 2} x2={cx + bw / 2} y1={yMed} y2={yMed}
                  stroke="var(--ink-900)" strokeWidth={2}
                  initial={{ opacity: 0 }}
                  animate={inView ? { opacity: 1 } : { opacity: 0 }}
                  transition={{ duration: 0.3, delay: delay + 0.6 }}
                />
                <text x={cx} y={height - M.bottom + 16} textAnchor="middle" fontSize={11} fill="var(--ink-500)">{d.label}</text>
              </g>
            );
          })}
        </>
      )}
    </ChartFrame>
  );
}
