import './VisProgUI.css'

import {
    useCallback,
    useRef
} from 'react';
import {
    Background,
    Controls,
    ReactFlow,
    useNodesState,
    useEdgesState,
    reconnectEdge,
    addEdge,
    MarkerType,
    type Edge,
    type Connection,
} from '@xyflow/react';
import '@xyflow/react/dist/style.css';
import {
    StartNode,
    EndNode,
    PhaseNode
} from "./components/NodeDefinitions.tsx";

const nodeTypes = {
    start: StartNode,
    end: EndNode,
    phase: PhaseNode,
};

const initialNodes = [
    {
        id: 'start',
        type: 'start',
        position: {x: 0, y: 0},
        data: {label: 'start'}
    },
    {
        id: 'genericPhase',
        type: 'phase',
        position: {x: 0, y: 150},
        data: {label: 'Generic Phase', number: 1},
    },
    {
        id: 'end',
        type: 'end',
        position: {x: 0, y: 300},
        data: {label: 'End'}
    }
];
const initialEdges = [{id: 'start-end', source: 'start', target: 'end'}];

const defaultEdgeOptions = {
    type: 'floating',
    markerEnd: {
        type: MarkerType.ArrowClosed,
        color: '#505050',
    },
};

const VisualProgrammingUI = ()=>  {
    const edgeReconnectSuccessful = useRef(true);
    const [nodes, , onNodesChange] = useNodesState(initialNodes);
    const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);



    const onConnect = useCallback(
        (params: Edge | Connection) => setEdges((els) => addEdge(params, els)),
        [setEdges],
    );

    const onReconnectStart = useCallback(() => {
        edgeReconnectSuccessful.current = false;
    }, []);

    const onReconnect = useCallback((oldEdge: Edge, newConnection: Connection) => {
        edgeReconnectSuccessful.current = true;
        setEdges((els) => reconnectEdge(oldEdge, newConnection, els));
    }, [setEdges]);

    const onReconnectEnd = useCallback((_: unknown, edge: { id: string; }) => {
        if (!edgeReconnectSuccessful.current) {
            setEdges((eds) => eds.filter((e) => e.id !== edge.id));
        }

        edgeReconnectSuccessful.current = true;
    }, [setEdges]);

    return (
        <div style={{outlineStyle: 'solid', borderRadius: '10pt' ,marginInline: 'auto',width: '60vw', height: '60vh' }}>
            <ReactFlow
                nodes={nodes}
                edges={edges}
                defaultEdgeOptions={defaultEdgeOptions}
                onNodesChange={onNodesChange}
                onEdgesChange={onEdgesChange}
                nodeTypes={nodeTypes}
                snapToGrid
                onReconnect={onReconnect}
                onReconnectStart={onReconnectStart}
                onReconnectEnd={onReconnectEnd}
                onConnect={onConnect}
                fitView
                proOptions={{hideAttribution: true }}
            >
                <Controls />
                <Background />
            </ReactFlow>
        </div>
    );
};

export default VisualProgrammingUI