"use client";

import React, { useMemo, useCallback } from "react";
import {
  ReactFlow,
  Panel,
  useNodesState,
  useEdgesState,
  Edge,
  Node,
  Position,
  Background,
  Controls,
  ConnectionLineType,
  Handle,
  useReactFlow,
  ReactFlowProvider,
} from "@xyflow/react";
import "@xyflow/react/dist/style.css";
import dagre from "dagre";
import { Folder, Edit } from "lucide-react";
import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";
import { CategoryActionMenu } from "@/components/dashboard/categorypage/CategoryActionMenu";

interface Category {
  id: string;
  name: string;
  parent_id: string | null;
}

interface CategoryDiagramProps {
  categories: Category[];
  onAddChild: (id: string, name: string) => void;
  onEdit: (id: string, name: string) => void;
  onDelete: (id: string, name: string) => void;
}

// Custom Node for Categories
const CategoryNode = ({ data }: any) => {
  const isHorizontal = data.direction === "LR";
  
  return (
    <div className="relative group ring-1 ring-border-light dark:ring-border-dark bg-card hover:ring-primary/50 transition-all rounded-lg p-4 shadow-sm min-w-[200px]">
      <Handle 
        type="target" 
        position={isHorizontal ? Position.Left : Position.Top} 
        className="!bg-primary/50" 
      />
      <div className="flex items-center gap-3">
        <div className="p-2 rounded-md bg-primary/10 text-primary">
          <Folder className="h-4 w-4" />
        </div>
        <div className="flex-1 overflow-hidden">
          <p className="text-sm font-semibold truncate leading-tight">{data.name}</p>
          <p className="text-[10px] text-muted-foreground font-mono">ID: {data.id.substring(0, 8)}...</p>
        </div>
        <div className="opacity-0 group-hover:opacity-100 transition-opacity">
            <CategoryActionMenu 
                categoryId={data.id} 
                categoryName={data.name}
                onAddChild={data.onAddChild}
                onEdit={data.onEdit}
                onDelete={data.onDelete}
            />
        </div>
      </div>
      <Handle 
        type="source" 
        position={isHorizontal ? Position.Right : Position.Bottom} 
        className="!bg-primary/50" 
      />
    </div>
  );
};

const nodeTypes = {
  category: CategoryNode,
};

const nodeWidth = 200;
const nodeHeight = 80;

const getLayoutedElements = (nodes: Node[], edges: Edge[], direction: "TB" | "LR" = "TB") => {
  const isHorizontal = direction === "LR";

  const g = new dagre.graphlib.Graph();
  g.setGraph({
    rankdir: direction, 
    nodesep: isHorizontal ? 40 : 80, 
    ranksep: isHorizontal ? 120 : 100 
  });
  g.setDefaultEdgeLabel(() => ({}));

  nodes.forEach((node) => {
    g.setNode(node.id, { width: nodeWidth, height: nodeHeight });
  });

  edges.forEach((edge) => {
    g.setEdge(edge.source, edge.target);
  });

  dagre.layout(g);

  const newNodes = nodes.map((node) => {
    const nodeWithPosition = g.node(node.id);
    return {
      ...node,
      position: {
        x: nodeWithPosition.x - nodeWidth / 2,
        y: nodeWithPosition.y - nodeHeight / 2,
      },
    };
  });

  return { nodes: newNodes, edges };
};

/**
 * ⚡ Optimization: Memoized CategoryDiagram
 * Prevents redundant re-calculations of the dagre layout when categories are stable.
 */
export const CategoryDiagram = React.memo(function CategoryDiagram(props: CategoryDiagramProps) {
  return (
    <ReactFlowProvider>
      <CategoryDiagramContent {...props} />
    </ReactFlowProvider>
  );
});

function CategoryDiagramContent({ categories, onAddChild, onEdit, onDelete }: CategoryDiagramProps) {
  const [direction, setDirection] = React.useState<"TB" | "LR">("TB");
  const { fitView } = useReactFlow();

  const initialElements = useMemo(() => {
    const nodes: Node[] = categories.map((cat) => ({
      id: cat.id,
      type: "category",
      data: { 
        name: cat.name, 
        id: cat.id, 
        direction,
        onAddChild,
        onEdit,
        onDelete
      },
      position: { x: 0, y: 0 },
    }));

    const edges: Edge[] = categories
      .filter((cat) => cat.parent_id !== null)
      .map((cat) => ({
        id: `e${cat.parent_id}-${cat.id}`,
        source: cat.parent_id!,
        target: cat.id,
        type: "smoothstep",
        animated: true,
        style: { stroke: "hsl(var(--primary) / 0.5)", strokeWidth: 2 },
      }));

    return getLayoutedElements(nodes, edges, direction);
  }, [categories, direction, onAddChild, onEdit, onDelete]);

  const [nodes, setNodes, onNodesChange] = useNodesState(initialElements.nodes);
  const [edges, setEdges, onEdgesChange] = useEdgesState(initialElements.edges);

  React.useEffect(() => {
    setNodes(initialElements.nodes);
    setEdges(initialElements.edges);
    // Use a small timeout to ensure layout is applied before fitting
    setTimeout(() => fitView({ duration: 400 }), 50);
  }, [initialElements, setNodes, setEdges, fitView]);

  return (
    <div className="h-[700px] w-full bg-muted/10 rounded-xl border border-border-light dark:border-border-dark overflow-hidden relative">
      <ReactFlow
        nodes={nodes}
        edges={edges}
        onNodesChange={onNodesChange}
        onEdgesChange={onEdgesChange}
        nodeTypes={nodeTypes}
        connectionLineType={ConnectionLineType.SmoothStep}
        fitView
        minZoom={0.2}
      >
        <Background gap={20} color="hsl(var(--muted-foreground) / 0.1)" />
        <Controls />
        <Panel position="top-right" className="bg-card/80 backdrop-blur border border-border p-2 rounded-lg shadow-xl m-4 flex flex-col gap-2">
            <div className="flex bg-muted p-1 rounded-md">
                <Button 
                    variant={direction === "TB" ? "default" : "ghost"} 
                    size="sm" 
                    className="h-7 text-[10px]"
                    onClick={() => setDirection("TB")}
                >
                    Vertikal
                </Button>
                <Button 
                    variant={direction === "LR" ? "default" : "ghost"} 
                    size="sm" 
                    className="h-7 text-[10px]"
                    onClick={() => setDirection("LR")}
                >
                    Horizontal
                </Button>
            </div>
            <div className="text-[10px] uppercase font-bold text-muted-foreground tracking-widest pl-1">Steuerung</div>
            <p className="text-[11px] text-foreground leading-relaxed px-1">Scroll zum Zoomen<br/>Ziehen zum Bewegen</p>
        </Panel>
      </ReactFlow>
    </div>
  );
}
