import React from "react";
import * as echarts from "echarts";
import "echarts-gl";

class Pie3DChart extends React.Component {
  constructor(props) {
    super(props);
    this.chartRef = React.createRef();
    this.chartInstance = null;
  }

  componentDidMount() {
    this.initChart();
    window.addEventListener("resize", this.resizeChart);
  }

  componentWillUnmount() {
    if (this.chartInstance) {
      this.chartInstance.dispose();
    }
    window.removeEventListener("resize", this.resizeChart);
  }

  resizeChart = () => {
    if (this.chartInstance) {
      this.chartInstance.resize();
    }
  };

  // 生成 Pie3D 的数据
  getPie3D(seriesData, internalDiameterRatio) {
    const series = [];
    let sumValue = 0;
    let startValue = 0;
    let endValue = 0;
    const k = (1 - internalDiameterRatio) / (1 + internalDiameterRatio);

    seriesData.forEach((d) => {
      sumValue += d.value;
    });

    for (let i = 0; i < seriesData.length; i++) {
      startValue = endValue;
      endValue = startValue + seriesData[i].value;

      series.push({
        name: seriesData[i].name,
        type: "surface",
        parametric: true,
        wireframe: { show: false },
        shading: "lambert",
        itemStyle: {
          color: seriesData[i].itemStyle.color,
        },
        parametricEquation: this.getParametricEquation(
          startValue / sumValue,
          endValue / sumValue,
          false,
          false,
          k,
          seriesData[i].value
        ),
      });
    }
    return series;
  }

  // 生成参数方程
  getParametricEquation(startRatio, endRatio, isSelected, isHovered, k, h) {
    const midRatio = (startRatio + endRatio) / 2;
    const startRadian = startRatio * Math.PI * 2;
    const endRadian = endRatio * Math.PI * 2;
    const midRadian = midRatio * Math.PI * 2;

    const offsetX = isSelected ? Math.cos(midRadian) * 0.1 : 0;
    const offsetY = isSelected ? Math.sin(midRadian) * 0.1 : 0;

    return {
      u: { min: -Math.PI, max: Math.PI * 3, step: Math.PI / 32 },
      v: { min: 0, max: Math.PI, step: Math.PI / 20 },
      x(u, v) {
        if (u < startRadian) return offsetX;
        if (u > endRadian) return offsetX;
        return Math.cos(u) * (1 + Math.cos(v) * k) + offsetX;
      },
      y(u, v) {
        if (u < startRadian) return offsetY;
        if (u > endRadian) return offsetY;
        return Math.sin(u) * (1 + Math.cos(v) * k) + offsetY;
      },
      z(u, v) {
        if (u < startRadian) return 0;
        if (u > endRadian) return 0;
        return Math.sin(v) > 0 ? h * 0.1 : -h * 0.1;
      },
    };
  }

  initChart() {
    if (!this.chartRef.current) return;
    this.chartInstance = echarts.init(this.chartRef.current);

    const seriesData = [
      { name: "A", value: 40, itemStyle: { color: "#5470C6" } },
      { name: "B", value: 25, itemStyle: { color: "#91CC75" } },
      { name: "C", value: 20, itemStyle: { color: "#EE6666" } },
      { name: "D", value: 15, itemStyle: { color: "#FAC858" } },
    ];

    const option = {
      tooltip: {
        formatter: (params) => {
          return `${params.seriesName}: ${params.series.value}`;
        },
      },
      xAxis3D: { min: -1, max: 1 },
      yAxis3D: { min: -1, max: 1 },
      zAxis3D: { min: -1, max: 1 },
      grid3D: {
        show: false,
        boxHeight: 20,
        viewControl: { distance: 200 },
        light: {
          main: { intensity: 1.2, shadow: true },
          ambient: { intensity: 0.3 },
        },
      },
      series: this.getPie3D(seriesData, 0.6),
    };

    this.chartInstance.setOption(option);
  }

  render() {
    return (
      <div ref={this.chartRef} style={{ width: "100%", height: "500px" }} />
    );
  }
}

export default Pie3DChart;
