"use client";

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

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

/** MindMap — central node with radial branches (curved edges); reveals outward by depth. */
export function MindMap({ root, width = 640, height = 460, className }: MindMapProps) {
  const cx = width / 2;
  const cy = height / 2;
  const { nodes, edges } = radialLayout(root, cx, cy, Math.min(width, height) / 2 - 70);
  const branchColor = new Map<string, string>();
  (root.children ?? []).forEach((b, i) => branchColor.set(b.id, catColor(i)));
  const colorFor = (n: { id: string; parentId?: string }): string =>
    branchColor.get(n.id) ?? (n.parentId ? branchColor.get(n.parentId) ?? "var(--accent-500)" : "var(--accent-500)");

  return (
    <ChartFrame width={width} height={height} label="Mapa mental" className={className}>
      {({ inView, reduce }) => (
        <>
          {edges.map((e, i) => {
            const mx = (e.from.x + e.to.x) / 2;
            const d = `M${e.from.x},${e.from.y} Q${mx},${e.from.y} ${e.to.x},${e.to.y}`;
            return (
              <motion.path
                key={i}
                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.5, delay: 0.15, ease: [0.22, 1, 0.36, 1] }}
              />
            );
          })}
          {nodes.map((n) => {
            const w = n.depth === 0 ? 120 : Math.max(56, (n.label?.length ?? 4) * 8 + 24);
            const h = n.depth === 0 ? 48 : 32;
            const color = colorFor(n);
            return (
              <motion.g
                key={n.id}
                initial={reduce ? false : { opacity: 0, scale: 0.7 }}
                animate={inView ? { opacity: 1, scale: 1 } : { opacity: 0, scale: 0.7 }}
                transition={{ duration: 0.4, delay: 0.15 + n.depth * 0.2, ease: [0.22, 1, 0.36, 1] }}
                style={{ transformOrigin: `${n.x}px ${n.y}px` }}
              >
                <rect
                  x={n.x - w / 2}
                  y={n.y - h / 2}
                  width={w}
                  height={h}
                  rx={h / 2}
                  fill={n.depth === 0 ? "var(--ink-900)" : "var(--paper)"}
                  stroke={n.depth === 0 ? "var(--ink-900)" : color}
                  strokeWidth={n.depth === 0 ? 0 : 2}
                />
                <text
                  x={n.x}
                  y={n.y}
                  textAnchor="middle"
                  dominantBaseline="middle"
                  fontSize={n.depth === 0 ? 14 : 11}
                  fontWeight={n.depth === 0 ? 800 : 700}
                  fill={n.depth === 0 ? "var(--accent-500)" : "var(--ink-900)"}
                >
                  {n.label}
                </text>
              </motion.g>
            );
          })}
        </>
      )}
    </ChartFrame>
  );
}
