import React, { useCallback } from 'react';
import {
    ReactFlow,
    Background,
    Controls,
    MiniMap,
    useNodesState,
    useEdgesState,
    addEdge,
    Connection,
    Edge,
    BackgroundVariant,
    Panel
} from '@xyflow/react';
import '@xyflow/react/dist/style.css';

import type { FlowNode, FlowEdge } from '../types';
import { nodeTypes } from '../nodes';
import CustomEdge from './CustomEdge';
import { generateEdgeId } from '../utils/idGenerator';

interface FlowCanvasProps {
    initialNodes?: FlowNode[];
    initialEdges?: FlowEdge[];
    onNodesChange?: (nodes: FlowNode[]) => void;
    onEdgesChange?: (edges: FlowEdge[]) => void;
    onNodeClick?: (event: React.MouseEvent, node: any) => void;
    onEdgeClick?: (event: React.MouseEvent, edge: any) => void;
    onDrop?: (event: React.DragEvent) => void;
    onDragOver?: (event: React.DragEvent) => void;
    onViewportChange?: () => void;
    className?: string;
}

const FlowCanvas: React.FC<FlowCanvasProps> = ({
    initialNodes = [],
    initialEdges = [],
    onNodesChange,
    onEdgesChange,
    onNodeClick,
    onEdgeClick,
    onDrop,
    onDragOver,
    onViewportChange,
    className = ''
}) => {
    const [nodes, , onNodesStateChange] = useNodesState(initialNodes);
    const [edges, setEdges, onEdgesStateChange] = useEdgesState(initialEdges);

    // 处理连接
    const onConnect = useCallback(
        (params: Connection | Edge) => {
            const newEdge: FlowEdge = {
                id: generateEdgeId(), // ✅ 生成格式: eid_xxxxxxxx_xxxx_xxxx_xxxx_xxxxxxxxxxxx
                source: params.source!,
                target: params.target!,
                type: 'smoothstep',
                animated: true,
                style: {
                    stroke: '#94a3b8',
                    strokeWidth: 2,
                },
                markerEnd: {
                    type: 'arrowclosed' as const,
                    color: '#94a3b8',
                },
                data: {
                    label: '',
                    condition: {
                        type: 'DEFAULT' as const,
                        priority: 10
                    }
                }
            };
            setEdges((eds) => addEdge(newEdge, eds));
        },
        [setEdges]
    );

    // 节点变化处理
    const handleNodesChange = useCallback((changes: any) => {
        onNodesStateChange(changes);
        if (onNodesChange) {
            // 延迟获取最新状态 - 在实际项目中可以使用useEffect监听nodes变化
            setTimeout(() => {
                onNodesChange(nodes as FlowNode[]);
            }, 0);
        }
    }, [onNodesStateChange, onNodesChange, nodes]);

    // 边变化处理
    const handleEdgesChange = useCallback((changes: any) => {
        onEdgesStateChange(changes);
        if (onEdgesChange) {
            // 延迟获取最新状态 - 在实际项目中可以使用useEffect监听edges变化
            setTimeout(() => {
                onEdgesChange(edges as FlowEdge[]);
            }, 0);
        }
    }, [onEdgesStateChange, onEdgesChange, edges]);

    // 连接验证 - 利用 React Flow 的实时验证功能
    const isValidConnection = useCallback((connection: Connection | Edge) => {
        // 1. 防止自连接
        if (connection.source === connection.target) {
            return false;
        }

        // 2. 检查是否已存在连接（防止重复）
        const isDuplicate = edges.some(
            (edge) =>
                edge.source === connection.source &&
                edge.target === connection.target
        );
        if (isDuplicate) {
            return false;
        }

        // 3. 获取源节点和目标节点
        const sourceNode = nodes.find(n => n.id === connection.source);
        const targetNode = nodes.find(n => n.id === connection.target);

        if (!sourceNode || !targetNode) {
            return false;
        }

        // 4. 开始节点不能作为连接目标
        if (targetNode.type === 'START_EVENT') {
            return false;
        }

        // 5. 结束节点不能作为连接源
        if (sourceNode.type === 'END_EVENT') {
            return false;
        }

        return true;
    }, [edges, nodes]);

    // 处理拖拽放置
    const handleDrop = useCallback((event: React.DragEvent) => {
        event.preventDefault();
        
        if (onDrop) {
            onDrop(event);
        }
    }, [onDrop]);

    // 处理拖拽悬停
    const handleDragOver = useCallback((event: React.DragEvent) => {
        event.preventDefault();
        event.dataTransfer.dropEffect = 'move';
        
        if (onDragOver) {
            onDragOver(event);
        }
    }, [onDragOver]);

    return (
        <div className={`flow-canvas ${className}`} style={{ width: '100%', height: '100%', position: 'relative', overflow: 'hidden' }}>
            <ReactFlow
                nodes={nodes}
                edges={edges}
                onNodesChange={handleNodesChange}
                onEdgesChange={handleEdgesChange}
                onConnect={onConnect}
                onNodeClick={onNodeClick}
                onEdgeClick={onEdgeClick}
                onDrop={handleDrop}
                onDragOver={handleDragOver}
                onMove={onViewportChange}
                nodeTypes={nodeTypes}
                edgeTypes={{ smoothstep: CustomEdge }}
                isValidConnection={isValidConnection}
                defaultEdgeOptions={{
                    type: 'smoothstep',
                    animated: false,
                    style: { stroke: '#94a3b8', strokeWidth: 2 },
                    markerEnd: { type: 'arrowclosed', color: '#94a3b8' },
                }}
                fitView
                fitViewOptions={{
                    padding: 0.1,
                    includeHiddenNodes: false,
                    minZoom: 1.0,
                    maxZoom: 1.0,
                    duration: 800,
                }}
                minZoom={0.1}
                maxZoom={4}
                deleteKeyCode={['Backspace', 'Delete']}
                multiSelectionKeyCode={['Meta', 'Ctrl']}
                panOnScroll
                selectionOnDrag
                panOnDrag={[1, 2]}
                selectNodesOnDrag={false}
                snapToGrid
                snapGrid={[15, 15]}
                connectionLineStyle={{ stroke: '#3b82f6', strokeWidth: 3, strokeDasharray: '5,5' }}
                connectionLineType={'smoothstep' as any}
                connectOnClick={false}
                elevateEdgesOnSelect
                style={{ width: '100%', height: '100%' }}
            >
                <Background 
                    variant={BackgroundVariant.Dots} 
                    gap={20} 
                    size={1} 
                    color="#e5e7eb"
                />
                <Controls 
                    position="bottom-right"
                    showZoom
                    showFitView
                    showInteractive
                />
                <MiniMap 
                    position="bottom-left"
                    nodeColor="#3b82f6"
                    maskColor="rgba(0, 0, 0, 0.2)"
                    style={{
                        height: 120,
                        width: 200,
                        backgroundColor: '#f9fafb',
                        border: '1px solid #e5e7eb',
                        borderRadius: '8px',
                    }}
                />
                
                {/* 状态面板 */}
                <Panel position="top-left">
                    <div style={{
                        background: 'white',
                        padding: '8px 12px',
                        borderRadius: '6px',
                        boxShadow: '0 2px 4px rgba(0,0,0,0.1)',
                        fontSize: '12px',
                        color: '#6b7280'
                    }}>
                        节点: {nodes.length}, 连接: {edges.length}
                    </div>
                </Panel>
            </ReactFlow>
        </div>
    );
};

export default FlowCanvas;
