import React, { useEffect, useState, useRef } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import { Button, Space, Card, Row, Col, message } from 'antd';
import { ArrowLeftOutlined, SaveOutlined, PlayCircleOutlined } from '@ant-design/icons';
import { Graph, Cell } from '@antv/x6';
import { getDefinitionDetail, saveDefinition } from '../service';
import { getNodeDefinitionList } from './service';
import NodePanel from './components/NodePanel';
import NodeConfigDrawer from './components/NodeConfigModal';
import { NodeDefinition } from './types';
import { validateWorkflow } from './utils/validator';
import { addNodeToGraph } from './utils/nodeUtils';
import { applyAutoLayout } from './utils/layoutUtils';
import {
    GRID_CONFIG,
    CONNECTING_CONFIG,
    HIGHLIGHTING_CONFIG,
    DEFAULT_STYLES,
} from './constants';

const WorkflowDesign: React.FC = () => {
    const { id } = useParams<{ id: string }>();
    const navigate = useNavigate();
    const [title, setTitle] = useState<string>('工作流设计');
    const graphContainerRef = useRef<HTMLDivElement>(null);
    const [graph, setGraph] = useState<Graph | null>(null);
    const [selectedNode, setSelectedNode] = useState<Cell | null>(null);
    const [selectedNodeDefinition, setSelectedNodeDefinition] = useState<NodeDefinition | null>(null);
    const [configModalVisible, setConfigModalVisible] = useState(false);
    const [definitionData, setDefinitionData] = useState<any>(null);
    const [nodeDefinitions, setNodeDefinitions] = useState<NodeDefinition[]>([]);

    // 加载节点定义列表
    useEffect(() => {
        const loadNodeDefinitions = async () => {
            try {
                const data = await getNodeDefinitionList();
                setNodeDefinitions(data);
            } catch (error) {
                console.error('加载节点定义失败:', error);
                message.error('加载节点定义失败');
            }
        };
        loadNodeDefinitions();
    }, []);

    useEffect(() => {
        if (graphContainerRef.current) {
            const graph = new Graph({
                container: graphContainerRef.current,
                grid: GRID_CONFIG,
                connecting: CONNECTING_CONFIG,
                highlighting: HIGHLIGHTING_CONFIG,
                snapline: true,
                history: true,
                clipboard: true,
                selecting: true,
                keyboard: true,
                background: {
                    color: '#f5f5f5',
                },
                mousewheel: {
                    enabled: true,
                    modifiers: ['ctrl', 'meta'],
                    factor: 1.1,
                    maxScale: 1.5,
                    minScale: 0.5,
                },
                panning: {
                    enabled: true,
                    eventTypes: ['rightMouseDown'],
                },
                preventDefaultContextMenu: true,
            });

            // 显示/隐藏连接桩
            graph.on('node:mouseenter', ({ node }) => {
                const ports = document.querySelectorAll(`[data-cell-id="${node.id}"] .x6-port-body`);
                ports.forEach((port) => {
                    port.setAttribute('style', 'visibility: visible');
                });
            });

            graph.on('node:mouseleave', ({ node }) => {
                const ports = document.querySelectorAll(`[data-cell-id="${node.id}"] .x6-port-body`);
                ports.forEach((port) => {
                    port.setAttribute('style', 'visibility: hidden');
                });
            });

            // 节点双击事件
            graph.on('node:dblclick', ({ node }) => {
                const nodeType = node.getProp('type');
                // 从节点定义列表中找到对应的定义
                const definition = nodeDefinitions.find(def => def.type === nodeType);
                if (definition) {
                    setSelectedNode(node);
                    setSelectedNodeDefinition(definition);
                    setConfigModalVisible(true);
                }
            });

            setGraph(graph);

            // 在 graph 初始化完成后加载数据
            if (id) {
                loadDefinitionDetail(graph, id);
            }

            return () => {
                graph.dispose();
            };
        }
    }, [graphContainerRef, id, nodeDefinitions]);

    const loadDefinitionDetail = async (graphInstance: Graph, definitionId: number) => {
        try {
            const response = await getDefinitionDetail(definitionId);
            setTitle(`工作流设计 - ${response.name}`);
            setDefinitionData(response);

            // 清空画布
            graphInstance.clearCells();
            const nodeMap = new Map();

            // 创建节点
            response.graph.nodes.forEach((nodeData: any) => {
                const node = addNodeToGraph(graphInstance, nodeData);
                nodeMap.set(nodeData.id, node);
            });

            // 创建边
            response.graph.edges.forEach((edge: any) => {
                const sourceNode = nodeMap.get(edge.from);
                const targetNode = nodeMap.get(edge.to);
                if (sourceNode && targetNode) {
                    graphInstance.addEdge({
                        source: { cell: sourceNode.id },
                        target: { cell: targetNode.id },
                        attrs: { line: DEFAULT_STYLES.edge },
                        labels: [{
                            attrs: { label: { text: edge.name || '' } }
                        }]
                    });
                }
            });

            // 应用自动布局
            applyAutoLayout(graphInstance);
        } catch (error) {
            console.error('加载工作流定义失败:', error);
            message.error('加载工作流定义失败');
        }
    };

    const handleNodeDragStart = (node: NodeDefinition, e: React.DragEvent) => {
        e.dataTransfer.setData('node', JSON.stringify(node));
    };

    const handleDrop = (e: React.DragEvent) => {
        e.preventDefault();
        if (!graph) return;

        try {
            const nodeData = e.dataTransfer.getData('node');
            if (!nodeData) return;

            const node = JSON.parse(nodeData);
            const { clientX, clientY } = e;
            const point = graph.clientToLocal({ x: clientX, y: clientY });
            
            addNodeToGraph(graph, node, point);
        } catch (error) {
            console.error('创建节点失败:', error);
            message.error('创建节点失败');
        }
    };

    const handleDragOver = (e: React.DragEvent) => {
        e.preventDefault();
    };

    const handleNodeConfigUpdate = (values: any) => {
        if (!selectedNode) return;

        // 更新节点配置
        selectedNode.setProp('config', values);
        // 更新节点显示名称
        if (values.name) {
            selectedNode.attr('label/text', values.name);
        }

        setConfigModalVisible(false);
        message.success('节点配置已更新');
    };

    const handleSaveWorkflow = async () => {
        if (!graph || !definitionData) return;

        try {
            // 校验流程图
            const validationResult = validateWorkflow(graph);
            if (!validationResult.valid) {
                message.error(validationResult.message);
                return;
            }

            // 获取所有节点和边的数据
            const nodes = graph.getNodes().map(node => {
                const nodeDefinition = node.getProp('nodeDefinition');
                const nodeType = node.getProp('type');

                return {
                    id: node.id,
                    code: nodeType,
                    type: nodeType,
                    name: node.attr('label/text'),
                    graph: {
                        shape: nodeDefinition?.graphConfig.uiSchema.shape,
                        size: {
                            width: node.size().width,
                            height: node.size().height
                        },
                        style: nodeDefinition?.graphConfig.uiSchema.style,
                        ports: nodeDefinition?.graphConfig.uiSchema.ports
                    },
                    config: node.getProp('config') || {}
                };
            });

            const edges = graph.getEdges().map(edge => ({
                id: edge.id,
                from: edge.getSourceCellId(),
                to: edge.getTargetCellId(),
                name: edge.getLabels()?.[0]?.attrs?.label?.text || '',
                config: {
                    type: 'sequence'
                }
            }));

            // 构建保存数据
            const saveData = {
                ...definitionData,
                graph: {
                    nodes,
                    edges
                }
            };

            // 调用保存接口
            await saveDefinition(saveData);
            message.success('流程保存成功');
        } catch (error) {
            console.error('保存流程失败:', error);
            message.error('保存流程失败');
        }
    };

    return (
        <div style={{ padding: '24px' }}>
            <Card
                title={title}
                extra={
                    <Space>
                        <Button
                            icon={<SaveOutlined />}
                            type="primary"
                            onClick={handleSaveWorkflow}
                        >
                            保存
                        </Button>
                        <Button
                            icon={<PlayCircleOutlined />}
                            onClick={() => console.log('Deploy workflow')}
                        >
                            发布
                        </Button>
                        <Button
                            icon={<ArrowLeftOutlined />}
                            onClick={() => navigate('/workflow/definition')}
                        >
                            返回
                        </Button>
                    </Space>
                }
            >
                <Row gutter={16}>
                    <Col span={6}>
                        <NodePanel 
                            nodeDefinitions={nodeDefinitions}
                            onNodeDragStart={handleNodeDragStart} 
                        />
                    </Col>
                    <Col span={18}>
                        <Card
                            size="small"
                            styles={{
                                body: {
                                    padding: 0,
                                    height: 'calc(100vh - 250px)',
                                    background: '#f5f5f5',
                                    border: '1px solid #d9d9d9',
                                    borderRadius: '4px',
                                }
                            }}
                        >
                            <div
                                ref={graphContainerRef}
                                style={{
                                    width: '100%',
                                    height: '100%',
                                }}
                                onDrop={handleDrop}
                                onDragOver={handleDragOver}
                            />
                        </Card>
                    </Col>
                </Row>
            </Card>

            <NodeConfigDrawer
                visible={configModalVisible}
                node={selectedNode}
                nodeDefinition={selectedNodeDefinition}
                onOk={handleNodeConfigUpdate}
                onCancel={() => setConfigModalVisible(false)}
            />
        </div>
    );
};

export default WorkflowDesign;
