<script setup lang="ts">
import { onMounted, onUnmounted, ref, watch, nextTick } from "vue";
import * as echarts from "echarts";

// 定义组件接收的props
const props = defineProps({
  xData: {
    type: Array as PropType<Array<string>>,
    default: () => [],
  },
  legendArr: {
    type: Array as PropType<Array<string>>,
    default: () => [],
  },
  datas: {
    type: Array as PropType<Array<Array<number>>>,
    default: () => [],
  },
  colorArr: {
    type: Array as PropType<Array<Array<string>>>,
    default: () => [],
  },
});
const chartContainer = ref<HTMLDivElement | null>(null);
let chartInstance: echarts.ECharts | null = null;

// 自定义3D形状
const CubeLeft = echarts.graphic.extendShape({
  shape: { x: 0, y: 0 },
  buildPath: (ctx, shape) => {
    const { xAxisPoint } = shape;
    const [c0, c1, c2, c3] = [
      [shape.x, shape.y],
      [shape.x - 12, shape.y - 6],
      [xAxisPoint[0] - 12, xAxisPoint[1] - 6],
      [xAxisPoint[0], xAxisPoint[1]],
    ];
    ctx
      .moveTo(c0[0], c0[1])
      .lineTo(c1[0], c1[1])
      .lineTo(c2[0], c2[1])
      .lineTo(c3[0], c3[1])
      .closePath();
  },
});

const CubeRight = echarts.graphic.extendShape({
  shape: { x: 0, y: 0 },
  buildPath: (ctx, shape) => {
    const { xAxisPoint } = shape;
    const [c1, c2, c3, c4] = [
      [shape.x, shape.y],
      [xAxisPoint[0], xAxisPoint[1]],
      [xAxisPoint[0] + 12, xAxisPoint[1] - 6],
      [shape.x + 12, shape.y - 6],
    ];
    ctx
      .moveTo(c1[0], c1[1])
      .lineTo(c2[0], c2[1])
      .lineTo(c3[0], c3[1])
      .lineTo(c4[0], c4[1])
      .closePath();
  },
});

const CubeTop = echarts.graphic.extendShape({
  shape: { x: 0, y: 0 },
  buildPath: (ctx, shape) => {
    const [c1, c2, c3, c4] = [
      [shape.x, shape.y],
      [shape.x + 12, shape.y - 6],
      [shape.x, shape.y - 12],
      [shape.x - 12, shape.y - 6],
    ];
    ctx
      .moveTo(c1[0], c1[1])
      .lineTo(c2[0], c2[1])
      .lineTo(c3[0], c3[1])
      .lineTo(c4[0], c4[1])
      .closePath();
  },
});
// 注册三个面图形
echarts.graphic.registerShape("CubeLeft", CubeLeft);
echarts.graphic.registerShape("CubeRight", CubeRight);
echarts.graphic.registerShape("CubeTop", CubeTop);

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

  chartInstance = echarts.init(chartContainer.value);
  setTimeout(() => {
    chartInstance?.resize();
    updateChart();
  }, 500);
};

// 更新图表配置
const updateChart = () => {
  if (!chartInstance) return;
  const series = props.datas
    .map((item, index) => [
      {
        type: "custom",
        name: props.legendArr[index],
        renderItem: (params, api) => ({
          type: "group",
          x: (index - props.datas.length / 2) * 30 + 15,
          children: [
            {
              type: "CubeLeft",
              shape: {
                api,
                xValue: api.value(0),
                yValue: api.value(1),
                x: api.coord([api.value(0), api.value(1)])[0],
                y: api.coord([api.value(0), api.value(1)])[1],
                xAxisPoint: api.coord([api.value(0), 0]),
              },
              style: {
                fill: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                  {
                    offset: 0,
                    color: props.colorArr[index % props.colorArr.length][1],
                  },
                  {
                    offset: 1,
                    color: props.colorArr[index % props.colorArr.length][0],
                  },
                ]),
              },
            },
            {
              type: "CubeRight",
              shape: {
                api,
                xValue: api.value(0),
                yValue: api.value(1),
                x: api.coord([api.value(0), api.value(1)])[0],
                y: api.coord([api.value(0), api.value(1)])[1],
                xAxisPoint: api.coord([api.value(0), 0]),
              },
              style: {
                fill: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                  {
                    offset: 0,
                    color: props.colorArr[index % props.colorArr.length][1],
                  },
                  {
                    offset: 1,
                    color: props.colorArr[index % props.colorArr.length][0],
                  },
                ]),
              },
            },
            {
              type: "CubeTop",
              shape: {
                api,
                xValue: api.value(0),
                yValue: api.value(1),
                x: api.coord([api.value(0), api.value(1)])[0],
                y: api.coord([api.value(0), api.value(1)])[1],
                xAxisPoint: api.coord([api.value(0), 0]),
              },
              style: {
                fill: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                  {
                    offset: 0,
                    color: props.colorArr[index % props.colorArr.length][1],
                  },
                  {
                    offset: 1,
                    color: props.colorArr[index % props.colorArr.length][1],
                  },
                ]),
              },
            },
          ],
        }),
        data: item,
      },
      {
        type: "bar",
        name: props.legendArr[index],
        barWidth: 25,
        // label: {
        //   normal: {
        //     show: true,
        //     position: "top",
        //     fontSize: 16,
        //     color: "#fff",
        //     offset: [0, -10],
        //   },
        // },
        itemStyle: { color: "transparent" },
        data: item,
        yAxisIndex: 0, // 使用左y轴
      },
      {
        type: "bar",
        name: props.legendArr[index],
        barWidth: 25,
        itemStyle: { color: "transparent" },
        data: item,
        yAxisIndex: 1, // 使用左y轴
      },
    ])
    .flat();

  chartInstance.setOption({
    tooltip: {
      trigger: "axis",
      borderWidth: 0,
      backgroundColor: "rgba(8,36,68,.9)",
      color: "#fff",
      textStyle: { color: "#fff" },
      formatter: (params) => {
        let str = params[0].name + "</br>";
        params.forEach((item, index) => {
          if (item.seriesType === "custom") {
            str += `
                <div style='display:flex;justify-content:space-between;align-items:center'>
                  <div style='margin-right:20px;'>
                    <span style="display:inline-block;width:10px;height:10px;border-radius:5px;background-color:${
                      props.colorArr[index % props.colorArr.length][0]
                    }"></span>
                    &nbsp;${item.seriesName}
                  </div>
                  <span>&nbsp;${item.value ? item.value : "-"}</span>
                </div>`;
          }
        });
        return str;
      },
    },
    grid: {
      left: "5%",
      right: "5%",
      top: "5%",
      bottom: "10%",
      containLabel: true,
    },
    legend: {
      left: "center",
      top: "90%",
      itemWidth: 12, // 图例项宽度
      itemHeight: 8,
      textStyle: { color: "#fff", fontSize: 12 },
      data: props.legendArr.map((name, index) => ({
        name,
        textStyle: { color: "#fff", fontSize: 12 },
        itemStyle: { color: props.colorArr[index % props.colorArr.length][1] },
      })),
    },
    xAxis: {
      type: "category",
      data: props.xData,
      axisLine: { lineStyle: { color: "rgba(239, 247, 253, .1)" } },
      axisLabel: { fontSize: 12, color: "#fff", margin: 12 },
    },
    yAxis: [
      {
        // name: "kWh",
        // nameTextStyle: { color: "#fff", fontSize: 12 },
        splitLine: {
          lineStyle: { type: "dashed", color: "rgba(80,112,242,0.3)" },
        },
        axisLabel: { textStyle: { color: "#8C8C8C" }, fontSize: 12 },
        // axisLine: { lineStyle: { color: "#8C8C8C" } },
        // scale: true, // 同步刻度
      },
      {
        // name: "kWh",
        // nameTextStyle: { color: "#fff", fontSize: 12 },
        splitLine: { lineStyle: { color: "transparent" } },
        axisLabel: { textStyle: { color: "#8C8C8C" }, fontSize: 12 },
        // axisLine: { lineStyle: { color: "#8C8C8C" } },
        position: "right",
        // scale: true, // 同步刻度
      },
    ],
    series,
  });
};
const handleResize = () => {
  chartInstance?.resize();
};
// 生命周期管理
onMounted(async () => {
  await nextTick();
  initChart();
});

onUnmounted(() => {
  if (chartInstance) {
    chartInstance.dispose();
    chartInstance = null;
    chartInstance?.resize();
  }
});

// 响应式更新
watch(
  () => props,
  async () => {
    await nextTick();
    updateChart();
    // delay(600).then(() => resize());
  },
  {
    deep: true,
    immediate: true,
  }
);
</script>
<template>
  <div ref="chartContainer" style="width: 100%; height: 100%" />
</template>
