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

<script setup>
import { ref, onMounted, onUnmounted, watch, nextTick } from 'vue';
import * as echarts from 'echarts';

// 使用 ref 创建图表容器的引用
const chartRef = ref(null);
let chartInstance = null;

// 定义组件接收的 props
const props = defineProps({
  nodes: {
    type: Array,
    default: () => [],
  },
  links: {
    type: Array,
    default: () => [],
  },
  theme: {
    type: String,
    default: 'light'
  }
});

// 生成示例数据的函数（用于测试）
const generateSampleData = () => {
  const sampleNodes = [
    { name: '主概念', category: 0, value: '核心主题', symbolSize: 60 },
    { name: '子概念1', category: 1, value: '相关主题1', symbolSize: 40 },
    { name: '子概念2', category: 1, value: '相关主题2', symbolSize: 40 },
    { name: '子概念3', category: 1, value: '相关主题3', symbolSize: 40 },
    { name: '孙概念1', category: 1, value: '详细主题1', symbolSize: 30 },
    { name: '孙概念2', category: 1, value: '详细主题2', symbolSize: 30 }
  ];
  
  const sampleLinks = [
    { source: '主概念', target: '子概念1' },
    { source: '主概念', target: '子概念2' },
    { source: '主概念', target: '子概念3' },
    { source: '子概念1', target: '孙概念1' },
    { source: '子概念2', target: '孙概念2' }
  ];
  
  return { nodes: sampleNodes, links: sampleLinks };
};

// 验证数据格式
const validateData = () => {
  if (!Array.isArray(props.nodes) || props.nodes.length === 0) {
    console.warn('MindChart: nodes 数据为空或格式不正确');
    return false;
  }
  
  // 确保每个节点都有必要的属性
  const validNodes = props.nodes.every(node => 
    node && typeof node === 'object' && node.name
  );
  
  if (!validNodes) {
    console.warn('MindChart: 某些节点数据格式不正确');
    return false;
  }
  
  return true;
};

// 获取实际使用的数据
const getChartData = () => {
  let nodes = props.nodes;
  let links = props.links;
  
  // 如果没有数据，使用示例数据
  if (!Array.isArray(nodes) || nodes.length === 0) {
    const sampleData = generateSampleData();
    nodes = sampleData.nodes;
    links = sampleData.links;
    console.log('MindChart: 使用示例数据');
  }
  
  return { nodes, links };
};

// 初始化图表
const initChart = async () => {
  if (!chartRef.value) {
    console.warn('MindChart: 图表容器未找到');
    return;
  }
  
  // 获取图表数据
  const { nodes, links } = getChartData();
  
  // 验证数据
  if (!nodes || nodes.length === 0) {
    console.warn('MindChart: 没有可用的节点数据');
    return;
  }
  
  try {
    // 销毁旧的图表实例（如果存在）
    if (chartInstance) {
      echarts.dispose(chartInstance);
      chartInstance = null;
    }
    
    // 等待DOM更新完成
    await nextTick();
    
    // 确保容器有尺寸
    const container = chartRef.value;
    if (container.offsetWidth === 0 || container.offsetHeight === 0) {
      console.warn('MindChart: 容器尺寸为0，延迟初始化');
      setTimeout(() => initChart(), 100);
      return;
    }
    
    // 初始化 ECharts 实例
    chartInstance = echarts.init(container, props.theme);
    
    // 配置图表选项
    const option = {
      backgroundColor: 'transparent',
      tooltip: {
        show: true,
        formatter: (params) => {
          if (params.dataType === 'node') {
            return `${params.data.name}<br/>${params.data.value || ''}`;
          }
          return `${params.data.source} → ${params.data.target}`;
        }
      },
      series: [{
        type: 'graph',
        layout: 'force', // 使用力导向布局
        force: {
          repulsion: 200, // 节点之间的斥力
          gravity: 0.1, // 向中心的引力
          edgeLength: 100, // 边的默认长度
          layoutAnimation: true,
        },
        data: nodes.map(node => ({
          ...node,
          category: node.category || 1, // 确保有category属性
          symbolSize: node.symbolSize || (node.category === 0 ? 50 : 30)
        })),
        links: links || [],
        categories: [
          { name: '主节点' },
          { name: '子节点' }
        ],
        roam: true, // 开启缩放和平移
        label: {
          show: true,
          position: 'right',
          formatter: '{b}',
          fontSize: 12,
          color: '#333'
        },
        edgeLabel: {
          show: false
        },
        emphasis: {
          focus: 'adjacency',
          lineStyle: {
            width: 3
          }
        },
        lineStyle: {
          opacity: 0.8,
          width: 2,
          curveness: 0.2, // 连接线曲度，0-1之间，0为直线，1为最大曲度
          color: '#666', // 连接线颜色
          type: 'solid' // 线条类型：solid, dashed, dotted
        },
        symbolSize: (val) => {
          // 主节点大小较大，子节点较小
          // 添加安全检查，防止 val 为 undefined 或没有 category 属性
          if (!val || typeof val.category === 'undefined') {
            return 30; // 默认大小
          }
          return val.category === 0 ? 50 : 30;
        },
        itemStyle: {
          borderColor: '#fff',
          borderWidth: 1,
          shadowBlur: 10,
          shadowColor: 'rgba(0, 0, 0, 0.3)'
        }
      }]
    };
    
    // 设置图表选项
    chartInstance.setOption(option);
    
    // 添加点击事件处理（可选）
    chartInstance.on('click', (params) => {
      if (params.dataType === 'node') {
        console.log('点击了节点:', params.data);
        // 可以在这里触发自定义事件
      }
    });
    
    console.log('MindChart: 图表初始化成功');
  } catch (error) {
    console.error('MindChart: 图表初始化失败', error);
  }
};

// 响应窗口大小变化
const handleResize = () => {
  if (chartInstance) {
    try {
      chartInstance.resize();
    } catch (error) {
      console.error('MindChart: 调整大小失败', error);
    }
  }
};

// 监听 props 变化
watch(() => [props.nodes, props.links, props.theme], () => {
  nextTick(() => {
    initChart();
  });
}, { deep: true });

// 生命周期钩子
onMounted(() => {
  // 延迟初始化，确保DOM完全渲染
  setTimeout(() => {
    initChart();
  }, 100);
  
  window.addEventListener('resize', handleResize);
});

onUnmounted(() => {
  if (chartInstance) {
    try {
      chartInstance.dispose();
    } catch (error) {
      console.error('MindChart: 销毁图表失败', error);
    }
    chartInstance = null;
  }
  window.removeEventListener('resize', handleResize);
});
</script>

<style scoped>
.mind-map-container {
  width: 100%;
  height: 600px;
  border: 1px solid #eaeaea;
  border-radius: 8px;
  overflow: hidden;
  position: relative;
}

.mind-map-chart {
  width: 100%;
  height: 100%;
  min-height: 400px;
}
</style>