import NodeKinerja from '@/components/sakip-punya/nodekinerja';
import { useAuthBreadcrumbOperator } from '@/hooks/use-auth-breadcrumb-operator';
import AppLayout from '@/layouts/app-layout';
import { Head } from '@inertiajs/react';
import * as dagre from 'dagre';
import { useEffect, useState } from 'react';
import ReactFlow, {
    addEdge,
    applyEdgeChanges,
    applyNodeChanges,
    Background,
    Connection,
    Controls,
    Edge,
    MiniMap,
    Node,
    OnEdgesChange,
    OnNodesChange,
    Position,
    ReactFlowInstance,
} from 'reactflow';
import 'reactflow/dist/style.css';

// ukuran tetap
const defaultWidth = 220;
const defaultHeight = 80;

// Graph dagre
const dagreGraph = new dagre.graphlib.Graph();
dagreGraph.setDefaultEdgeLabel(() => ({}));

/**
 * Fungsi layout otomatis dengan tinggi node fix
 */
const getLayoutedElements = (
    nodes: Node[],
    edges: Edge[],
    direction: 'TB' | 'LR' = 'TB',
): Node[] => {
    dagreGraph.setGraph({
        rankdir: direction,
        nodesep: defaultWidth + 40,
        ranksep: defaultHeight + 40, // tinggi node + jarak antar level
        marginx: 20,
        marginy: 20,
    });

    nodes.forEach((node) => {
        dagreGraph.setNode(node.id, {
            width: defaultWidth,
            height: defaultHeight, // fix tinggi
        });
    });

    edges.forEach((edge) => {
        dagreGraph.setEdge(edge.source, edge.target);
    });

    dagre.layout(dagreGraph);

    return nodes.map((node) => {
        const nodeWithPos = dagreGraph.node(node.id);

        return {
            ...node,
            position: {
                x: nodeWithPos.x - defaultWidth / 2,
                y: nodeWithPos.y - defaultHeight / 2,
            },
            sourcePosition: Position.Bottom,
            targetPosition: Position.Top,
        } as Node;
    });
};

type BackendNode = {
    id: number;
    uraian: string;
    kategori: string;
    parent_id?: number | null;
};

interface SakipDiagramProps {
    nodes: BackendNode[];
}

export default function PohonKinerjaIndex({
    nodes: backendNodes,
}: SakipDiagramProps) {
    const breadcrumbs = useAuthBreadcrumbOperator();

    const [nodes, setNodes] = useState<Node[]>([]);
    const [edges, setEdges] = useState<Edge[]>([]);
    const [rfInstance, setRfInstance] = useState<ReactFlowInstance | null>(
        null,
    );

    const nodeTypes = {
        custom: NodeKinerja,
    };

    useEffect(() => {
        if (backendNodes && backendNodes.length > 0) {
            const initialNodes: Node[] = backendNodes.map((item) => ({
                id: item.id.toString(),
                type: 'custom',
                data: {
                    kategori: item.kategori,
                    uraian: item.uraian,
                },
                position: { x: 0, y: 0 },
            }));

            const initialEdges: Edge[] = backendNodes
                .filter((item) => item.parent_id)
                .map((item) => ({
                    id: `e${item.parent_id}-${item.id}`,
                    source: item.parent_id!.toString(),
                    target: item.id.toString(),
                }));

            // apply layout
            const layouted = getLayoutedElements(
                initialNodes,
                initialEdges,
                'TB',
            );
            setNodes(layouted);
            setEdges(initialEdges);
        }
    }, [backendNodes]);

    const onNodesChange: OnNodesChange = (changes) =>
        setNodes((nds) => applyNodeChanges(changes, nds));

    const onEdgesChange: OnEdgesChange = (changes) =>
        setEdges((eds) => applyEdgeChanges(changes, eds));

    const onConnect = (connection: Connection) =>
        setEdges((eds) => addEdge(connection, eds));

    return (
        <AppLayout breadcrumbs={breadcrumbs}>
            <Head title="Pohon Kinerja Teknis" />
            <div className="flex h-full flex-1 flex-col gap-4 rounded-xl px-6 py-4">
                <div style={{ width: '100%', height: '800px' }}>
                    <ReactFlow
                        nodes={nodes}
                        edges={edges}
                        nodeTypes={nodeTypes}
                        onNodesChange={onNodesChange}
                        onEdgesChange={onEdgesChange}
                        onConnect={onConnect}
                        onInit={setRfInstance}
                        fitView
                    >
                        <MiniMap />
                        <Controls />
                        <Background />
                    </ReactFlow>
                </div>
            </div>
        </AppLayout>
    );
}
