import './VisProgUI.css'


import {
    Background,
    Controls,
    ReactFlow,
    ReactFlowProvider,
    MarkerType,
    Panel,
} from '@xyflow/react';
import '@xyflow/react/dist/style.css';
import {
    StartNode,
    EndNode,
    PhaseNode,
    NormNode
} from "./components/NodeDefinitions.tsx";

import { Sidebar } from './components/DragDropSidebar.tsx';

import useStore from "./VisProgStores.tsx";
import {useShallow} from "zustand/react/shallow";
import type {FlowState} from "./VisProgTypes.tsx";

// --| config starting params for flow |--


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





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

const selector = (state: FlowState) => ({
    nodes: state.nodes,
    edges: state.edges,
    onNodesChange: state.onNodesChange,
    onEdgesChange: state.onEdgesChange,
    onConnect: state.onConnect,
    onReconnectStart: state.onReconnectStart,
    onReconnectEnd: state.onReconnectEnd,
    onReconnect: state.onReconnect
});

// --| define ReactFlow editor |--

const VisProgUI = ()=>  {

    const { nodes, edges, onNodesChange, onEdgesChange, onConnect, onReconnect, onReconnectStart, onReconnectEnd } = useStore(
        useShallow(selector),
    );

    // handles connection of newly created edges


    return (
        <div style={{marginInline: 'auto',display: 'flex',justifySelf: 'center', padding:'10px', alignItems: 'center', width: '80vw', height: '80vh'}}>
            <div style={{outlineStyle: 'solid', borderRadius: '10pt',width: '90%', height:'100%' }}>
                <ReactFlow
                    nodes={nodes}
                    edges={edges}
                    defaultEdgeOptions={defaultEdgeOptions}
                    onNodesChange={onNodesChange}
                    onEdgesChange={onEdgesChange}
                    nodeTypes={nodeTypes}
                    onReconnect={onReconnect}
                    onReconnectStart={onReconnectStart}
                    onReconnectEnd={onReconnectEnd}
                    onConnect={onConnect}
                    snapToGrid
                    fitView
                    proOptions={{hideAttribution: true }}
                >
                    <Panel position="top-center" style={{marginInlineStart: 'auto', marginInlineEnd:'auto',backgroundColor: 'canvas' ,marginBottom: '0.5rem', marginTop:'auto', width: '50%', height:'7%'}}>
                        <Sidebar />
                    </Panel>
                    <Controls />
                    <Background />
                </ReactFlow>
            </div>

        </div>

    );
};

/* --| Places the VisProgUI component inside a ReactFlowProvider
 *
 * Wrapping the editor component inside a ReactFlowProvider
 * allows us to access and interact with the components inside the editor,
 * thus facilitating the addition of node specific functions inside their node definitions
 */
function VisualProgrammingUI(){
    return (
        <ReactFlowProvider>
            <VisProgUI />
        </ReactFlowProvider>
    );
}

export default VisualProgrammingUI;