<template>
  <div class="pie-charts-wrapper  vue-echarts-3d-components-pie-inner" :style="pieStyle">
    <div ref="chartContainer" class="chart-container"></div>
  </div>
</template>
<script>
// 导入必要的依赖
import * as echarts from 'echarts';
// 正确导入echarts-gl，不需要use方法
import 'echarts-gl';
// 导入默认图片资源
import defaultPieImage from './pie.png';

export default {
  name: 'PieEcharts',
  props: {
    pieData: {
      type: Array,
      default: () => [],
    },
    pieStyle: {
      type: Object,
      default: () => ({
        width: '232px',
        height: '160px',
      })
    },
    // 可以通过props传入自定义图片配置，如果需要
    customGraphic: {
      type: Object,
      default: null
    },
    // 饼图背景图片相关配置
    pieImageConfig: {
      type: Object,
      default: () => ({
        top: '12%',
        left: '5%',
        bounding: 'raw',
        origin: [0.5, 0.5],
        scale: [1.05, 1.05],
      }),
      description: '饼图背景图片相关配置'
    },
    // 背景图样式相关配置
    pieImageStyle: {
      type: Object,
      default: () => ({
        image: null,
        opacity: 0.8,
        width: 200,
        height: 150,
        rotate: -12
      }),
      description: '饼图背景图片样式相关配置'
    },
    // 数据排序方式
    // - 'asc': 按数值从小到大升序排列
    // - 'desc': 按数值从大到小降序排列
    sortOrder: {
      type: String,
      default: 'desc',
      description: '控制饼图数据的排序方式',
      validator: (value) => {
        return ['asc', 'desc'].includes(value);
      }
    },
    // 饼图高度
    pieHeight: {
      type: Number,
      description: '饼图高度'
    },
  },
  data() {
    return {
      chartInstance: null,
      updateTimer: null,
      isUpdating: false // 防止并发更新的标志
    }
  },
  watch: {
    pieData: {
      handler(newData, oldData) {
        // 避免空数据或数据未变化时更新
        if (!this.chartInstance || !newData || newData.length === 0) {
          return;
        }

        // 浅比较数据是否真正变化，避免不必要的更新
        const dataChanged = JSON.stringify(newData) !== JSON.stringify(oldData);
        if (dataChanged) {
          this.updateChart();
        }
      },
      deep: true,
      // 延迟执行，避免初始化时的渲染问题
      immediate: false
    }
  },
  created() {
    this.updateTimer = null;
  },
  mounted() {
    this.initChart();
    window.addEventListener('resize', this.handleResize);
  },
  beforeUnmount() {
    if (this.updateTimer) {
      clearTimeout(this.updateTimer);
    }
    if (this.chartInstance) {
      this.chartInstance.dispose();
      this.chartInstance = null;
    }
    window.removeEventListener('resize', this.handleResize);
  },
  methods: {
    async initChart() {
      await this.$nextTick();
      this.chartInstance = echarts.init(this.$refs.chartContainer);
      const option = this.initPie();
      this.chartInstance.setOption(option);
    },
    handleResize() {
      if (this.chartInstance) {
        this.chartInstance.resize();
      }
    },
    // 防抖更新图表，避免递归更新
    updateChart() {
      // 防止并发更新
      if (this.isUpdating) {
        return;
      }

      if (this.updateTimer) {
        clearTimeout(this.updateTimer);
      }

      this.updateTimer = setTimeout(() => {
        if (this.chartInstance) {
          try {
            this.isUpdating = true;
            const option = this.initPie();
            this.chartInstance.setOption(option, true);
          } catch (error) {
            console.error('Chart update error:', error);
          } finally {
            this.isUpdating = false;
          }
        }
      }, 100); // 增加延迟时间，确保防抖效果
    },
    /** 初始化饼图 */
    initPie() {
      // 优化的扇形曲面参数方程，避免复杂的条件判断
      const getParametricEquation = (startRatio, endRatio, isSelected, isHovered, k = 1 / 3, h = 10) => {
        const midRatio = (startRatio + endRatio) / 2;
        const startRadian = startRatio * Math.PI * 2;
        const endRadian = endRatio * Math.PI * 2;
        const midRadian = midRatio * Math.PI * 2;

        // 避免不必要的变量重新赋值
        const finalIsSelected = (startRatio === 0 && endRatio === 1) ? false : isSelected;

        // 调整饼图位置：增加基础偏移量使饼图向上移动，保持大小和倾斜度不变
        const baseOffsetX = 0; // 水平位置保持不变
        const baseOffsetY = 0; // 负值使饼图适度向上移动
        const offsetX = baseOffsetX + (finalIsSelected ? Math.cos(midRadian) * 0.1 : 0);
        const offsetY = baseOffsetY + (finalIsSelected ? Math.sin(midRadian) * 0.1 : 0);
        const hoverRate = isHovered ? 1 : 1;
        const scaleFactor = 1.2; // 保持原始大小

        // 简化x, y, z函数，避免重复计算
        const calculateX = (u, v) => {
          const baseValue = offsetX + (1 + Math.cos(v) * k) * hoverRate * scaleFactor;
          if (u < startRadian) return baseValue * Math.cos(startRadian);
          if (u > endRadian) return baseValue * Math.cos(endRadian);
          return baseValue * Math.cos(u);
        };

        const calculateY = (u, v) => {
          const baseValue = offsetY + (1 + Math.cos(v) * k) * hoverRate * scaleFactor;
          if (u < startRadian) return baseValue * Math.sin(startRadian);
          if (u > endRadian) return baseValue * Math.sin(endRadian);
          return baseValue * Math.sin(u);
        };


        const calculateZ = (u, v) => {
          if (u < -Math.PI * 0.5 || u > Math.PI * 2.5) return Math.sin(u) * (u > Math.PI * 2.5 ? h * 0.1 : 1);
          return Math.sin(v) > 0 ? h * 0.1 : -1;
        };

        return {
          u: { min: -Math.PI, max: Math.PI * 3, step: Math.PI / 32 },
          v: { min: 0, max: Math.PI * 2, step: Math.PI / 20 },
          x: calculateX,
          y: calculateY,
          z: calculateZ
        };
      };

      // 优化的3D饼图配置生成函数
      const getPie3D = (pieData, internalDiameterRatio = 0.8) => {
        // 避免空数据处理
        if (!pieData || pieData.length === 0) {
          return {
            series: [],
            graphic: {
              elements: [{
                type: 'image',
                ...this.pieImageConfig,
                style: {
                  ...this.pieImageStyle,
                  image: this.pieImageStyle.image || defaultPieImage,
                }
              }]
            }
          };
        }

        const series = [];
        const k = (1 - internalDiameterRatio) / (1 + internalDiameterRatio);

        // 预先计算总和，避免重复遍历
        const sumValue = pieData.reduce((sum, item) => sum + item.value, 0);

        let currentStartValue = 0;

        // 使用map代替for循环，避免中间变量
        pieData.forEach((dataItem, index) => {
          const endValue = currentStartValue + dataItem.value;

          const seriesItem = {
            name: dataItem.name || `series${index}`,
            type: 'surface',
            parametric: true,
            wireframe: { show: false },
            pieData: { ...dataItem }, // 深拷贝避免修改原始数据
            pieStatus: { selected: false, hovered: false, k },
            itemStyle: dataItem.itemStyle
          };
          let heightPie = this.sortOrder === 'desc' ? 10 + 5 * (pieData.length - 1 - index) : 10 + 5 * index
          if (this.pieHeight) heightPie = this.pieHeight
          // 计算比例并设置参数方程
          seriesItem.pieData.startRatio = currentStartValue / sumValue;
          seriesItem.pieData.endRatio = endValue / sumValue;
          seriesItem.parametricEquation = getParametricEquation(
            seriesItem.pieData.startRatio,
            seriesItem.pieData.endRatio,
            false,
            false,
            k,
            heightPie
          );

          series.push(seriesItem);
          currentStartValue = endValue;
        });

        // 缓存tooltip格式化函数，避免重复创建
        const tooltipFormatter = (params) => {
          if (params.seriesName === 'mouseoutSeries') return '';

          // 避免访问option.series导致的潜在循环引用
          const pieData = series[params.seriesIndex]?.pieData;
          if (!pieData) return params.seriesName;

          return `${params.seriesName}<br/>
            <span style="display:inline-block;margin-right:5px;border-radius:10px;
            width:10px;height:10px;background-color:${params.color};"></span>
            ${pieData.value}`;
        };

        return {
          tooltip: {
            backgroundColor: 'rgba(0, 32, 75, 0.9)',
            borderColor: '#008CFF',
            textStyle: { color: '#FFFFFF' },
            formatter: tooltipFormatter
          },
          xAxis3D: { min: -1, max: 1 },
          yAxis3D: { min: -1, max: 1 },
          zAxis3D: { min: -1, max: 1 },
          grid3D: {
            show: false,
            boxHeight: 12,
            top: "-14%",
            left: "-3%",
            viewControl: {
              alpha: 35,
              beta: 25,
              rotateSensitivity: 0,
              zoomSensitivity: 0,
              panSensitivity: 0,
              autoRotate: false,
              distance: 160
            },
            postEffect: {
              enable: false,
              bloom: { enable: true, bloomIntensity: 0.1 },
              SSAO: { enable: true, quality: 'medium', radius: 2 }
            }
          },
          graphic: {
            elements: [{
              type: 'image',
              ...this.pieImageConfig,
              style: {
                ...this.pieImageStyle,
                image: this.pieImageStyle.image || defaultPieImage,
              }
            }]
          },
          series
        };
      };
      // 安全处理饼图数据
      const safePieData = Array.isArray(this.pieData) ? [...this.pieData] : [];

      // 为数据项添加样式，避免修改原始数据
      const styledPieData = safePieData.map((item, index) => ({
        ...item,
        itemStyle: {
          ...item.itemStyle,
          color: item.color || item.itemStyle?.color
        }
      }));

      // 生成配置
      const option = getPie3D(styledPieData, 0.8);

      // 安全合并自定义图像配置
      if (this.customGraphic && typeof this.customGraphic === 'object') {
        option.graphic = { ...option.graphic, ...this.customGraphic };
      }

      return option;
    },
  },
}
</script>
<style>
.vue-echarts-3d-components-pie-inner.pie-charts-wrapper {
  width: 100%;
  height: 100%;
  /* 设置明确的高度 */
  position: relative;
}

.vue-echarts-3d-components-pie-inner .chart-container {
  width: 100%;
  height: 100%;
}
</style>