<template>
  <div class="flex flex-col">
    <div class="relative flex-1">
      <div class="particle-base"></div>
      <div ref="chartRef" class="w-full h-full"></div>
      <div
        class="absolute left-50% top-50% transform-translate-x-[-50%] transform-translate-y-[-50%]  flex items-baseline">
        <span class="text-[24px] font-700 text-color" :data-text="total">{{ total }}</span>
        <span class="text-[16px] font-700 text-color" data-text="人">人</span>
      </div>
      
    </div>
  </div>
</template>

<script lang="ts" setup>
  import * as echarts from "echarts/core";
  import { TooltipComponent } from "echarts/components";
  import { CanvasRenderer } from "echarts/renderers";
  import { SurfaceChart } from "echarts-gl/charts";
  import { Grid3DComponent } from "echarts-gl/components";
  import { ref, onMounted, watch, onBeforeUnmount } from "vue";

  echarts.use([TooltipComponent, Grid3DComponent, SurfaceChart, CanvasRenderer]);

  type DefaultProps = {
    chartData: any;
    ringSize: number;
  };

  const props = withDefaults(defineProps<DefaultProps>(), {
    chartData: [
      { name: "线下", value: 0, itemStyle: { color: "rgba(147, 219, 255, 1)" } },
      { name: "线上", value: 0, itemStyle: { color: "rgb(79, 214, 169)" } },
    ],
    ringSize: 1,
  });

  const chartRef = ref<HTMLElement | null>(null);
  let chartInstance: echarts.ECharts | null = null;

  interface SeriesItem {
    [key: string]: any;
  }

  // 获取3D饼图的最高扇区的高度
  const getHeight3D = (series: any[], height: number) => {
    series.sort((a, b) => {
      return b.pieData.value - a.pieData.value;
    });
    return (height * 35) / series[0].pieData.value;
  };

  // 生成扇形的曲面参数方程
  const getParametricEquation = (startRatio: number, endRatio: number, isSelected: boolean, isHovered: boolean, k: number, h: number) => {
    const midRatio = (startRatio + endRatio) / 2;
    const startRadian = startRatio * Math.PI * 2;
    const endRadian = endRatio * Math.PI * 2;
    const midRadian = midRatio * Math.PI * 2;

    if (startRatio === 0 && endRatio === 1) {
      isSelected = false;
    }

    k = typeof k !== "undefined" ? k : 1 / 3;
    const offsetX = isSelected ? Math.cos(midRadian) * 0.1 : 0;
    const offsetY = isSelected ? Math.sin(midRadian) * 0.1 : 0;
    const hoverRate = isHovered ? 1.05 : 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: (u: number, v: number) => {
        if (u < startRadian) {
          return offsetX + Math.cos(startRadian) * (1 + Math.cos(v) * k) * hoverRate;
        }
        if (u > endRadian) {
          return offsetX + Math.cos(endRadian) * (1 + Math.cos(v) * k) * hoverRate;
        }
        return offsetX + Math.cos(u) * (1 + Math.cos(v) * k) * hoverRate;
      },
      y: (u: number, v: number) => {
        if (u < startRadian) {
          return offsetY + Math.sin(startRadian) * (1 + Math.cos(v) * k) * hoverRate;
        }
        if (u > endRadian) {
          return offsetY + Math.sin(endRadian) * (1 + Math.cos(v) * k) * hoverRate;
        }
        return offsetY + Math.sin(u) * (1 + Math.cos(v) * k) * hoverRate;
      },
      z: (u: number, v: number) => {
        if (u < -Math.PI * 0.5) {
          return Math.sin(u);
        }
        if (u > Math.PI * 2.5) {
          return Math.sin(u) * h * 0.1;
        }
        return Math.sin(v) > 0 ? 1 * h * 0.1 : -1;
      },
    };
  };

  // 构建3D饼图配置
  const getPie3D = (pieData: any[], internalDiameterRatio: number): any => {
    const series: SeriesItem[] = [];
    let sumValue = 0;
    let startValue = 0;
    let endValue = 0;
    const legendData: any[] = [];
    const k = 1 - internalDiameterRatio;

    pieData.sort((a, b) => b.value - a.value);

    // 为每个饼图数据生成series-surface配置
    for (let i = 0; i < pieData.length; i++) {
      sumValue += pieData[i].value;
      const seriesItem: SeriesItem = {
        name: pieData[i].name || `series${i}`,
        type: "surface",
        parametric: true,
        wireframe: {
          show: false,
        },
        pieData: pieData[i],
        pieStatus: {
          selected: false,
          hovered: false,
          k: k,
        },
        animation: false,
      };

      if (pieData[i].itemStyle) {
        seriesItem.itemStyle = {
          color: pieData[i].itemStyle.color,
          opacity: 0.6,
        };
      }
      series.push(seriesItem);
    }

    // 计算每个扇形的参数方程
    for (let i = 0; i < series.length; i++) {
      endValue = startValue + series[i].pieData.value;
      series[i].pieData.startRatio = startValue / sumValue;
      series[i].pieData.endRatio = endValue / sumValue;
      series[i].parametricEquation = getParametricEquation(series[i].pieData.startRatio, series[i].pieData.endRatio, false, false, k, series[i].pieData.value);
      startValue = endValue;
      legendData.push(series[i].name);
    }

    const boxHeight = getHeight3D(series, 26);

    return {
      tooltip: {
        triggerOn:"mousemove|click",
        formatter: (params: any) => {
          if (params.seriesName !== "mouseoutSeries" && params.seriesName !== "pie2d") {
            const bfb = ((series[params.seriesIndex].pieData.endRatio - series[params.seriesIndex].pieData.startRatio) * 100).toFixed(2);
            return `${params.seriesName}<br/>${bfb}%`;
          }
        },
      },
      xAxis3D: {
        min: -1,
        max: 1,
      },
      yAxis3D: {
        min: -1,
        max: 1,
      },
      zAxis3D: {
        min: -4,
        max: 4,
      },
      grid3D: {
        show: false,
        boxHeight: boxHeight,
        viewControl: {
          alpha: 30,
          distance: 160,
          rotateSensitivity: 1,
          zoomSensitivity: 1,
          panSensitivity: 1,
          autoRotate: false,
        },
      },
      series: [
        ...series,
        {
          name: "pie2d",
          type: "pie",
          labelLine: {
            length: 18,
            length2: 18,
            smooth: true,
            minTurnAngle: 20,
          },
          label: {
            show: true,
            position: "outside",
            color: "inherit",
            rich: {
              a: {
                width: 5,
                height: 5,
                borderRadius: 50,
                backgroundColor: "inherit",
              },
              b: {
                fontSize: 12,
              },
              c: {
                fontSize: 12,
              },
            },
            formatter: "{a|} {b|{b}}{d|{d}}%",
          },
          startAngle: 30,
          clockwise: false,
          radius: ["30%", "60%"],
          padAngle: 360,
          center: ["50%", "50%"],
          data: props.chartData,
          itemStyle: {
            opacity: 1,
            borderWidth: 0,
          },
          // z: 0,
        },
      ],
      // graphic: [
      //   // {
      //   //   id: "backgroundImg",
      //   //   elements: [
      //   //     {
      //   //       type: "image",
      //   //       left: "center",
      //   //       top: "33%",
      //   //       style: {
      //   //         image: "/images/particleBase.png",
      //   //         width: 254,
      //   //         height: 106,
      //   //       },
      //   //       z: 0,
      //   //       cursor: "point",
      //   //       origin: [127, 53],
      //   //       // keyframeAnimation: [
      //   //       //   {
      //   //       //     duration: 1600,
      //   //       //     loop: true,
      //   //       //     keyframes: [
      //   //       //       {
      //   //       //         percent: 0,
      //   //       //         scaleX: 1.1,
      //   //       //         scaleY: 1.1,
      //   //       //       },
      //   //       //       {
      //   //       //         percent: 0.3,
      //   //       //         scaleX: 1,
      //   //       //         scaleY: 1,
      //   //       //       },
      //   //       //       {
      //   //       //         percent: 1,
      //   //       //         scaleX: 1.1,
      //   //       //         scaleY: 1.1,
      //   //       //       },
      //   //       //     ],
      //   //       //   },
      //   //       // ],
      //   //     },
      //   //   ],
      //   // },
      // ],
    };
  };

  // 初始化图表
  const initChart = () => {
    if (!chartRef.value) return;
    chartInstance = echarts.init(chartRef.value);
    updateChart();
  };

  const updateChart = () => {
    if (!chartInstance) return;
    const option = getPie3D(props.chartData, props.ringSize);
    chartInstance.setOption(option, true);
  };

  const total = computed(() => props.chartData.reduce((sum: number, item: any) => sum + item.value, 0));

  // 监听数据变化
  watch(
    () => props.chartData,
    () => {
      if (chartInstance) {
        updateChart();
      }
    },
    { deep: true },
  );

  // 组件挂载时初始化
  onMounted(() => {
    if (!chartInstance) {
      initChart();
    }
    window.addEventListener("resize", handleResize);
  });

  onBeforeUnmount(() => {
    if (chartInstance) {
      chartInstance.dispose();
      chartInstance = null;
    }
    window.removeEventListener("resize", handleResize);
  });

  const handleResize = () => {
    chartInstance?.resize();
  };
</script>

<style scoped lang="scss">
@use "@/styles/text-color.scss";

.particle-base {
  position: absolute;
  left: 50%;
  top: 60%;
  transform: translate(-50%, -50%);
  width: 254px;
  height: 106px;
  background-image: url('/images/particleBase.png');
  background-size: contain;
  background-repeat: no-repeat;
  animation: scaleAnimation 1.6s infinite;
  will-change: transform;
}

@keyframes scaleAnimation {
  0% {
    transform: translate(-50%, -50%) scale(1.1);
  }
  30% {
    transform: translate(-50%, -50%) scale(1);
  }
  100% {
    transform: translate(-50%, -50%) scale(1.1);
  }
}
</style>
