<template>
  <el-dialog v-model="dialogFormVisible" title="图谱节点详情" width="1100" height="600">
    <div id="graph" class="graph">

        <svg id="mindSvg" ref="svgContainer" viewBox="0 0 900 600" width="900" height="600" >                
              <!-- 定义箭头 -->
              <defs>
                <marker id="arrow"
                        viewBox="0 -5 10 10"
                        refX="8"
                        refY="0"
                        markerWidth="6"
                        markerHeight="6"
                        orient="auto">
                  <path d="M 0,-5 L 10,0 L 0,5" fill="rgb(65, 143, 146)"/>
                </marker>
                <pattern id="crossHatch" patternUnits="userSpaceOnUse" width="10" height="10" patternTransform="rotate(45)">
                  <line x1="0" y1="0" x2="0" y2="10" stroke="lightgrey" stroke-width="1"/>
                  <line x1="0" y1="0" x2="10" y2="0" stroke="lightgrey" stroke-width="1"/>
                </pattern>
              </defs>
       
            </svg>
    </div>
  </el-dialog>
</template>

<script setup lang="ts">

import { ref, onMounted, defineEmits ,nextTick} from 'vue'
import { getNodeNeighbors } from '@/api/GraphApi'
import svgPanZoom  from 'svg-pan-zoom';
import { ElMessageBox } from 'element-plus';
const dialogFormVisible = ref(false)
const nodesData = ref([{ id: 1, label: 'Node 1', direction:"in"}])
const edgesData = ref([{ from: 1, to: 2 ,fromPos: {x:100,y:100}, toPos: {x:100,y:100}}])
const svgContainer = ref()
const props = defineProps({
    title: { type: String, required: true, default: '图谱节点详情'},
    nodeId: { type: Number, required: true, default: 0},
    graphId: { type: Number, required: true, default: 0}
  
})
const loadNodeNeighbors = (node_id:number) => {
  nodesData.value.length = 0
  edgesData.value.length = 0
    getNodeNeighbors(node_id, props.graphId).then((res:any) => {
      for (let i = 0; i < res.records.length; i++) {
        const element = res.records[i];
        console.log(element)
        nodesData.value.push({id:element.id, label:element.name, direction:element.direction})   

      }        
      drawGraph(node_id)
    })
}
function handleNodeClick(nodeId){
  loadNodeNeighbors(Number(nodeId)) 
  // var result = ElMessageBox.confirm('是否加载该节点的邻居节点？', '提示', )
  // result.then(() => {
    
  // })
}
const drawGraph = (node_id:number) => {
    const svg = svgContainer.value //document.getElementById('mindSvg') as SVGElement | null;
    if (svg == null) {
        console.log("svg is null")
        console.log(svgContainer.value)
        return; 
    }
    svg.innerHTML = '';
    console.log("drawGraph", svg)
    const svgWidth = svg.width.baseVal.value
    const svgHeight = svg.height.baseVal.value
    console.log("svgWidth", svgWidth, "svgHeight", svgHeight)
    // 计算左边，中间，和右边的节点数量
    var totalNodes = nodesData.value.length    
    var leftNodesCount = 0
    var rightNodesCount = 0
    nodesData.value.forEach(node => {
     if (node.direction=='in') {
        leftNodesCount += 1
     } else if (node.direction=='out') {
        rightNodesCount += 1
     }
    })
    var rectHeight = 40
    var rectWidth = 120
    var rectMargin = 20
    var totalLeftHeight = leftNodesCount * (rectHeight + rectMargin) - rectMargin
    var totalRightHeight = rightNodesCount * (rectHeight + rectMargin) - rectMargin
    var leftTop = [svgWidth / 4, (svgHeight - totalLeftHeight) / 2] // 左边顶部节点的位置    
    var rightTop = [svgWidth * 3 / 4, (svgHeight - totalRightHeight) / 2] // 左边顶部节点的位置    
    const centerPos = {x:svgWidth / 2 , y:svgHeight / 2 }
    var gLinesGroup = document.createElementNS('http://www.w3.org/2000/svg', 'g')
    var gRectsGroup = document.createElementNS('http://www.w3.org/2000/svg', 'g')
    svg.appendChild(gLinesGroup)
    svg.appendChild(gRectsGroup)
    // 绘制节点
    var left_index = 1
    var right_index = 1
    nodesData.value.forEach(node => {
        console.log("draw node:",node)
        const g = document.createElementNS('http://www.w3.org/2000/svg', 'g');
        if (node.direction=="in") {
          var pos = {x:leftTop[0]- rectWidth/2 , y:leftTop[1] + (left_index - 1) * (rectHeight + rectMargin) }
          g.setAttribute('transform', `translate(${pos.x}, ${pos.y})`);
          left_index += 1
          pos.x = pos.x + rectWidth/2
          pos.y = pos.y + rectHeight/2
          edgesData.value.push({from:node.id, to:node_id, fromPos: pos, toPos: centerPos})
        } else if (node.direction=="out") {
          var pos ={x:rightTop[0]- rectWidth/2 ,y:rightTop[1] + (right_index - 1) * (rectHeight + rectMargin)}
          g.setAttribute('transform', `translate(${pos.x}, ${pos.y})`); 
          right_index += 1        
          pos.x = pos.x + rectWidth/2
          pos.y = pos.y + rectHeight/2  
          edgesData.value.push({from:node_id, to:node.id, fromPos: centerPos, toPos: pos})
        } else if (node.direction=="self") {
          g.setAttribute('transform', `translate(${svgWidth / 2 - rectWidth/2}, ${svgHeight / 2 - rectHeight/2})`);
        }
        const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
        rect.setAttribute('width', '120');
        rect.setAttribute('height', '40');
        rect.setAttribute('data-node-id', node.id.toString());
        if (node.direction=="self") {
          rect.setAttribute('fill', '#418f92'); 
        } else {
          
          rect.setAttribute('fill', '#f0f0f0');
        }
        //rect.setAttribute('stroke', '#418f92');
        rect.setAttribute('rx', '5');
        rect.setAttribute('class', 'node_rect');
        
        const link = document.createElementNS('http://www.w3.org/2000/svg', 'a')
        
        link.setAttribute('data-node-id', node.id.toString())
        link.setAttribute('class', 'node_text')
        const text = document.createElementNS('http://www.w3.org/2000/svg', 'text');
        text.setAttribute('x', '60');
        text.setAttribute('y', '25');
        text.setAttribute('text-anchor', 'middle');     
  
        text.textContent = node.label;
        link.appendChild(text)
        
        g.appendChild(rect);
        g.appendChild(link);
        gRectsGroup.appendChild(g);
        
        console.log("draw node finished")
        
    });
    // 绘制边
    edgesData.value.forEach(edge => {
        const line = document.createElementNS('http://www.w3.org/2000/svg', 'line');
        line.setAttribute('x1', `${edge.fromPos.x}`);
        line.setAttribute('y1', `${edge.fromPos.y}`);
        line.setAttribute('x2', `${edge.toPos.x}`);
        line.setAttribute('y2', `${edge.toPos.y}`);
        line.setAttribute('stroke', '#418f92');
        line.setAttribute('stroke-width', '2');

        line.setAttribute('style', 'z-index:0');
        gLinesGroup.appendChild(line);
    });
    // document.querySelectorAll('.node_rect').forEach((rect:any) => {
    //     rect.addEventListener('click', () => {
    //       const nodeId = rect.getAttribute('data-node-id');
    //       console.log('Node clicked:', nodeId);
    //       handleNodeClick(nodeId)
    //     });
    //   }) 
      
    document.querySelectorAll('.node_text').forEach((rect:any) => {
        rect.addEventListener('click', () => {
          const nodeId = rect.getAttribute('data-node-id');
          console.log('Node clicked:', nodeId);
          handleNodeClick(nodeId)
        });
      }) 
    
}
let panZoomController: any = null;

onMounted(() => {
  nextTick(() => {

  });
});
const showDialog = (visible:boolean = true, nodeId:number) => {
    dialogFormVisible.value = visible
    
    loadNodeNeighbors(nodeId)
}
defineExpose({ showDialog })
</script>
<style scoped>
.graph {
    background-color:rgb(255, 255, 255);
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
}
  
.edge_line {
    stroke: #418f92;
    stroke-width: 20;
    marker-end: url(#arrow);
    z-index: 1;
}
.node_rect {
    font-size: 14px;
    font-weight: bold;
    background-color: #cecece;
    z-index: 10;
}
</style>
