"use client";

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

export type LineSeries = { label: string; data: Point[] };

type LineChartProps = {
  series: LineSeries[];
  /** Category labels along x (aligned to x = 0..n-1). */
  xLabels?: string[];
  smooth?: boolean;
  yMin?: number;
  yMax?: number;
  width?: number;
  height?: number;
  className?: string;
};

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

/**
 * LineChart — multi-series line. Each line draws via `pathLength` 0→1 (staggered
 * by series), points fade in once the line lands. Colors from `--cat-*`.
 */
export function LineChart({
  series,
  xLabels,
  smooth = false,
  yMin,
  yMax,
  width = 640,
  height = 380,
  className,
}: LineChartProps) {
  const all = series.flatMap((s) => s.data);
  const xs = all.map((p) => p.x);
  const ys = all.map((p) => p.y);
  const xDomain: [number, number] = [Math.min(...xs), Math.max(...xs)];
  const yDomain: [number, number] = [yMin ?? Math.min(0, ...ys), yMax ?? Math.max(...ys)];
  const sx = linearScale(xDomain, [M.left, width - M.right]);
  const sy = linearScale(yDomain, [height - M.bottom, M.top]);
  const ticks = niceTicks(yDomain[0], yDomain[1], 4);

  return (
    <ChartFrame width={width} height={height} label="Gráfica de líneas" className={className}>
      {({ inView }) => (
        <>
          {/* y gridlines + labels */}
          {ticks.map((t) => (
            <g key={t}>
              <line x1={M.left} x2={width - M.right} y1={sy(t)} y2={sy(t)} stroke="var(--ink-100)" strokeWidth={1} />
              <text x={M.left - 8} y={sy(t)} textAnchor="end" dominantBaseline="middle" fontSize={11} fill="var(--ink-400)">
                {t}
              </text>
            </g>
          ))}
          {/* x labels */}
          {xLabels?.map((lab, i) => (
            <text key={i} x={sx(i)} y={height - M.bottom + 18} textAnchor="middle" fontSize={11} fill="var(--ink-500)">
              {lab}
            </text>
          ))}
          {/* lines */}
          {series.map((s, si) => {
            const pts = s.data.map((p) => ({ x: sx(p.x), y: sy(p.y) }));
            const d = smooth ? smoothPath(pts) : linePath(pts);
            const color = catColor(si);
            return (
              <g key={s.label}>
                <motion.path
                  d={d}
                  fill="none"
                  stroke={color}
                  strokeWidth={2.5}
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  initial={{ pathLength: 0, opacity: 0 }}
                  animate={inView ? { pathLength: 1, opacity: 1 } : { pathLength: 0, opacity: 0 }}
                  transition={{ duration: 1.1, delay: 0.1 + si * 0.25, ease: [0.22, 1, 0.36, 1] }}
                />
                {pts.map((p, i) => (
                  <motion.circle
                    key={i}
                    cx={p.x}
                    cy={p.y}
                    r={3.5}
                    fill="var(--paper)"
                    stroke={color}
                    strokeWidth={2}
                    initial={{ opacity: 0, scale: 0 }}
                    animate={inView ? { opacity: 1, scale: 1 } : { opacity: 0, scale: 0 }}
                    transition={{ duration: 0.3, delay: 0.1 + si * 0.25 + 1.1 + i * 0.03, ease: [0.22, 1, 0.36, 1] }}
                    style={{ transformOrigin: `${p.x}px ${p.y}px` }}
                  />
                ))}
              </g>
            );
          })}
        </>
      )}
    </ChartFrame>
  );
}
