import React, { useState, useCallback, useRef, useEffect } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import { message } from 'antd';
import { ReactFlowProvider, useReactFlow } from '@xyflow/react';

import WorkflowToolbar from './components/WorkflowToolbar';
import NodePanel from './components/NodePanel';
import FlowCanvas from './components/FlowCanvas';
import NodeConfigModal from './components/NodeConfigModal';
import EdgeConfigModal, { type EdgeCondition } from './components/EdgeConfigModal';
import type { FlowNode, FlowEdge, FlowNodeData } from './types';
import type { WorkflowNodeDefinition } from './nodes/types';
import { NodeType } from './types';
import { useWorkflowSave } from './hooks/useWorkflowSave';
import { useWorkflowLoad } from './hooks/useWorkflowLoad';
import { useHistory } from './hooks/useHistory';

// 样式
import '@xyflow/react/dist/style.css';
import './index.less';

const WorkflowDesignInner: React.FC = () => {
    const { id } = useParams<{ id: string }>();
    const navigate = useNavigate();
    const { 
        getNodes, 
        setNodes, 
        getEdges, 
        setEdges, 
        screenToFlowPosition,
        fitView,
        zoomIn,
        zoomOut,
        getZoom
    } = useReactFlow();

    const [workflowTitle, setWorkflowTitle] = useState('新建工作流');
    const [currentZoom, setCurrentZoom] = useState(1); // 当前缩放比例
    const reactFlowWrapper = useRef<HTMLDivElement>(null);
    
    // 当前工作流ID
    const currentWorkflowId = id ? parseInt(id) : undefined;
    
    // 节点配置模态框状态
    const [configModalVisible, setConfigModalVisible] = useState(false);
    const [configNode, setConfigNode] = useState<FlowNode | null>(null);
    
    // 边配置模态框状态
    const [edgeConfigModalVisible, setEdgeConfigModalVisible] = useState(false);
    const [configEdge, setConfigEdge] = useState<FlowEdge | null>(null);
    
    // 保存和加载hooks
    const { hasUnsavedChanges, saveWorkflow, markUnsaved } = useWorkflowSave();
    const { workflowDefinition, loadWorkflow } = useWorkflowLoad();
    
    // 历史记录管理
    const history = useHistory();
    
    // 剪贴板（用于复制粘贴）
    const clipboard = useRef<{ nodes: FlowNode[]; edges: FlowEdge[] } | null>(null);

    // 加载工作流数据
    useEffect(() => {
        const loadData = async () => {
            if (currentWorkflowId) {
                const data = await loadWorkflow(currentWorkflowId);
                if (data) {
                    setNodes(data.nodes);
                    setEdges(data.edges);
                    setWorkflowTitle(data.definition.name);
                }
            }
        };
        
        loadData();
    }, [currentWorkflowId, loadWorkflow, setNodes, setEdges]);

    // 初始化缩放比例
    useEffect(() => {
        setCurrentZoom(getZoom());
    }, [getZoom]);

    // 自动适应视图
    useEffect(() => {
        // 延迟执行fitView以确保节点已渲染
        const timer = setTimeout(() => {
            fitView({ 
                padding: 0.1, 
                duration: 800,
                minZoom: 1.0,  // 最小缩放100%
                maxZoom: 1.0   // 最大缩放100%，确保默认100%
            });
            // 更新zoom显示
            setTimeout(() => setCurrentZoom(getZoom()), 850);
        }, 100);
        
        return () => clearTimeout(timer);
    }, [fitView, getZoom]);

    // 初始化示例节点 - 优化位置和布局
    const initialNodes: FlowNode[] = [
        {
            id: '1',
            type: 'START_EVENT',
            position: { x: 250, y: 50 },
            data: {
                label: '开始',
                nodeType: NodeType.START_EVENT,
                category: 'EVENT' as any,
                icon: '▶️',
                color: '#10b981'
            }
        },
        {
            id: '2',
            type: 'USER_TASK', 
            position: { x: 200, y: 150 },
            data: {
                label: '用户审批',
                nodeType: NodeType.USER_TASK,
                category: 'TASK' as any,
                icon: '👤',
                color: '#6366f1'
            }
        },
        {
            id: '3',
            type: 'END_EVENT',
            position: { x: 250, y: 250 },
            data: {
                label: '结束',
                nodeType: NodeType.END_EVENT,
                category: 'EVENT' as any,
                icon: '⏹️',
                color: '#ef4444'
            }
        }
    ];

    const initialEdges: FlowEdge[] = [
        {
            id: 'e1-2',
            source: '1',
            target: '2',
            type: 'default',
            animated: true,
            data: {
                label: '提交',
                condition: {
                    type: 'DEFAULT',
                    priority: 0
                }
            }
        },
        {
            id: 'e2-3',
            source: '2',
            target: '3',
            type: 'default',
            animated: true,
            data: {
                label: '通过',
                condition: {
                    type: 'DEFAULT',
                    priority: 0
                }
            }
        }
    ];

    // 工具栏事件处理
    const handleSave = useCallback(async () => {
        const nodes = getNodes() as FlowNode[];
        const edges = getEdges() as FlowEdge[];
        
        const success = await saveWorkflow({
            nodes,
            edges,
            workflowId: currentWorkflowId,
            name: workflowTitle,
            description: workflowDefinition?.description || '',
            definitionData: workflowDefinition  // 传递原始定义数据
        });
        
        if (success) {
            console.log('保存工作流成功:', { nodes, edges });
        }
    }, [getNodes, getEdges, saveWorkflow, currentWorkflowId, workflowTitle, workflowDefinition]);

    const handleBack = useCallback(() => {
        navigate('/workflow2/definition');
    }, [navigate]);

    // 撤销操作
    const handleUndo = useCallback(() => {
        const state = history.undo();
        if (state) {
            history.pauseRecording();
            setNodes(state.nodes);
            setEdges(state.edges);
            setTimeout(() => history.resumeRecording(), 100);
            message.success('已撤销');
        } else {
            message.info('没有可撤销的操作');
        }
    }, [history, setNodes, setEdges]);

    // 重做操作
    const handleRedo = useCallback(() => {
        const state = history.redo();
        if (state) {
            history.pauseRecording();
            setNodes(state.nodes);
            setEdges(state.edges);
            setTimeout(() => history.resumeRecording(), 100);
            message.success('已重做');
        } else {
            message.info('没有可重做的操作');
        }
    }, [history, setNodes, setEdges]);

    // 复制选中的节点和边
    const handleCopy = useCallback(() => {
        const selectedNodes = getNodes().filter(node => node.selected);
        const selectedEdges = getEdges().filter(edge => {
            // 只复制两端都被选中的边
            return selectedNodes.some(n => n.id === edge.source) &&
                   selectedNodes.some(n => n.id === edge.target);
        });
        
        if (selectedNodes.length > 0) {
            clipboard.current = {
                nodes: JSON.parse(JSON.stringify(selectedNodes)),
                edges: JSON.parse(JSON.stringify(selectedEdges))
            };
            message.success(`已复制 ${selectedNodes.length} 个节点`);
        } else {
            message.warning('请先选择要复制的节点');
        }
    }, [getNodes, getEdges]);

    // 粘贴节点
    const handlePaste = useCallback(() => {
        if (!clipboard.current || clipboard.current.nodes.length === 0) {
            message.info('剪贴板为空');
            return;
        }

        const { nodes: copiedNodes, edges: copiedEdges } = clipboard.current;
        const offset = 50; // 粘贴偏移量
        const idMap = new Map<string, string>();

        // 创建新节点（带偏移）
        const newNodes = copiedNodes.map(node => {
            const newId = `${node.type}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
            idMap.set(node.id, newId);
            
            return {
                ...node,
                id: newId,
                position: {
                    x: node.position.x + offset,
                    y: node.position.y + offset
                },
                selected: true
            };
        });

        // 创建新边（更新source和target为新ID）
        const newEdges = copiedEdges.map(edge => {
            const newSource = idMap.get(edge.source);
            const newTarget = idMap.get(edge.target);
            
            if (!newSource || !newTarget) return null;
            
            return {
                ...edge,
                id: `e${newSource}-${newTarget}`,
                source: newSource,
                target: newTarget,
                selected: true
            };
        }).filter(edge => edge !== null) as FlowEdge[];

        // 取消其他元素的选中状态
        setNodes(nodes => [
            ...nodes.map(n => ({ ...n, selected: false })),
            ...newNodes
        ]);
        setEdges(edges => [
            ...edges.map(e => ({ ...e, selected: false })),
            ...newEdges
        ]);

        message.success(`已粘贴 ${newNodes.length} 个节点`);
    }, [setNodes, setEdges]);

    const handleDelete = useCallback(() => {
        const selectedNodes = getNodes().filter(node => node.selected);
        const selectedEdges = getEdges().filter(edge => edge.selected);
        
        if (selectedNodes.length > 0 || selectedEdges.length > 0) {
            setNodes(nodes => nodes.filter(node => !node.selected));
            setEdges(edges => edges.filter(edge => !edge.selected));
            message.success(`已删除 ${selectedNodes.length} 个节点和 ${selectedEdges.length} 条连接`);
            markUnsaved();
        } else {
            message.warning('请先选择要删除的元素');
        }
    }, [getNodes, getEdges, setNodes, setEdges, markUnsaved]);

    const handleSelectAll = useCallback(() => {
        setNodes(nodes => nodes.map(node => ({ ...node, selected: true })));
        setEdges(edges => edges.map(edge => ({ ...edge, selected: true })));
        message.info('已全选所有元素');
    }, [setNodes, setEdges]);

    const handleFitView = useCallback(() => {
        fitView({ padding: 0.2, duration: 800 });
        // 延迟更新zoom值以获取最新的缩放比例
        setTimeout(() => setCurrentZoom(getZoom()), 850);
    }, [fitView, getZoom]);

    const handleZoomIn = useCallback(() => {
        zoomIn({ duration: 300 });
        // 延迟更新zoom值以获取最新的缩放比例
        setTimeout(() => setCurrentZoom(getZoom()), 350);
    }, [zoomIn, getZoom]);

    const handleZoomOut = useCallback(() => {
        zoomOut({ duration: 300 });
        // 延迟更新zoom值以获取最新的缩放比例
        setTimeout(() => setCurrentZoom(getZoom()), 350);
    }, [zoomOut, getZoom]);

    // 处理节点拖拽放置 - 使用官方推荐的screenToFlowPosition方法
    const handleDrop = useCallback((event: React.DragEvent) => {
        event.preventDefault();

        const dragData = event.dataTransfer.getData('application/reactflow');
        if (!dragData) return;

        try {
            const { nodeType, nodeDefinition }: { nodeType: string; nodeDefinition: WorkflowNodeDefinition } = JSON.parse(dragData);
            
            // 根据React Flow官方文档，screenToFlowPosition会自动处理所有边界计算
            // 不需要手动减去容器边界！
            const position = screenToFlowPosition({
                x: event.clientX,
                y: event.clientY,
            });

            const newNode: FlowNode = {
                id: `${nodeType}-${Date.now()}`,
                type: nodeType,
                position,
                data: {
                    label: nodeDefinition.nodeName,
                    nodeType: nodeDefinition.nodeType,
                    category: nodeDefinition.category,
                    icon: nodeDefinition.uiConfig.style.icon,
                    color: nodeDefinition.uiConfig.style.fill,
                    // 保存原始节点定义引用，用于配置
                    nodeDefinition,
                    // 初始化配置数据
                    configs: {
                        nodeName: nodeDefinition.nodeName,
                        nodeCode: nodeDefinition.nodeCode,
                        description: nodeDefinition.description
                    },
                    inputMapping: {},
                    outputMapping: {}
                }
            };

            setNodes(nodes => [...nodes, newNode]);
            message.success(`已添加 ${nodeDefinition.nodeName} 节点`);
        } catch (error) {
            console.error('解析拖拽数据失败:', error);
            message.error('添加节点失败');
        }
    }, [screenToFlowPosition, setNodes]);

    // 处理节点双击 - 打开配置面板
    const handleNodeClick = useCallback((event: React.MouseEvent, node: FlowNode) => {
        // 只处理双击事件
        if (event.detail === 2) {
            console.log('双击节点，打开配置:', node);
            setConfigNode(node);
            setConfigModalVisible(true);
        }
    }, []);

    // 处理边双击 - 打开条件配置弹窗
    const handleEdgeClick = useCallback((event: React.MouseEvent, edge: FlowEdge) => {
        if (event.detail === 2) {
            console.log('双击边，打开配置:', edge);
            setConfigEdge(edge);
            setEdgeConfigModalVisible(true);
        }
    }, []);

    // 处理节点配置更新
    const handleNodeConfigUpdate = useCallback((nodeId: string, updatedData: Partial<FlowNodeData>) => {
        setNodes((nodes) =>
            nodes.map((node) =>
                node.id === nodeId
                    ? {
                        ...node,
                        data: {
                            ...node.data,
                            ...updatedData,
                        },
                    }
                    : node
            )
        );
        markUnsaved(); // 标记有未保存更改
    }, [setNodes, markUnsaved]);

    // 关闭节点配置模态框
    const handleCloseConfigModal = useCallback(() => {
        setConfigModalVisible(false);
        setConfigNode(null);
    }, []);

    // 处理边条件更新
    const handleEdgeConditionUpdate = useCallback((edgeId: string, condition: EdgeCondition) => {
        setEdges((edges) =>
            edges.map((edge) => {
                if (edge.id === edgeId) {
                    // 根据条件类型生成显示文本
                    const label = condition.type === 'EXPRESSION' 
                        ? condition.expression 
                        : '默认路径';
                    
                    return {
                        ...edge,
                        data: {
                            ...edge.data,
                            condition,
                        },
                        label,
                    };
                }
                return edge;
            })
        );
        markUnsaved(); // 标记有未保存更改
        message.success('边条件配置已更新');
        setEdgeConfigModalVisible(false);
        setConfigEdge(null);
    }, [setEdges, markUnsaved]);

    // 关闭边配置模态框
    const handleCloseEdgeConfigModal = useCallback(() => {
        setEdgeConfigModalVisible(false);
        setConfigEdge(null);
    }, []);

    // 监听视图变化（缩放、平移等）
    const handleViewportChange = useCallback(() => {
        const zoom = getZoom();
        setCurrentZoom(zoom);
    }, [getZoom]);

    // 监听节点和边的变化，记录到历史
    useEffect(() => {
        const nodes = getNodes() as FlowNode[];
        const edges = getEdges() as FlowEdge[];
        
        // 只在有节点或边时记录（避免空状态）
        if (nodes.length > 0 || edges.length > 0) {
            history.record(nodes, edges);
        }
    }, [getNodes, getEdges, history]);

    // 键盘快捷键支持
    useEffect(() => {
        const handleKeyDown = (e: KeyboardEvent) => {
            // 检查焦点是否在输入框、文本域或可编辑元素内
            const target = e.target as HTMLElement;
            const tagName = target.tagName?.toUpperCase();
            const isInputElement = tagName === 'INPUT' || 
                                   tagName === 'TEXTAREA' || 
                                   target.isContentEditable ||
                                   target.getAttribute('contenteditable') === 'true';
            const isInDrawer = target.closest('.ant-drawer-body') !== null;
            const isInModal = target.closest('.ant-modal') !== null;
            
            // 在抽屉或模态框内，且在输入元素中时，允许原生行为
            const shouldSkipShortcut = isInputElement || isInDrawer || isInModal;

            const isMac = navigator.platform.toUpperCase().indexOf('MAC') >= 0;
            const ctrlKey = isMac ? e.metaKey : e.ctrlKey;

            // Ctrl+Z / Cmd+Z - 撤销（仅在画布区域）
            if (ctrlKey && e.key === 'z' && !e.shiftKey) {
                if (!shouldSkipShortcut) {
                    e.preventDefault();
                    handleUndo();
                }
            }
            // Ctrl+Shift+Z / Cmd+Shift+Z - 重做（仅在画布区域）
            else if (ctrlKey && e.key === 'z' && e.shiftKey) {
                if (!shouldSkipShortcut) {
                    e.preventDefault();
                    handleRedo();
                }
            }
            // Ctrl+C / Cmd+C - 复制节点（仅在画布区域）
            else if (ctrlKey && e.key === 'c') {
                if (!shouldSkipShortcut) {
                    e.preventDefault();
                    handleCopy();
                }
            }
            // Ctrl+V / Cmd+V - 粘贴节点（仅在画布区域）
            else if (ctrlKey && e.key === 'v') {
                if (!shouldSkipShortcut) {
                    e.preventDefault();
                    handlePaste();
                }
            }
            // Ctrl+A / Cmd+A - 全选节点（仅在画布区域）
            else if (ctrlKey && e.key === 'a') {
                if (!shouldSkipShortcut) {
                    e.preventDefault();
                    handleSelectAll();
                }
            }
            // Delete / Backspace - 删除节点（仅在画布区域）
            else if (e.key === 'Delete' || e.key === 'Backspace') {
                if (!shouldSkipShortcut) {
                    e.preventDefault();
                    handleDelete();
                }
            }
        };

        window.addEventListener('keydown', handleKeyDown);
        return () => window.removeEventListener('keydown', handleKeyDown);
    }, [handleUndo, handleRedo, handleCopy, handlePaste, handleSelectAll, handleDelete]);

    return (
        <div 
            className="workflow-design-container"
            style={{
                // 确保覆盖父容器的overflow设置
                overflow: 'hidden'
            }}
        >
            {/* 工具栏 */}
            <WorkflowToolbar
                title={`${workflowTitle}${hasUnsavedChanges ? ' *' : ''}`}
                onSave={handleSave}
                onBack={handleBack}
                onUndo={handleUndo}
                onRedo={handleRedo}
                onZoomIn={handleZoomIn}
                onZoomOut={handleZoomOut}
                onFitView={handleFitView}
                canUndo={history.canUndo}
                canRedo={history.canRedo}
                zoom={currentZoom}
            />

            {/* 主要内容区域 */}
            <div className="workflow-content-area">
                {/* 节点面板 */}
                <NodePanel />

                {/* 画布区域 */}
                <div 
                    ref={reactFlowWrapper}
                    className="workflow-canvas-area"
                >
                    <FlowCanvas
                        initialNodes={initialNodes}
                        initialEdges={initialEdges}
                        onNodeClick={handleNodeClick}
                        onEdgeClick={handleEdgeClick}
                        onDrop={handleDrop}
                        onViewportChange={handleViewportChange}
                        className="workflow-canvas"
                    />
                </div>
            </div>
            
            {/* 节点配置弹窗 */}
            <NodeConfigModal
                visible={configModalVisible}
                node={configNode}
                onCancel={handleCloseConfigModal}
                onOk={handleNodeConfigUpdate}
            />
            
            {/* 边条件配置弹窗 */}
            <EdgeConfigModal
                visible={edgeConfigModalVisible}
                edge={configEdge}
                onOk={handleEdgeConditionUpdate}
                onCancel={handleCloseEdgeConfigModal}
            />
        </div>
    );
};

const WorkflowDesign: React.FC = () => {
    return (
        <ReactFlowProvider>
            <WorkflowDesignInner />
        </ReactFlowProvider>
    );
};

export default WorkflowDesign;
