"use client";

import { motion } from "motion/react";
import { ChartFrame } from "@/components/charts/chart-frame";
import { treeLayout, type TreeNode } from "@/lib/layout";

type DecisionTreeProps = {
  root: TreeNode;
  width?: number;
  height?: number;
  className?: string;
};

const BOX_W = 124;
const BOX_H = 44;

/** DecisionTree — tree where internal nodes are decisions (accent outline) and leaves are outcomes; edges carry yes/no labels and draw in. */
export function DecisionTree({ root, width = 720, height = 400, className }: DecisionTreeProps) {
  const { nodes, edges } = treeLayout(root, width, height);
  const isLeaf = (id: string) => !nodes.some((n) => n.parentId === id);

  return (
    <ChartFrame width={width} height={height} label="Árbol de decisión" className={className}>
      {({ inView, reduce }) => (
        <>
          {edges.map((e, i) => {
            const target = nodes.find((n) => n.x === e.to.x && n.y === e.to.y);
            const midY = (e.from.y + BOX_H / 2 + (e.to.y - BOX_H / 2)) / 2;
            const d = `M${e.from.x},${e.from.y + BOX_H / 2} V${midY} H${e.to.x} V${e.to.y - BOX_H / 2}`;
            return (
              <g key={i}>
                <motion.path
                  d={d}
                  fill="none"
                  stroke="var(--ink-300)"
                  strokeWidth={1.5}
                  initial={reduce ? false : { pathLength: 0 }}
                  animate={inView ? { pathLength: 1 } : { pathLength: 0 }}
                  transition={{ duration: 0.4, delay: 0.1 + (target?.depth ?? 1) * 0.22, ease: [0.22, 1, 0.36, 1] }}
                />
                {e.label && (
                  <motion.text
                    x={e.to.x + 6}
                    y={midY - 3}
                    fontSize={10}
                    fontWeight={800}
                    fill="var(--accent-700)"
                    initial={{ opacity: 0 }}
                    animate={inView ? { opacity: 1 } : { opacity: 0 }}
                    transition={{ duration: 0.3, delay: 0.1 + (target?.depth ?? 1) * 0.22 + 0.3 }}
                  >
                    {e.label}
                  </motion.text>
                )}
              </g>
            );
          })}
          {nodes.map((n) => {
            const leaf = isLeaf(n.id);
            return (
              <motion.g
                key={n.id}
                initial={reduce ? false : { opacity: 0, scale: 0.85 }}
                animate={inView ? { opacity: 1, scale: 1 } : { opacity: 0, scale: 0.85 }}
                transition={{ duration: 0.4, delay: 0.1 + n.depth * 0.25, ease: [0.22, 1, 0.36, 1] }}
                style={{ transformOrigin: `${n.x}px ${n.y}px` }}
              >
                <rect
                  x={n.x - BOX_W / 2}
                  y={n.y - BOX_H / 2}
                  width={BOX_W}
                  height={BOX_H}
                  rx={leaf ? 22 : 6}
                  fill={leaf ? "var(--accent-50)" : "var(--paper)"}
                  stroke={leaf ? "var(--accent-400)" : "var(--accent-500)"}
                  strokeWidth={leaf ? 1.5 : 2}
                />
                <text x={n.x} y={n.y} textAnchor="middle" dominantBaseline="middle" fontSize={11} fontWeight={700} fill="var(--ink-900)">
                  {n.label}
                </text>
              </motion.g>
            );
          })}
        </>
      )}
    </ChartFrame>
  );
}
