<template>
  <div>
    <div id="mainChart"></div>
    <div
      v-for="(engine, index) in data.data"
      :key="'chart-' + index"
      :id="'chart-' + index"
    ></div>
  </div>
</template>

<script>
import Plotly from "plotly.js-dist";
import {
  creatNewChartsJson,
  downLoadChartsJsonFile,
  _debounce,
} from "@/utils/common";
export default {
  name: "PlotlyChart",
  data() {
    return {
      data: {
        analysisTypeCode: "power_curve",
        graphType: "scatter",
        data: [
          {
            engineName: "#1",
            windSpeed: [
              "3",
              "4",
              "5",
              "6",
              "7",
              "8",
              "9",
              "10",
              "11",
              "12",
              "13",
              "14",
              "15",
              "16",
              "17",
              "18",
              " 19",
              "20",
              "27",
              "30",
            ],
            power: [
              "6.06",
              "76.54",
              "184.1",
              "345.94",
              "574.4",
              "879.9",
              "1274.73",
              "1664.94",
              "1942.96",
              "2004.78",
              "2004.78",
              "2004.78",
              "2004.78",
              "2004.78",
              "2004.78",
              "2004.78",
              "2004.78",
              "2004.78",
              "2230",
            ],
          },
          {
            engineName: "#2",
            windSpeed: [
              2, 2.5, 3, 3.5, 4, 4.5, 5, 5.5, 6, 6.5, 7, 7.5, 8, 8.5, 9, 9.5,
              10, 10.5, 11, 11.5, 12, 12.5, 13, 13.5, 14, 14.5, 15, 15.5, 16,
              16.5, 33,
            ],
            power: [
              2, 9.23, 100.12, 155.51, 230.09, 400.15, 500.95, 689.55, 961.09,
              1257.53, 1346.02, 1479.78, 1528.01, 1618.52, 1789.09, 1819.35,
              1920.29, 2053.52, 2053.52, 2053.52, 2053.52, 2053.52, 2053.52,
              2053.52, 2053.52, 2053.52, 2053.52, 2053.52, 2053.52, 2053.52,
              2153.52, 2159,
            ],
          },
          {
            engineName: "#3",
            windSpeed: [
              2.7, 3.7, 4.7, 5.7, 6.7, 7.7, 8.7, 9.7, 10.7, 11.5, 12, 13.5, 14,
              15.5, 16, 17.5, 18, 19.5, 21, 21.5, 22, 22.5, 23, 23.5, 24, 27.5,
              28, 29.5, 30, 36.5,
            ],
            power: [
              2, 9.23, 100.12, 155.51, 230.09, 400.15, 500.95, 689.55, 961.09,
              1257.53, 1346.02, 1479.78, 1528.01, 1618.52, 1789.09, 1819.35,
              1920.29, 2053.52, 2053.52, 2053.52, 2053.52, 2053.52, 2053.52,
              2053.52, 2053.52, 2053.52, 2053.52, 2053.52, 2053.52, 2053.52,
            ],
          },
        ],
      },
      selectJson: {},
      selectedPoints: [],
      modeBarButtons: [
        // // 撤销按钮
        // {
        //   name: "撤销圈选",
        //   icon: Plotly.Icons.undo,
        //   click: (gd) => {
        //     this.deleteLastShapeAndPoints(gd);
        //   },
        // },
        // // 自定义工具按钮配置
        // {
        //   name: "套索选择",
        //   icon: Plotly.Icons.lasso,
        //   click: (gd) => {
        //     // 处理套索选择功能
        //     Plotly.relayout(gd, { dragmode: "lasso" });
        //     // 创建一个用于保存所有选择点的数组
        //     let allSelectedPoints = [];
        //     // 监听 plotly_selected 事件
        //     gd.on("plotly_selected", (eventData) => {
        //       if (eventData && eventData.points) {
        //         // 将每次选择的点累加到 allSelectedPoints 中
        //         allSelectedPoints = allSelectedPoints.concat(eventData.points);
        //         // 显示累加后的所有选中点
        //         this.debouncedGetSelectData(allSelectedPoints, gd.layout);
        //         // this.getSelectData(allSelectedPoints, gd.layout);
        //       }
        //     });
        //   },
        // },
        // // 其他工具按钮配置
        // {
        //   name: "下载标记数据",
        //   icon: Plotly.Icons.disk,
        //   click: (gd) => {
        //     this.downLoadSelectJson();
        //   },
        // },
      ],
      imageDataUri: [],
      currentEngineIndex: 0,
      actionHistory: [],
      lastLasso: null,
      undoStack: [], // 初始化为一个空数组
      allSelectedPoints: [], // 所有选择的点
      lastTraceIndex: null, // 上一次添加的 trace 索引
      lastSelectedPoints: [], // 上一次选择的点
    };
  },
  mounted() {
    this.initializeMainChart();
    this.initializeEngineCharts();
    // 初始化防抖函数
    this.debouncedGetSelectData = _debounce(this.getSelectData, 500);
  },
  methods: {
    initializeMainChart() {
      const layout = {
        title: "功率曲线图",
        xaxis: { title: "Wind Speed (m/s)" },
        yaxis: { title: "Power (kW)" },
        // 布局配置
        shapes: this.lassoShapes, // 初始化时加载已保存的套索
        legend: {
          orientation: "h",
          y: -0.2,
          x: 0.5,
          xanchor: "center",
        },
        shapes: [],
        _undoStack: [],
        editable: true,
      };
      const plotlyData = this.data.data.map((engine) => ({
        x: engine.windSpeed,
        y: engine.power,
        mode: "lines+markers",
        name: engine.engineName,
      }));
      const config = {
        modeBarButtonsToAdd: this.modeBarButtons,
        modeBarButtonsToRemove: [
          // 移除不需要的工具按钮
          "lasso2d",
        ],
        displaylogo: false,
        editable: true,
        scrollZoom: true,
      };
      Plotly.newPlot("mainChart", plotlyData, layout, config).then((gd) => {
        // 初始化 _undoStack
        if (!gd._fullLayout._undoStack) {
          gd._fullLayout._undoStack = [];
        }
        Plotly.toImage(gd, { format: "png" }).then((dataUrl) => {
          this.imageDataUri.push(dataUrl);
        });
      });
    },
    //初始化分图
    initializeEngineCharts() {
      this.data.data.forEach((engine, index) => {
        const layout = {
          title: engine.engineName + "风机",
          xaxis: { title: "风速 (m/s)" },
          yaxis: { title: "功率 (kW)" },
          legend: {
            orientation: "h",
            y: -0.2,
            x: 0.5,
            xanchor: "center",
          },
          annotations: [
            {
              x: 5, // 示例坐标
              y: 500,
              xref: "x",
              yref: "y",
              text: "示例注释",
              showarrow: true,
              arrowhead: 2,
              ax: -50,
              ay: -50,
              font: {
                size: 12,
                color: "black",
              },
              bgcolor: "white",
              bordercolor: "black",
            },
          ],
          shapes: [],
          _undoStack: [], // 用于存储撤回操作的栈
          editable: true,
        };
        const plotlyData = this.data.data.map((eng, i) => ({
          x: eng.windSpeed,
          y: eng.power,
          mode: "lines+markers",
          name: eng.engineName,
          line: {
            color: index === i ? "#1c77b3" : "#c1c1c1",
          },
        }));
        const config = {
          modeBarButtonsToAdd: this.modeBarButtons,
          modeBarButtonsToRemove: [
            // "selectbox",
            "lasso",
            // "zoombox",
            // "pan",
            // "autoscale",
            // "zoom2d",
            // "pan2d",
            // "select2d",
          ],
          displaylogo: false,
          scrollZoom: true,
          editable: true,
        };
        Plotly.newPlot(`chart-${index}`, plotlyData, layout, config).then(
          (gd) => {
            // 初始化 _undoStack
            if (!gd._fullLayout._undoStack) {
              gd._fullLayout._undoStack = [];
            }
            gd.on("plotly_relayout", (eventData) => {
              if (eventData.shapes) {
                gd._fullLayout._undoStack.push({
                  undo: gd.layout.shapes.slice(),
                });
              }
            });
            // 生成图片方法
            Plotly.toImage(gd, { format: "png" }).then((dataUrl) => {
              this.imageDataUri.push(dataUrl);
            });
          }
        );
      });
    },
    deleteLastShapeAndPoints(gd) {
      if (this.undoStack.length > 0) {
        const lastAction = this.undoStack.pop();
        // 删除上一次添加的 trace
        if (lastAction.traceIndex !== undefined) {
          Plotly.deleteTraces(gd, lastAction.traceIndex);
        }
        // 从 allSelectedPoints 中删除上一次添加的点
        this.allSelectedPoints = this.allSelectedPoints.filter(
          (point) =>
            !lastAction.points.some((p) => p.x === point.x && p.y === point.y)
        );
        // 删除上一次的 shape（即套索）
        if (lastAction.shape) {
          const newShapes = gd.layout.shapes.filter(
            (shape) => shape !== lastAction.shape
          );
          Plotly.relayout(gd, { shapes: newShapes });
        }
        // 删除 selectionlayer 和 zoomlayer 的子元素
        const selectionLayer = document.querySelector(".selectionlayer");
        const zoomLayer = document.querySelector(".zoomlayer");
        if (selectionLayer) {
          while (selectionLayer.firstChild) {
            selectionLayer.removeChild(selectionLayer.firstChild); // 清空 selectionlayer 的子元素
          }
        }
        if (zoomLayer) {
          while (zoomLayer.firstChild) {
            zoomLayer.removeChild(zoomLayer.firstChild); // 清空 zoomlayer 的子元素
          }
        }

        // 恢复为 pan 平移工具
        Plotly.relayout(gd, { dragmode: "pan" });
      }
      // 清除所有选择点
      this.allSelectedPoints = [];
      this.selectJson = {};
    },
    getSelectData(selectedPoints, fullLayout) {
      const { newPlotlyData, layout } = creatNewChartsJson(
        selectedPoints,
        fullLayout
      );

      this.selectJson = {
        data: newPlotlyData,
        layout: layout,
      };

      const update = {
        x: selectedPoints.map((p) => p.x),
        y: selectedPoints.map((p) => p.y),
        mode: "markers",
        marker: { color: "red", size: 10 },
        showlegend: false,
      };

      Plotly.addTraces("mainChart", update).then((gd) => {
        const traceIndex = gd.data.length - 1;
        this.lastSelectedPoints = [...selectedPoints];
        this.allSelectedPoints = [...this.allSelectedPoints, ...selectedPoints];

        // 获取当前 shapes
        const currentShape = gd.layout.shapes
          ? gd.layout.shapes[gd.layout.shapes.length - 1]
          : null;

        // 将添加的 trace 索引、选择点、和 shape 压入栈中
        this.undoStack.push({
          traceIndex,
          points: [...selectedPoints],
          shape: currentShape, // 记录当前的 shape
        });
      });
    },
    downLoadSelectJson() {
      // 处理选中的点数据
      // 根据name对选中的点进行分组
      if (this.selectJson.data && this.selectJson.data.length > 0) {
        downLoadChartsJsonFile(this.selectJson);
      } else {
        this.$message({
          message: "请圈选数据后进行下载操作",
          type: "warning",
        });
      }
    },
  },
  beforeDestroy() {
    // 清理 Plotly 监听器
    const gd = document.getElementById("mainChart");
    if (gd) {
      Plotly.purge(gd);
    }
  },
};
</script>

<style scoped>
/* 样式可选 */
</style>
