"use client";

import { useMemo } from "react";
import {
  ResponsiveContainer,
  Sankey,
  Tooltip,
  type SankeyNodeProps,
} from "recharts";
import type { SankeyDataset } from "@/lib/types";
import { cn } from "@/lib/utils";

type SankeyChartProps = {
  data: SankeyDataset;
  selectedNode?: string;
  compact?: boolean;
  onNodeSelect?: (nodeName: string) => void;
};

export default function SankeyChart({
  data,
  selectedNode,
  compact,
  onNodeSelect,
}: SankeyChartProps) {
  const chartData = useMemo(
    () => ({
      nodes: data.nodes.map((node) => ({
        ...node,
        isActive: selectedNode ? node.name === selectedNode : false,
      })),
      links: data.links,
    }),
    [data, selectedNode]
  );

  const nodeColorMap = useMemo(
    () =>
      Object.fromEntries(
        data.nodes.map((node) => [node.name, node.color])
      ) as Record<string, string>,
    [data.nodes]
  );

  return (
    <div className="w-full">
      <div
        className={cn(
          "w-full",
          compact ? "h-[280px] sm:h-[320px] lg:h-[360px]" : "h-[320px] sm:h-[420px] lg:h-[540px] xl:h-[620px]"
        )}
      >
        <ResponsiveContainer width="100%" height="100%">
          <Sankey
            data={chartData}
            nodePadding={compact ? 24 : 34}
            nodeWidth={compact ? 18 : 12}
            margin={{ top: compact ? 10 : 12, right: compact ? 25 : 30, bottom: 10, left: compact ? 10 : 20 }}
            iterations={64}
            link={{ stroke: "#E6DCC8" }}
            node={(props: SankeyNodeProps) => {
              const nodeName = props.payload.name;
              const nodeValue = Number(props.payload.value ?? 0);
              const isActive = selectedNode === nodeName;

              const handleSelect = () => {
                onNodeSelect?.(nodeName);
              };

              return (
                <g
                  role="button"
                  tabIndex={0}
                  onClick={handleSelect}
                  onKeyDown={(event) => {
                    if (event.key === "Enter" || event.key === " ") {
                      event.preventDefault();
                      handleSelect();
                    }
                  }}
                  aria-label={`Nodo ${nodeName}, valor ${nodeValue}`}
                  className="cursor-pointer outline-none"
                >
                  <rect
                    x={props.x}
                    y={props.y}
                    width={props.width}
                    height={Math.max(props.height, 12)}
                    fill={nodeColorMap[nodeName] ?? "#D49667"}
                    stroke={isActive ? "#3A2A1E" : "transparent"}
                    strokeWidth={isActive ? 2 : 0}
                    rx={4}
                  />
                </g>
              );
            }}
          >
            <Tooltip
              contentStyle={{
                borderRadius: 12,
                borderColor: "#D9CFBC",
                backgroundColor: "#FFFFFF",
                color: "#111111",
              }}
              formatter={(value, _name, item) => {
                const safeValue = typeof value === "number" ? value : Number(value ?? 0);
                const nodeName = (item?.payload as { name?: string } | undefined)?.name ?? "Nodo";
                return [`${safeValue}K`, nodeName];
              }}
            />
          </Sankey>
        </ResponsiveContainer>
      </div>
      <div className="mt-4 flex flex-wrap gap-3">
        {data.nodes.map((node) => (
          <button
            key={node.name}
            type="button"
            onClick={() => onNodeSelect?.(node.name)}
            className={cn(
              "text-label rounded-xl border border-benell-stroke bg-benell-surface-muted px-3 py-2 font-semibold transition",
              selectedNode === node.name && "bg-benell-brown text-white"
            )}
          >
            {node.name}
          </button>
        ))}
      </div>
    </div>
  );
}
