<template>
  <div class="mind-map-container">
    <div ref="containerRef" class="mind-map"></div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
import G6 from '@antv/g6'
import { useWrittingAsstaintStore } from "@/stores/writtingAsstaintStore";
// 子组件直接获取Pinia Store（核心优化）
const store = useWrittingAsstaintStore();

// pushfenzhi 
let mindMapData = {
  id: 'root',
  label: '名称',
  children: [

  ]
}

let uniqueId = 1;

function convertMindMap(rawData) {
  uniqueId = 1; // 每次重置
  const tree = buildTreeRecursive(rawData.node, rawData.links);
  return tree[0]; // 返回单个根节点
}

const raw = store.resultWriteData.政令深度分析.条款分析.科技条款内容[0].领域举措.data;
const treeData = convertMindMap(raw);


// 全局唯一自增计数器（最稳、最短、永不重复）

// 递归构建树 + 自动生成全局唯一数字ID
function buildTreeRecursive(nodes, links, parentId = null) {
  const tree = [];

  // 找到当前父节点的所有子节点
  const childrenNodes = nodes.filter(node => {
    if (parentId === null) {
      return node.depth === 0;
    }
    return links.some(
      link => link.source === parentId && link.target === node.id
    );
  });

  // 遍历子节点，递归生成
  for (const node of childrenNodes) {
    const currentNode = {
      id: `${uniqueId++}_`, // 🔥 纯数字自增，绝对唯一！
      label: node.name,
      children: buildTreeRecursive(nodes, links, node.id)
    };

    tree.push(currentNode);
  }

  return tree;
}

treeData.id= 'root',
console.log(treeData)
mindMapData=treeData








const containerRef = ref(null)





let graph = null

// 文字换行（不溢出）
function splitTextToLines(text, maxWidth, fontSize) {
  const canvas = document.createElement('canvas')
  const ctx = canvas.getContext('2d')
  ctx.font = `${fontSize}px sans-serif`
  const lines = []
  let currentLine = ''
  let width = 0

  for (const char of text) {
    const w = ctx.measureText(char).width
    if (width + w > maxWidth) {
      lines.push(currentLine)
      currentLine = char
      width = w
    } else {
      currentLine += char
      width += w
    }
  }
  if (currentLine) lines.push(currentLine)

  const lineHeight = fontSize + 8
  const totalHeight = lineHeight * lines.length + 24
  return { lines, lineHeight, totalHeight }
}

onMounted(() => {
  if (graph) graph.destroy()
  
  const el = containerRef.value
  if (!el) return

  // 注册节点
  G6.registerNode('custom-node', {
    draw(cfg, group) {
      const isRoot = cfg.id === 'root'
      const isDept = cfg.id.startsWith('dept')
      const MAX_WIDTH = isRoot ? 280 : isDept ? 240 : 400
      const fontSize = isRoot ? 16 : isDept ? 15 : 14
      const fontWeight = isRoot || isDept ? 'bold' : 'normal'
      const color = 'rgba(5, 95, 194, 1)'
      const padding = 16

      const { lines, lineHeight, totalHeight } = splitTextToLines(cfg.label, MAX_WIDTH - padding * 2, fontSize)
      const nodeW = MAX_WIDTH
      const nodeH = totalHeight

      // 节点背景
      group.addShape('rect', {
        attrs: {
          x: -nodeW / 2,
          y: -nodeH / 2,
          width: nodeW,
          height: nodeH,
          fill: '#f8fcff',
          stroke: color,
          lineWidth: 1,
          radius: 6
        }
      })

      // 文字居中
      lines.forEach((line, i) => {
        group.addShape('text', {
          attrs: {
            text: line,
            x: 0,
            y: (i - (lines.length - 1) / 2) * lineHeight,
            textAlign: 'center',
            textBaseline: 'middle',
            fontSize, fontWeight, fill: color
          }
        })
      })

      return group
    },
    getAnchorPoints: () => [[0, 0.5], [1, 0.5]]
  }, 'single-node')


  graph = new G6.TreeGraph({
    container: el,
    width: el.offsetWidth,
    height: el.offsetHeight,
    modes: {
      default: ['drag-canvas', 'zoom-canvas', 'collapse-expand']
    },
    defaultNode: { type: 'custom-node' },
    defaultEdge: {
      type: 'cubic-horizontal',
      style: { stroke: 'rgba(5, 95, 194, 0.4)', lineWidth: 1 }
    },

    layout: {
      type: 'compactBox',
      direction: 'LR',
      getWidth: () => 400,
      getHGap: () => 80,
      getVGap: () => 50,
    }
  })

  graph.data(mindMapData)
  graph.render()

  // 自适应显示
  setTimeout(() => {
    graph.fitCenter()
    graph.zoomTo(0.65)
  }, 200)
})

onUnmounted(() => graph?.destroy())


function exportGraph() {
  if (!graph) return
  graph.downloadFullImage('思维导图.png')
}
defineExpose({
  exportGraph
});
</script>

<style scoped>
.mind-map-container {
  width: 100%;
  height: 100vh;
  background: #f5f7fa;
}
.mind-map {
  width: 92%;
  height: 100%;
  margin: 0 auto;
}
</style>