<template>
  <Wrapper>
    <a-layout class="bg-transparent" style="background: transparent">
      <Header />
      <a-layout class="ks-layout-body">
        <div class="ks-model-builder-body">
          <div class="ks-model-builder-left">
            <TressCard
              ref="treesCardRef"
              @create-tree="handleCreateTree"
              @select-tree="handleSelectTree"
            />
            <NodesCard
              @drag-item-start="handleDragStart"
              @drag-item-end="handleDragEnd"
            />
          </div>

          <div class="ks-model-builder-content">
            <div class="ks-model-builder-actions">
              <a-space>
                <a-button v-if="graph && currentBehaviorTree" class="ks-model-builder-save" size="small" @click="handleSave">
                  <CheckOutlined />
                  <span>保存</span>
                </a-button>

                <a-button v-if="currentScenarioId" class="ks-model-builder-save" size="small" @click="handleGoback">
                  <BackwardFilled />
                  <span>返回</span>
                </a-button>
              </a-space>
            </div>
            <div
              ref="canvas"
              class="ks-model-builder-canvas"
              @dragenter="handleDragEnter"
              @dragleave="handleDragLeave"
              @drop="handleDrop"
              @dragover.prevent
            ></div>
            <TeleportContainer />
          </div>
          <Properties
            v-if="graph"
            :platforms="platforms"
            :sub-platforms="subPlatforms"
            :nodeCommands="nodeCommands"
            :element="selectedNodeTaskElement"
            :graph="(graph as any)"
            :node="(selectedModelNode as any)"
            :tree="currentBehaviorTree"
            :tree-editing="currentTreeEditing"
            @update-element="handleUpdateElement" />
        </div>
      </a-layout>
    </a-layout>
  </Wrapper>
</template>

<script lang="ts">
import { defineComponent, nextTick, onBeforeUnmount, onMounted, ref } from 'vue';
import { useRoute } from 'vue-router';
import { message } from 'ant-design-vue';
import { getTeleport } from '@antv/x6-vue-shape';
import { Graph, Node, type NodeProperties } from '@antv/x6';
import { CheckCircleOutlined, CheckOutlined, RollbackOutlined, SaveOutlined, BackwardFilled } from '@ant-design/icons-vue';
import { Wrapper } from '@/components/wrapper';
import { safePreventDefault, safeStopPropagation } from '@/utils/event';
import Header from '../header.vue';
import Properties from './properties.vue';
import type { NodeDragTemplate } from './template';
import type { BehaviorTree } from './tree';
import { createGraphTaskElementFromTemplate } from './utils';

import { createGraphTaskElement, createLineOptions, type GraphContainer, type GraphTaskElement, hasElements, hasRootElementNode, resolveGraph, useGraphCanvas } from '../graph';
import { registerNodeElement } from './register';
import { findAllBasicPlatforms, findAllNodeCommands } from '../api';
import type { NodeCommand, Platform } from '../types';
import { createTree, findOneTreeById, findOneTreeByPlatformId, updateTree, findSubPlatforms } from './api';
import TressCard from './trees-card.vue';
import NodesCard from './nodes-card.vue';

const TeleportContainer = defineComponent(getTeleport());

registerNodeElement();

export default defineComponent({
  components: {
    TressCard,
    NodesCard,
    Wrapper,
    Header,
    Properties,
    SaveOutlined,
    CheckCircleOutlined,
    CheckOutlined,
    RollbackOutlined,
    BackwardFilled,
    TeleportContainer,
  },
  setup() {
    const currentRoute = useRoute();
    const canvas = ref<HTMLDivElement | null>(null);
    const graph = ref<Graph | null>(null);
    const currentZoom = ref<number>(1);
    const draggedNodeData = ref<NodeDragTemplate | null>(null);
    const isDraggingOver = ref(false);
    const currentTreeEditing = ref<boolean>(false);
    const currentBehaviorTree = ref<BehaviorTree | null>(null);
    const currentGraph = ref<GraphContainer | null>(null);
    const selectedModelNode = ref<Node<NodeProperties> | null>(null);
    const selectedNodeTaskElement = ref<GraphTaskElement | null>(null);
    const changed = ref<boolean>(false);
    const treesCardRef = ref<InstanceType<typeof TressCard> | null>(null);
    const platforms = ref<Platform[]>([]);
    const subPlatforms = ref<Platform[]>([]);
    const nodeCommands = ref<NodeCommand[]>([])
    const currentScenarioId = ref<number | null>(null);
    const currentPlatformId = ref<number | null>(null);

    const {
      handleGraphEvent,
      createCanvas,
      zoomIn,
      zoomOut,
      fitToScreen,
      centerContent,
      resizeCanvas,
      destroyGraph,
      clearGraph,
    } = useGraphCanvas();

    const destroy = ()=> {
      window.removeEventListener('resize', handleResize);
      destroyGraph();
      graph.value = null;
    }

    const loadPlatforms = () => {
      platforms.value = [];
      findAllBasicPlatforms().then(r => {
        platforms.value = r.data ?? [];
      });
    };

    const loadNodeCommands = ()=> {
      nodeCommands.value = []
      findAllNodeCommands().then(r=> {
        nodeCommands.value = r.data ?? []
      })
    }

    const loadDatasource = ()=> {
      loadPlatforms();
      loadNodeCommands();
    }

    // 加载下属平台
    const loadSubPlatforms = (platformId: number | null) => {
      if (!platformId || platformId <= 0) {
        subPlatforms.value = [];
        return;
      }
      
      findSubPlatforms(platformId).then(r => {
        subPlatforms.value = r.data ?? [];
      }).catch(err => {
        console.error('加载下属平台失败:', err);
        subPlatforms.value = [];
      });
    };

    // 处理拖动开始
    const handleDragStart = (nm: NodeDragTemplate) => {
      draggedNodeData.value = nm;
    };

    // 处理拖动结束
    const handleDragEnd = () => {
      isDraggingOver.value = false;
    };

    // 处理拖动进入
    const handleDragEnter = (e: DragEvent) => {
      safePreventDefault(e);
      safeStopPropagation(e);
      isDraggingOver.value = true;
    };

    // 处理拖动离开
    const handleDragLeave = (e: DragEvent) => {
      safePreventDefault(e);
      safeStopPropagation(e);

      if (canvas.value && e.relatedTarget &&
        typeof e.relatedTarget === 'object' &&
        'nodeType' in e.relatedTarget) {
        // 使用 Element 类型而不是 x6 的 Node 类型
        if (!canvas.value.contains(e.relatedTarget as Element)) {
          isDraggingOver.value = false;
        }
      }
    };

    // 处理放置
    const handleDrop = (e: DragEvent) => {
      console.info('handleDrop', e);
      safePreventDefault(e);
      safeStopPropagation(e);
      isDraggingOver.value = false;
      currentTreeEditing.value = false;

      if (!currentBehaviorTree.value) {
        message.error('请先选择或者创建行为树.');
        return;
      }

      if (!graph.value || !canvas.value || !draggedNodeData.value) {
        message.error('无法放置节点,缺少必要数据');
        return;
      }

      try {
        // 获取拖动的数据
        const template = draggedNodeData.value as NodeDragTemplate;

        if (!hasElements(graph.value as Graph) && template.type !== 'root') {
          message.error('请先添加根节点.');
          return;
        }

        if (hasRootElementNode(graph.value as Graph) && template.type === 'root') {
          message.error('根节点已经存在.');
          return;
        }

        // 计算相对于画布的位置（考虑缩放）
        const rect = canvas.value.getBoundingClientRect();
        const scale = currentZoom.value || 1;
        const x = (e.clientX - rect.left) / scale;
        const y = (e.clientY - rect.top) / scale;

        console.log('放置节点:', { ...template, x, y });

        // 创建节点数据
        const settingTaskElement: GraphTaskElement = createGraphTaskElementFromTemplate(template, { x, y });
        // 创建节点
        const settingTaskNode = createGraphTaskElement(settingTaskElement);
        console.info('create settingTaskNode: ', settingTaskElement, settingTaskNode);

        // 将节点添加到画布
        graph.value?.addNode(settingTaskNode as any);
        console.log('节点已添加到画布:', settingTaskNode.id);

        // 重置拖动数据
        draggedNodeData.value = null;
      } catch (error) {
        console.error('放置节点时出错:', error);
      }
    };

    const handleSelectTree = (tree: BehaviorTree) => {
      destroyGraph();
      currentPlatformId.value = null;
      currentScenarioId.value = null;

      console.info('handleSelectTree', tree);
      findOneTreeById(tree.id).then(r => {
        if (r.data) {
          let nodeGraph: GraphContainer | null = null;
          try {
            nodeGraph = JSON.parse(r.data?.xmlContent as unknown as string) as unknown as GraphContainer;
          } catch (e: any) {
            console.error('parse error,cause:', e);
          }
          if (!nodeGraph) {
            nodeGraph = {
              nodes: [],
              edges: [],
            };
          }
          currentBehaviorTree.value = {
            ...r.data,
            graph: nodeGraph,
          };
          currentTreeEditing.value = true;
          
          // 加载下属平台
          loadSubPlatforms(r.data.platformId);
          
          nextTick(() => {
            initGraph();
          });
        } else {
          message.error(r.msg ?? '行为树不存在.');
        }
      });
    };

    const createElements = () => {
      clearGraph();
      nextTick(() => {
        setTimeout(() => {
          if (currentBehaviorTree.value?.graph && graph.value) {
            if (currentBehaviorTree.value?.graph.nodes) {
              currentBehaviorTree.value?.graph.nodes.forEach(ele => {
                const node = createGraphTaskElement(ele as GraphTaskElement);
                console.info('create node: ', ele);
                // 将节点添加到画布
                graph.value?.addNode(node as Node);
              });
            }
            if (currentBehaviorTree.value?.graph.edges) {
              // 然后添加所有边，确保包含桩点信息
              setTimeout(() => {
                currentBehaviorTree.value?.graph.edges.forEach(edgeData => {
                  graph.value?.addEdge({
                    ...edgeData,
                    ...createLineOptions(),
                  });
                });
              }, 100);  // 延迟一会儿,免得连线错位
            }
          }
        }, 100);
      });
    };

    const resolveQuery = ()=> {
      let scenarioId = Number(currentRoute.query.scenario);
      if (!isNaN(scenarioId)) {
        currentScenarioId.value = scenarioId;
      } else {
        currentScenarioId.value = null;
      }
      let platformId = Number(currentRoute.query.platform);
      if (!isNaN(platformId)) {
        currentPlatformId.value = platformId;
      } else {
        currentPlatformId.value = null;
      }
    }

    const handleCreateTree = () => {
      destroyGraph();

      currentBehaviorTree.value = {
        id: 0,
        name: '行为树',
        description: null,
        englishName: null,
        xmlContent: null,
        createdAt: null,
        platformId: currentPlatformId.value,
        graph: {
          edges: [],
          nodes: [],
        },
        updatedAt: null,
      };
      currentGraph.value = {
        edges: [],
        nodes: [],
      };
      selectedModelNode.value = null;
      selectedNodeTaskElement.value = null;
      subPlatforms.value = []; // 重置下属平台

      nextTick(() => {
        initGraph();
      });
    };

    // 初始化X6画布
    const initGraph = () => {
      if (!canvas.value) {
        console.error('画布容器不存在');
        return;
      }

      try {
        graph.value = createCanvas(canvas.value);
        console.log('画布初始化成功');
        createElements();

        // 监听缩放变化
        handleGraphEvent('scale', ({ sx }: { sx: number }) => {
          currentZoom.value = sx;
        });

        handleGraphEvent('blank:click', () => {
          selectedModelNode.value = null;
          selectedNodeTaskElement.value = null;
          currentTreeEditing.value = null !== currentBehaviorTree.value;
        });

        handleGraphEvent('node:click', (args: any) => {
          const node = args.node as Node<NodeProperties>;
          const newElement = node.getData() as GraphTaskElement;
          console.error('ddd', args);

          selectedModelNode.value = node;
          selectedNodeTaskElement.value = JSON.parse(JSON.stringify(newElement || {})) as GraphTaskElement;
        });

        // 监听节点鼠标事件，显示/隐藏连接点
        handleGraphEvent('node:mouseenter', (_ctx: any) => {
        });

        handleGraphEvent('node:mouseleave', (_ctx: any) => {
        });
      } catch (error) {
        console.error('初始化画布失败:', error);
      }
    };

    // 监听窗口大小变化
    const handleResize = () => {
      nextTick(() => {
        resizeCanvas();
      });
    };

    const init = () => {
      console.info('init');
      nextTick(() => {
        initGraph();
        window.addEventListener('resize', handleResize);
        console.log('节点挂载完成');

        resolveQuery();

        if (currentPlatformId.value) {
          findOneTreeByPlatformId(currentPlatformId.value).then(r => {
            if (r.data) {
              handleSelectTree(r.data);
            } else {
              handleCreateTree();
            }
          });
        } else {
          currentPlatformId.value = null;
          handleCreateTree();
        }
      });
    };

    const handleUpdateElement = (element: GraphTaskElement) => {
      // 更新选中的节点数据
      if (selectedModelNode.value) {
        selectedModelNode.value.replaceData(element);
      }
      console.info('handleUpdateElement', element);
      // 更新本地引用
      selectedNodeTaskElement.value = element;
      changed.value = true;
    };

    const handleGoback = ()=> {
      window.location.href = `/app/decision/communication?scenario=${currentScenarioId.value}`
    }

    const handleSave = () => {
      const graphData: GraphContainer = resolveGraph(graph.value as Graph);
      console.info('handleSave', graphData);
      if (!currentBehaviorTree.value) {
        message.error('当前决策树不存在');
        return;
      }
      const newTree: BehaviorTree = {
        ...currentBehaviorTree.value,
        graph: graphData,
        xmlContent: JSON.stringify(graphData),
      };
      if (!newTree.name) {
        message.error('行为树名称不能为空.');
        return;
      }
      if (!newTree.englishName) {
        message.error('行为树英文名称不能为空.');
        return;
      }
      let res = null;
      if (currentBehaviorTree.value.id > 0) {
        res = createTree(newTree);
      } else {
        res = updateTree(newTree);
      }
      res.then(r => {
        if (r.code === 200) {
          treesCardRef.value?.refresh();
          message.success(r.msg ?? '操作成功.');
        } else {
          message.error(r.msg ?? '操作失败.');
        }
      });
    };

    // 初始化
    onMounted(() => {
      init();
      loadDatasource();
    });


    // 清理
    onBeforeUnmount(() => destroy());

    return {
      nodeCommands,
      currentScenarioId,
      platforms,
      subPlatforms,
      treesCardRef,
      handleCreateTree,
      currentTreeEditing,
      currentBehaviorTree,
      currentGraph,
      selectedNodeTaskElement,
      selectedModelNode,
      graph,
      canvas,
      zoomIn,
      zoomOut,
      fitToScreen,
      centerContent,
      handleDragStart,
      handleDragEnd,
      handleDragEnter,
      handleDragLeave,
      handleDrop,
      isDraggingOver,
      handleSave,
      handleUpdateElement,
      handleSelectTree,
      handleGoback,
    };
  },
});
</script>