<template>
  <div ref="chartRef" :style="containerStyle" class="echarts-container"></div>
</template>

<script setup>
import { ref, onMounted, watch, onUnmounted, nextTick } from "vue";
import installer from "../utils/install.js";
import * as echarts from 'echarts/core';
import { PieChart, RadarChart } from 'echarts/charts';
import { PolarComponent } from 'echarts/components';

// Register components directly
echarts.use([PieChart, RadarChart, PolarComponent]);

/**
 * ECharts 图表类型说明
 * 
 * 支持的主要图表类型：
 * 1. LineChart - 折线图：用于展示数据随时间或其他序列的变化趋势
 *    适用场景：时间序列数据、连续数据变化、趋势分析
 *    特点：清晰展示变化趋势，支持多条线对比，可设置平滑曲线
 * 
 * 2. BarChart - 柱状图/条形图：用于比较不同类别的数据大小
 *    适用场景：分类数据对比、排名展示、分布统计
 *    特点：直观比较数据大小，支持堆叠柱状图和分组柱状图
 * 
 * 3. PieChart - 饼图/环形图：用于展示部分与整体的比例关系
 *    适用场景：占比分析、部分与整体关系、百分比展示
 *    特点：直观显示比例，可设置空心环形效果，支持扇区交互
 * 
 * 4. RadarChart - 雷达图/蜘蛛图：用于多维度数据的综合对比
 *    适用场景：多维数据分析、综合能力评估、多指标对比
 *    特点：同时展示多个维度数据，直观对比综合实力
 * 
 * 5. ScatterChart - 散点图：用于展示两个变量之间的相关关系
 *    适用场景：相关性分析、分布模式识别、异常点检测
 *    特点：展示数据分布规律，支持气泡图表示第三个维度
 * 
 * 6. MapChart - 地图：用于地理数据的可视化展示
 *    适用场景：地区数据对比、地理分布、区域统计
 *    特点：结合地理信息，支持多种地图数据和交互方式
 * 
 * 7. FunnelChart - 漏斗图：用于展示流程中各阶段的数据变化
 *    适用场景：流程分析、转化漏斗、人口金字塔
 *    特点：直观展示流程损耗，可设置水平或垂直方向
 * 
 * 8. SunburstChart - 旭日图：用于展示层级数据的结构和占比
 *    适用场景：层级数据可视化、树状结构展示、多层占比分析
 *    特点：从中心向外辐射展示层级关系，面积表示数据大小
 * 
 * 9. CustomChart - 自定义图表：用于创建自定义可视化效果
 *    适用场景：特殊可视化需求、创意图表、自定义交互
 *    特点：高度灵活，支持自定义图形和交互逻辑
 * 
 * 10. HeatmapChart - 热力图：用于展示数据密度或权重分布
 *     适用场景：数据密集度分析、相关性矩阵、时间模式识别
 *     特点：通过颜色深浅展示数据密度，支持大型数据集可视化
 */

// Props定义
const props = defineProps({
  // 图表配置选项
  option: {
    type: Object,
    default: () => ({}),
    required: true,
  },
  // 需要加载的ECharts组件列表
  components: {
    type: Array,
    default: () => [
      "LineChart",
      "BarChart",
      "PieChart",
      "RadarChart",
      "TitleComponent",
      "TooltipComponent",
      "GridComponent",
      "LegendComponent",
      "ToolboxComponent",
    ],
  },
  // 需要加载的地图数据列表
  maps: {
    type: Array,
    default: () => [],
  },
  // ECharts初始化选项
  initOptions: {
    type: Object,
    default: () => ({}),
  },
  // 容器样式
  style: {
    type: Object,
    default: () => ({
      width: "100%",
      height: "100%",
    }),
  },
});

// 事件定义
const emit = defineEmits(["init", "resize", "click", "dataChange"]);

// 图表DOM引用
const chartRef = ref();
// ECharts实例
let chartInstance = null;

// 计算容器样式
const containerStyle = ref({
  width: props.style.width,
  height: props.style.height,
  ...props.style,
});

// 初始化图表
const initChart = async () => {
  if (!chartRef.value) return;

  try {
    // 使用installer初始化ECharts实例
    chartInstance = await installer(chartRef.value, {
      components: props.components,
      maps: props.maps,
      initOptions: props.initOptions,
    });

    // 设置图表配置
    if (props.option) {
      chartInstance.setOption(props.option);
    }

    // 绑定事件
    bindEvents();

    // 触发初始化完成事件
    emit("init", chartInstance);
  } catch (error) {
    console.error("ECharts initialization failed:", error);
  }
};

// 绑定图表事件
const bindEvents = () => {
  if (!chartInstance) return;

  // 绑定点击事件
  chartInstance.on("click", (params) => {
    emit("click", params);
  });
};

// 更新图表配置
const updateChart = () => {
  if (!chartInstance || !props.option) return;

  chartInstance.setOption(props.option, true);
  emit("dataChange");
};

// 调整图表大小
const resizeChart = () => {
  if (!chartInstance) return;

  chartInstance.resize();
  emit("resize");
};

// 处理窗口大小变化
const handleResize = () => {
  nextTick(() => {
    resizeChart();
  });
};

// 监听option变化
watch(
  () => props.option,
  () => {
    updateChart();
  },
  { deep: true }
);

// 监听style变化
watch(
  () => props.style,
  (newStyle) => {
    containerStyle.value = {
      width: newStyle.width,
      height: newStyle.height,
      ...newStyle,
    };
    nextTick(() => {
      resizeChart();
    });
  },
  { deep: true }
);

// 组件挂载
onMounted(() => {
  nextTick(() => {
    initChart();
  });
  // 添加窗口大小变化监听
  window.addEventListener("resize", handleResize);
});

// 组件卸载
onUnmounted(() => {
  // 移除窗口大小变化监听
  window.removeEventListener("resize", handleResize);
  // 销毁图表实例
  if (chartInstance) {
    chartInstance.dispose();
    chartInstance = null;
  }
});

// 暴露方法给父组件
defineExpose({
  updateChart,
  resizeChart,
  getInstance: () => chartInstance,
});
</script>

<style lang='less' scoped>
.echarts-container {
  width: 100%;
  height: 100%;
  min-height: 0;
}
</style>