<template>
  <div class="knowledge-graph-container">
    <!-- 控制面板 -->
    <div class="control-panel">
      <!-- 节点控制 -->
      <div class="section">
        <h5>节点控制</h5>
        <label style="text-align: left;margin: 10px 0;display: flex;align-items: center;font-size: 12px;">
          <input v-model="nodeShowLabel" type="checkbox" />
          显示节点标签
        </label>
        <div class="form-group">
          <label>字体名称:</label>
          <select v-model="nodeFontFamily">
            <!-- 中文常用字体 -->
            <option value="Microsoft YaHei, sans-serif">微软雅黑</option>
            <option value="SimSun, serif">宋体（SimSun）</option>
            <option value="SimHei, sans-serif">黑体（SimHei）</option>
            <option value="KaiTi, serif">楷体（KaiTi）</option>
            <option value="FangSong, serif">仿宋（FangSong）</option>
            <option value="PingFang SC, Helvetica Neue, sans-serif">苹方（PingFang SC）</option>

            <!-- 英文/通用字体 -->
            <option value="Arial, sans-serif">Arial</option>
            <option value="Helvetica, sans-serif">Helvetica</option>
            <option value="Times New Roman, serif">Times New Roman</option>
            <option value="Georgia, serif">Georgia</option>
            <option value="Courier New, monospace">Courier New（等宽）</option>
            <option value="Verdana, sans-serif">Verdana</option>
            <option value="Tahoma, sans-serif">Tahoma</option>
            <option value="Impact, sans-serif">Impact</option>
          </select>
        </div>
        <div class="slider-group">
          <span>字体大小: {{ nodeFontSize }}px</span>
          <input
              v-model.number="nodeFontSize"
              type="range"
              min="10"
              max="24"
              step="1"
          />
        </div>

        <div class="color-picker">
          <label>字体颜色:</label>
          <input v-model="nodeFontColor" type="color" />
        </div>
        <div class="form-group">
          <label>图形:</label>
          <select v-model="nodeShape">
            <option value="circle">圆形</option>
            <option value="diamond">菱形</option>
            <option value="triangle">三角形</option>
            <option value="rect">矩形</option>
            <option value="star">星形</option>
            <option value="hexagon">六边形</option>
          </select>
        </div>
        <div class="form-group">
          <label>尺寸:</label>
          <input v-model.number="nodeSize" type="number" min="30" max="100" />
        </div>
        <div class="color-picker">
          <label>填充颜色:</label>
          <input v-model="nodeFill" type="color" />
        </div>
        <div class="color-picker">
          <label>边框颜色:</label>
          <input v-model="nodeStroke" type="color" />
        </div>
        <div class="form-group">
          <label>边框尺寸:</label>
          <input v-model.number="nodeLineWidth" type="number" min="1" max="5" />
        </div>
      </div>

      <!-- 连边控制 -->
      <div class="section">
        <h5>连边控制</h5>
        <label style="text-align: left;margin: 10px 0;display: flex;align-items: center;font-size: 12px;">
          <input v-model="edgeShowLabel" type="checkbox" />
          显示连边标签
          <input v-model="edgeEndArrow" type="checkbox" style="margin-left: 10px"/>
          显示端点箭头
        </label>
        <div class="form-group">
          <label>字体名称:</label>
          <select v-model="edgeFontFamily">
            <option value="Microsoft YaHei, sans-serif">微软雅黑</option>
            <option value="SimSun, serif">宋体</option>
            <option value="SimHei, sans-serif">黑体</option>
            <option value="Arial, sans-serif">Arial</option>
            <option value="sans-serif">无衬线（默认）</option>
          </select>
        </div>
        <div class="slider-group">
          <span>字体大小: {{ edgeFontSize }}px</span>
          <input
              v-model.number="edgeFontSize"
              type="range"
              min="8"
              max="16"
              step="1"
          />
        </div>
        <div class="color-picker">
          <label>字体颜色:</label>
          <input v-model="edgeFontColor" type="color" />
        </div>
        <div class="form-group">
          <label>连边类型:</label>
          <select v-model="edgeType">
            <option value="line">直线</option>
            <option value="polyline">折线边</option>
            <option value="cubic">三次贝塞尔曲线边</option>
            <option value="cubic-horizontal">水平三次贝塞尔曲线边</option>
            <option value="cubic-vertical">垂直三次贝塞尔曲线边</option>
            <option value="quadratic">二次贝塞尔曲线边</option>

          </select>
        </div>
        <div class="form-group">
          <label>线粗细:</label>
          <input v-model.number="edgeLineWidth" type="number" min="1" max="5" />
        </div>
        <div class="color-picker">
          <label>线条颜色:</label>
          <input v-model="edgeStroke" type="color" />
        </div>
<!--        <label>-->
<!--          <input v-model="edgeEndArrow" type="checkbox" />-->
<!--          显示端点箭头-->
<!--        </label>-->
      </div>
      <button @click="resetView">重置视图</button>
      <button @click="resetStyle">重置样式</button>
      <!-- 操作按钮 -->

    </div>

    <!-- 图谱容器 -->
    <div ref="graphContainer" class="graph-container" id="container"></div>
  </div>
</template>

<script>
import { getTestGraphData } from "@/api/graph"
import { Graph } from '@antv/g6';

export default {
  name: 'GraphDemo',
  data() {
    return {
      G6: null, // 添加这个
      // 节点样式
      nodeShowLabel: true,
      nodeFontSize: 12,
      nodeFontColor: '#000000',
      nodeShape: 'circle',
      nodeSize: 60,
      nodeFill: '#9FD5FF',
      nodeStroke: '#5B8FF9',
      nodeLineWidth: 2,
      nodeFontFamily: 'Microsoft YaHei, sans-serif',

      // 边样式
      edgeShowLabel: true,
      edgeFontSize: 10,
      edgeFontColor: '#666666',
      edgeType: 'line',
      edgeLineWidth: 2,
      edgeStroke: '#F00',
      edgeEndArrow: true,
      edgeFontFamily: 'Microsoft YaHei, sans-serif',

      defaultData: {
        nodes: [
          {id: 'A', label: '人工智能'},
          {id: 'B', label: '机器学习'},
          {id: 'C', label: '深度学习'}
        ],
        edges: [
          {source: 'A', target: 'B', label: '包含'},
          {source: 'B', target: 'C', label: '子领域'}
        ]
      }
    }
  },

  async mounted() {
    await this.$nextTick();
    try {
      const response = await getTestGraphData(); // 等待 Promise 解析
      const updatedNodes = response.nodes.map(node => ({
        ...node,
        type: this.nodeShape,
        style:{
          size: this.nodeSize,
          fill: this.nodeFill,
          stroke: this.nodeStroke,
          lineWidth: this.nodeLineWidth,
          label: this.nodeShowLabel,
          labelFontSize: this.nodeFontSize,
          labelFontFamily: this.nodeFontFamily,
          labelFontColor: this.nodeFontColor,
        }
      }))

      const updatedEdges = response.edges.map(edge => ({
        ...edge,
        type:  this.edgeType,
        style: {
          endArrow: this.edgeEndArrow,
          stroke: this.edgeStroke,
          lineWidth: this.edgeLineWidth,
          label: this.edgeShowLabel,
          labelFontSize: this.edgeFontSize,
          labelFontFamily: this.edgeFontFamily,
          labelFill: this.edgeFontColor,
        },

      }))
      const updatedData = {
        nodes: updatedNodes,
        edges: updatedEdges
      }
      this.defaultData = updatedData
      setTimeout(() => {
        this.initGraph();
        window.addEventListener('resize', this.handleResize);
      }, 1000);
    } catch (error) {
      console.error('加载图谱数据失败:', error);
    }
  },
  beforeUnmount() {
    this._graph.destroy()
    this._graph = null;
    window.removeEventListener('resize', this.handleResize);
  },
  watch: {
    // 节点相关
    nodeShowLabel: 'updateAllNodes',
    nodeFontSize: 'updateAllNodes',
    nodeFontColor: 'updateAllNodes',
    nodeShape: 'updateAllNodes',
    nodeSize: 'updateAllNodes',
    nodeFill: 'updateAllNodes',
    nodeStroke: 'updateAllNodes',
    nodeLineWidth: 'updateAllNodes',
    nodeFontFamily: 'updateAllNodes',

    // 边相关
    edgeShowLabel: 'updateAllEdges',
    edgeFontSize: 'updateAllEdges',
    edgeFontColor: 'updateAllEdges',
    edgeType: 'updateAllEdges',
    edgeLineWidth: 'updateAllEdges',
    edgeStroke: 'updateAllEdges',
    edgeEndArrow: 'updateAllEdges',
    edgeFontFamily: 'updateAllEdges',
  },
  methods: {

    initGraph() {

      if (this._graph!=null){
        this._graph.destroy()
        this._graph = null;
      }

      const container = this.$refs.graphContainer;
      const width = container.clientWidth || 800;
      const height = container.clientHeight || 600;

      const graph = new Graph({
        container,
        width,
        height,
        layout: {
          type: 'radial',
          nodeSize: 32,
          unitRadius: 100,
          linkDistance: 200,
        },
        behaviors: [ 'zoom-canvas', 'drag-element','click-select','focus-element',
          {
            type: 'hover-activate',
            degree: 1, // 👈🏻 Activate relations.
          },
          {
            type: 'drag-canvas',
            enable: (event) => event.shiftKey === false,
          },
          {
            type: 'brush-select',
          },
        ],

        node: {
          style: {
            labelText: (d) => d.data.name,
            labelPlacement: 'center',

            labelWordWrap: true,
            labelMaxWidth: '150%',
            labelMaxLines: 3,
            labelTextOverflow: 'ellipsis',
            labelTextAlign: 'center',
          },
          state: {
            active: {
              fill: '#95D6FB',
              stroke: '#1890FF',
              lineWidth: 2,
              shadowColor: '#1890FF',
              shadowBlur: 10,
            },
            highlight: {
              stroke: '#FF6A00',
              lineWidth: 3,
            },
            disabled: {
              fill: '#ECECEC',
              stroke: '#BFBFBF',
              opacity: 0.5,
            },
          },
        },
        edge: {
          style: {
            labelText: (d) => d.data.relationship.type,
          },
          state: {
            selected: {
              stroke: '#1890FF',
              lineWidth: 2,
            },
            highlight: {
              stroke: '#FF6A00',
              lineWidth: 3,
            },
          },

        },
        data:this.defaultData
      });

      graph.render();
      this._graph = graph
      this._graph?.fitView()
    },

    updateGraph(data) {
      if (!this._graph) return
      this._graph.setData(data)
      this._graph.render()
    },

    updateAllNodes() {
      if (!this._graph) return
      const updatedNodes = this.defaultData.nodes.map(node => ({
        ...node,
        type: this.nodeShape,
        style:{
          size: this.nodeSize,
          fill: this.nodeFill,
          stroke: this.nodeStroke,
          lineWidth: this.nodeLineWidth,
          label: this.nodeShowLabel,
          labelFontSize: this.nodeFontSize,
          labelFontFamily: this.nodeFontFamily,
          labelFontColor: this.nodeFontColor,
        }
      }))
      const updatedData = {
        nodes: updatedNodes,
        edges: this.defaultData.edges
      }
      this.defaultData = updatedData
      this.updateGraph(updatedData)
    },

    updateAllEdges() {
      if (!this._graph) return
      const updatedEdges = this.defaultData.edges.map(edge => ({
        ...edge,
        type:this.edgeType,
        style: {
          endArrow: this.edgeEndArrow,
          stroke: this.edgeStroke,
          lineWidth: this.edgeLineWidth,
          label: this.edgeShowLabel,
          labelFontSize: this.edgeFontSize,
          labelFontFamily: this.edgeFontFamily,
          labelFill: this.edgeFontColor,

        },

      }))
      const updatedData = {
        nodes: this.defaultData.nodes,
        edges: updatedEdges
      }
      this.defaultData = updatedData
      this.updateGraph(updatedData)
    },

    clearAllStates() {
      if (!this._graph) return

      // 清除所有节点的状态
      this._graph.getNodes().forEach(node => {
        this._graph.clearItemStates(node)
      })

      // 清除所有边的状态
      this._graph.getEdges().forEach(edge => {
        this._graph.clearItemStates(edge)
      })
    },

    handleResize() {
      const container = this.$refs.graphContainer
      if (this._graph && container) {
        this._graph.resize(container.offsetWidth, container.offsetHeight)
      }
    },

    resetView() {
      this._graph?.fitView()
    },

    resetStyle() {
      Object.assign(this, {
        nodeShowLabel: true,
        nodeFontSize: 12,
        nodeFontColor: '#000000',
        nodeShape: 'circle',
        nodeSize: 60,
        nodeFill: '#9FD5FF',
        nodeStroke: '#5B8FF9',
        nodeLineWidth: 2,
        nodeFontFamily: 'Microsoft YaHei, sans-serif',

        edgeShowLabel: true,
        edgeFontSize: 10,
        edgeFontColor: '#666666',
        edgeType: 'line',
        edgeLineWidth: 2,
        edgeStroke: '#F00',
        edgeEndArrow: true,
        edgeFontFamily: 'Microsoft YaHei, sans-serif'
      })
    }
  }
}
</script>

<style scoped>
.knowledge-graph-container {
  display: flex;
  height: 100vh;
}

.control-panel {
  width: 280px;
  background: #f5f7fa;
  padding: 16px;
  border-right: 1px solid #ddd;
  box-shadow: 0 0 8px rgba(0, 0, 0, 0.1);
  font-family: 'Microsoft YaHei';
}

.section {
  margin-bottom: 10px;
  padding: 10px;
  background: white;
  border-radius: 8px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

.section h5 {
  margin-top: 0;
  color: #333;
  font-size: 14px;
}

.slider-group {
  margin: 10px 0;
  display: flex;
  align-items: center;
}

.slider-group span {
  margin-right: 10px;
  font-size: 12px;
}

.form-group {
  margin: 10px 0;
  display: flex;
  align-items: center;
}

.form-group label {
  margin-right: 8px;
  font-size: 12px;
}

.form-group select,
.form-group input[type="number"] {
  padding: 4px;
  border: 1px solid #ccc;
  border-radius: 4px;
  font-size: 12px;
}

.color-picker {
  margin: 10px 0;
  display: flex;
  align-items: center;
}

.color-picker label {
  margin-right: 8px;
  font-size: 12px;
}

.color-picker input[type="color"] {
  width: 40px;
  height: 20px;
  border: none;
  cursor: pointer;
}

button {
  width: 45%;
  padding: 10px;
  //margin: 10px 0;
  background: #007bff;
  color: white;
  border: none;
  border-radius: 6px;
  font-size: 14px;
  cursor: pointer;
  margin-right: 2%;
}

button:hover {
  background: #0056b3;
}

.graph-container {
  flex: 1;
  border: 1px solid #eee;
  background: #fff;
}
</style>