import { useCallback } from 'react'
import {
  ReactFlow,
  Background,
  Controls,
  MiniMap,
  BackgroundVariant,
  type OnConnect,
  type OnNodesChange,
  type OnEdgesChange,
  type Node,
  type Edge,
} from '@xyflow/react'
import { nodeTypes } from './nodes/nodeTypes'
import { edgeTypes } from './edges/edgeTypes'

interface NetworkCanvasProps {
  nodes: Node[]
  edges: Edge[]
  onNodesChange: OnNodesChange
  onEdgesChange: OnEdgesChange
  onConnect: OnConnect
  onNodeSelect: (nodeId: string | null) => void
  onEdgeSelect: (edgeId: string | null) => void
  onDrop: (event: React.DragEvent) => void
  onDragOver: (event: React.DragEvent) => void
}

export function NetworkCanvas({
  nodes,
  edges,
  onNodesChange,
  onEdgesChange,
  onConnect,
  onNodeSelect,
  onEdgeSelect,
  onDrop,
  onDragOver,
}: NetworkCanvasProps) {
  const handleSelectionChange = useCallback(({ nodes: selectedNodes, edges: selectedEdges }: { nodes: Node[]; edges: Edge[] }) => {
    if (selectedNodes.length === 1) {
      onNodeSelect(selectedNodes[0].id)
      onEdgeSelect(null)
    } else if (selectedEdges.length === 1) {
      onEdgeSelect(selectedEdges[0].id)
      onNodeSelect(null)
    } else {
      onNodeSelect(null)
      onEdgeSelect(null)
    }
  }, [onNodeSelect, onEdgeSelect])

  const handlePaneClick = useCallback(() => {
    onNodeSelect(null)
    onEdgeSelect(null)
  }, [onNodeSelect, onEdgeSelect])

  return (
    <ReactFlow
      nodes={nodes}
      edges={edges}
      onNodesChange={onNodesChange}
      onEdgesChange={onEdgesChange}
      onConnect={onConnect}
      onSelectionChange={handleSelectionChange}
      onPaneClick={handlePaneClick}
      onDrop={onDrop}
      onDragOver={onDragOver}
      nodeTypes={nodeTypes}
      edgeTypes={edgeTypes}
      defaultEdgeOptions={{ type: 'connection' }}
      deleteKeyCode={['Backspace', 'Delete']}
      multiSelectionKeyCode="Shift"
      fitView
      className="bg-page"
    >
      <Background variant={BackgroundVariant.Dots} color="var(--color-border-default)" gap={20} size={1} />
      <Controls className="!border-default !bg-card [&>button]:!border-default [&>button]:!bg-card [&>button]:!fill-text-primary" />
      <MiniMap
        nodeColor="var(--color-bg-elevated)"
        maskColor="rgba(0,0,0,0.5)"
        className="!border-default !bg-card"
        position="bottom-right"
      />
    </ReactFlow>
  )
}
