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' import { getDeviceRenderConfig } from './nodes/deviceRegistry' import type { DeviceNodeData } from './nodes/DeviceNode' 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 onDragLeave?: (event: React.DragEvent) => void isDragOver?: boolean onNodeContextMenu?: (event: React.MouseEvent, node: Node) => void onPaneContextMenu?: (event: MouseEvent | React.MouseEvent) => void onPaneClick?: () => void } export function NetworkCanvas({ nodes, edges, onNodesChange, onEdgesChange, onConnect, onNodeSelect, onEdgeSelect, onDrop, onDragOver, onDragLeave, isDragOver, onNodeContextMenu, onPaneContextMenu, onPaneClick: onPaneClickProp, }: 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) onPaneClickProp?.() }, [onNodeSelect, onEdgeSelect, onPaneClickProp]) const getNodeColor = useCallback((node: Node) => { if (node.type === 'group') return 'var(--color-bg-elevated)' const data = node.data as unknown as DeviceNodeData return getDeviceRenderConfig(data?.deviceType || '', data?.category).color }, []) return (