<template>
  <div v-loading="loading">
    <!-- ECharts 图表容器 -->
    <div class="line-chart" ref="chart"></div>
    <div class="control-panel">
      <!-- 光标 -->
      <div class="panel-block">
        <span class="label">光标</span>
        <div class="btn-group">
          <span
            v-for="item in GBcheckList"
            :key="item.val"
            :class="['btn', checkedGB.includes(item.val) ? 'active' : '']"
            @click="selectCursor(item.val)"
          >
            {{ item.val }}
          </span>
        </div>
      </div>
      <!-- 特征值（多选） -->
      <div class="panel-block full-width">
        <span class="label">特征 </span>
        <el-cascader
          v-model="selectedFeatures"
          :options="cascaderOptions"
          :props="cascaderProps"
          collapse-tags
          clearable
          placeholder="请选择特征"
          size="small"
          @change="handleCascaderChange"
        />
      </div>
    </div>
  </div>
</template>

<script>
import axios from "axios";
import * as echarts from "echarts"; // 导入 echarts 库
import cursorReferenceMixin from "./spectrogramcharts/cursorReferenceMixin";
import Bdgb from "./spectrogramcharts/Bdgb";
import Xdgb from "./spectrogramcharts/Xdgb";
import Tjgb from "./spectrogramcharts/Tjgb";
export default {
  name: "TimedomainCharts", // 组件名称
  mixins: [cursorReferenceMixin, Bdgb, Xdgb, Tjgb],
  props: {
    currentIndex: {
      type: Number,
      default: 0,
    },
    activeIndex: {
      type: Number,
      default: 0,
    },
    loading: {
      type: Boolean,
      default: false,
    },
    ids: {
      type: Array,
      default: () => [],
    },
    timeListTwo: {
      type: Object,
      default: () => ({}),
    },
    currentRow: {
      type: Object,
      default: () => ({}),
    },
    windCode: {
      type: String,
      default: "",
    },
  },
  data() {
    return {
      chartInstance: null,
      option: null,
      TZshow: false,
      timeList: {},
      manualMarks: [],
      // 时域：多单指针
      singlePointerPoints: [],
      activeSinglePointer: null,
      // 时域：边带
      sidebandCursorVisible: false,
      sidebandCursorPoints: [],
      // 光标
      GBcheckList: [
        { val: "单指针" },
        // { val: "谐波光标" },
        // { val: "边带光标" },
      ],
      checkedGB: [],
      featureGroups: [
        {
          label: "时域特征",
          type: "time",
          children: [
            { key: "Xrms", label: "有效值" },
            { key: "mean_value", label: "平均值" },
            { key: "max_value", label: "最大值" },
            { key: "min_value", label: "最小值" },
            { key: "Xp", label: "峰值" },
            { key: "Xpp", label: "峰峰值" },
          ],
        },
      ],
      selectedFeatures: [],
      cascaderProps: {
        // multiple: true, // 多选
        // checkStrictly: false, // 不能选父节点（只选叶子）
        // emitPath: true, // 返回路径（重要）
        multiple: true,
        checkStrictly: false,
        emitPath: true, // 保留（你需要路径）
        value: "value",
        label: "label",
      },
      // 特征值按钮
      TZFeatureList: [
        { key: "Xrms", label: "有效值" },
        { key: "mean_value", label: "平均值" },
        { key: "max_value", label: "最大值" },
        { key: "min_value", label: "最小值" },
        { key: "Xp", label: "峰值" },
        { key: "Xpp", label: "峰峰值" },
      ],
      activeFeatures: [],
    };
  },
  computed: {
    cascaderOptions() {
      return this.featureGroups.map((group) => ({
        label: group.label,
        value: group.type, // ✅ 改这里
        children: group.children.map((item) => ({
          label: item.label,
          value: item.key,
        })),
      }));
    },
  },
  watch: {
    // 监听 chartData 和 chartLabels 的变化，重新绘制图表
    chartData(newData) {
      this.updateChart(newData, this.chartLabels);
    },
    chartLabels(newLabels) {
      this.updateChart(this.chartData, newLabels);
    },
    timeListTwo(newValue) {
      this.timeList = newValue; // 将 timeListTwo 的新值赋给 timeList
      if (this.chartInstance) {
        this.updateChart(this.timeList.y, this.timeList.x); // 更新图表
      }
    },
    // 监听 timeList 的变化
    timeList: {
      handler(newValue) {
        if (this.chartInstance) {
          this.updateChart(newValue.y, newValue.x); // 只在 chartInstance 初始化后更新图表
        }
      },
      deep: true, // 深度监听
    },
  },
  mounted() {
    this.$nextTick(() => {
      this.initializeChart();
    });
  },
  beforeDestroy() {
    if (this.chartInstance) {
      this.chartInstance.getZr().off("click", this.handleSinglePointerClick);
      this.chartInstance.getZr().off("click", this.handleSidebandCursorClick);
      this.chartInstance.dispose();
      this.chartInstance = null;
    }
  },
  methods: {
    getChartXYData() {
      return {
        x: this.timeList?.x || [],
        y: this.timeList?.y || [],
      };
    },
    findClosestIndex(target, xData) {
      if (!Array.isArray(xData) || !xData.length) return -1;
      let closestIndex = 0;
      let minDiff = Math.abs(Number(xData[0]) - target);
      for (let i = 1; i < xData.length; i++) {
        const diff = Math.abs(Number(xData[i]) - target);
        if (diff < minDiff) {
          minDiff = diff;
          closestIndex = i;
        }
      }
      return closestIndex;
    },
    bindSinglePointerClick() {
      if (!this.chartInstance) return;
      this.chartInstance.getZr().off("click", this.handleSinglePointerClick);
      this.chartInstance.getZr().on("click", this.handleSinglePointerClick);
    },
    unbindSinglePointerClick() {
      if (!this.chartInstance) return;
      this.chartInstance.getZr().off("click", this.handleSinglePointerClick);
    },
    enableSinglePointer() {
      this.bindSinglePointerClick();
    },
    disableSinglePointer() {
      this.unbindSinglePointerClick();
      this.singlePointerPoints = [];
      this.activeSinglePointer = null;
      this.removeSinglePointerSeries();
    },
    handleSinglePointerClick(event) {
      if (!this.checkedGB.includes("单指针")) return;
      if (this.checkedGB.includes("边带光标")) return; // 边带模式冻结单指针
      if (!this.chartInstance) return;

      const { x, y } = this.getChartXYData();
      if (!x.length || !y.length) return;

      const pointInGrid = this.chartInstance.convertFromPixel(
        { seriesIndex: 0 },
        [event.offsetX, event.offsetY],
      );
      const xClick = pointInGrid?.[0];
      if (xClick == null || Number.isNaN(xClick)) return;

      const idx = this.findClosestIndex(xClick, x);
      if (idx < 0) return;

      const xAxis = Number(x[idx]);
      const yValue = Number(y[idx]);
      if (Number.isNaN(xAxis) || Number.isNaN(yValue)) return;

      const existed = this.singlePointerPoints.some(
        (p) => Number(p.xAxis) === xAxis,
      );
      if (!existed) {
        this.singlePointerPoints.push({
          xAxis,
          val: yValue.toFixed(6),
        });
      }

      // 默认最后一次点击的单指针作为边带中心（0线）
      this.activeSinglePointer = {
        xAxis,
        val: yValue.toFixed(6),
      };

      this.applySinglePointerSeries();
    },
    applySinglePointerSeries() {
      if (!this.chartInstance) return;
      const option = this.chartInstance.getOption();
      const otherSeries = (option.series || []).filter(
        (s) => s && s.id !== "SINGLE_POINTER_LINE",
      );

      if (!this.singlePointerPoints.length) {
        this.chartInstance.setOption(
          { series: otherSeries },
          { replaceMerge: ["series"] },
        );
        return;
      }

      const seriesConfig = {
        id: "SINGLE_POINTER_LINE",
        type: "line",
        data: [],
        silent: true,
        z: 20,
        markLine: {
          silent: false,
          symbol: ["none", "none"],
          lineStyle: {
            color: "#ff0000",
            type: "dashed",
            width: 2,
          },
          label: {
            show: true,
            position: "end",
            formatter: (params) => params.data?.val || "",
          },
          data: this.singlePointerPoints.map((p) => ({
            xAxis: p.xAxis,
            val: p.val,
          })),
        },
      };

      this.chartInstance.setOption(
        { series: [...otherSeries, seriesConfig] },
        { replaceMerge: ["series"] },
      );
    },
    removeSinglePointerSeries() {
      if (!this.chartInstance) return;
      const option = this.chartInstance.getOption();
      const series = (option.series || []).filter(
        (s) => s && s.id !== "SINGLE_POINTER_LINE",
      );
      this.chartInstance.setOption({ series }, { replaceMerge: ["series"] });
    },
    enableSidebandCursor() {
      this.sidebandCursorVisible = true;
      if (!this.chartInstance) return;
      // 边带模式：只响应边带点击，冻结单指针
      this.unbindSinglePointerClick();
      this.chartInstance.getZr().off("click", this.handleSidebandCursorClick);
      this.chartInstance.getZr().on("click", this.handleSidebandCursorClick);
    },
    disableSidebandCursor() {
      this.sidebandCursorVisible = false;
      if (this.chartInstance) {
        this.chartInstance.getZr().off("click", this.handleSidebandCursorClick);
      }
      this.removeSidebandCursor();
      if (this.checkedGB.includes("单指针")) {
        this.bindSinglePointerClick();
      }
    },
    handleSidebandCursorClick(event) {
      if (!this.sidebandCursorVisible || !this.chartInstance) return;
      if (!this.singlePointerPoints.length) return;

      const pointInGrid = this.chartInstance.convertFromPixel(
        { seriesIndex: 0 },
        [event.offsetX, event.offsetY],
      );
      const clickX = pointInGrid?.[0];
      if (clickX == null || Number.isNaN(clickX)) return;

      // 以离点击最近的单指针来定义边带间隔 delta
      const nearestCenter = this.singlePointerPoints.reduce((prev, cur) => {
        const prevDiff = Math.abs(clickX - Number(prev.xAxis));
        const curDiff = Math.abs(clickX - Number(cur.xAxis));
        return curDiff < prevDiff ? cur : prev;
      });
      const referenceCenterX = Number(nearestCenter.xAxis);
      const delta = Math.abs(clickX - referenceCenterX);
      if (!delta) return;

      const points = [];
      this.singlePointerPoints.forEach((center) => {
        const centerX = Number(center.xAxis);
        for (let n = -5; n <= 5; n++) {
          if (n === 0) continue;
          points.push({
            xAxis: centerX + n * delta,
            val: `${n > 0 ? "+" : ""}${n}`,
          });
        }
      });
      this.sidebandCursorPoints = points;
      this.applySidebandSeries();
    },
    applySidebandSeries() {
      if (!this.chartInstance) return;
      const option = this.chartInstance.getOption();
      const otherSeries = (option.series || []).filter(
        (s) => s && s.id !== "SIDEBAND_CURSOR",
      );

      if (!this.sidebandCursorPoints.length) {
        this.chartInstance.setOption(
          { series: otherSeries },
          { replaceMerge: ["series"] },
        );
        return;
      }

      const sidebandSeries = {
        id: "SIDEBAND_CURSOR",
        type: "line",
        data: [],
        silent: true,
        z: 21,
        markLine: {
          silent: true,
          symbol: ["none", "none"],
          lineStyle: {
            color: "#ff0000",
            type: "dashed",
            width: 1,
          },
          label: {
            show: true,
            position: "start",
            formatter: (params) => params.data?.val || "",
            color: "#ff0000",
          },
          data: this.sidebandCursorPoints.map((p) => ({
            xAxis: p.xAxis,
            val: p.val,
          })),
        },
      };

      this.chartInstance.setOption(
        { series: [...otherSeries, sidebandSeries] },
        { replaceMerge: ["series"] },
      );
    },
    removeSidebandCursor() {
      this.sidebandCursorPoints = [];
      if (!this.chartInstance) return;
      const option = this.chartInstance.getOption();
      const series = (option.series || []).filter(
        (s) => s && s.id !== "SIDEBAND_CURSOR",
      );
      this.chartInstance.setOption({ series }, { replaceMerge: ["series"] });
    },
    initializeChart() {
      const chartDom = this.$refs.chart;
      if (chartDom && !this.chartInstance) {
        this.chartInstance = echarts.init(chartDom);
      }
      if (this.timeList.y && this.timeList.x) {
        this.updateChart(this.timeList.y, this.timeList.x);
      }
    },
    handleCascaderChange(val) {
      if (!val || val.length === 0) {
        this.activeFeatures = [];
        this.renderTZFeatures();
        return;
      }

      // val = [["时域特征", "Xrms"], ["时域特征", "max_value"]]

      this.activeFeatures = val.map((item) => item[item.length - 1]);

      this.renderTZFeatures(); // ✅ 直接用你已有方法
    },
    renderTZFeatures() {
      if (!this.chartInstance) return;

      const marks = this.activeFeatures
        .filter((key) => this.timeList[key] !== undefined)
        .map((key) => ({
          yAxis: this.timeList[key],
          label: {
            // formatter: key,
            formatter: this.timeList[key],
          },
        }));

      this.chartInstance.setOption({
        series: [
          {
            id: "MAIN_SERIES",
            markLine: {
              silent: true,
              symbol: ["none", "none"],
              lineStyle: {
                color: "#00aaff",
                type: "dashed",
              },
              data: marks,
            },
          },
        ],
      });
    },
    selectCursor(val) {
      const isAlreadyChecked = this.checkedGB.includes(val);
      const isSinglePointerVal = val === "单指针";
      const isSidebandVal = val === "边带光标";
      const isHarmonicVal = val === "谐波光标";

      if (isAlreadyChecked) {
        if (isSinglePointerVal) {
          // 单指针取消时，级联取消边带
          this.checkedGB = this.checkedGB.filter(
            (v) => v !== "单指针" && v !== "边带光标",
          );
        } else {
          this.checkedGB = this.checkedGB.filter((v) => v !== val);
        }
      } else if (isSinglePointerVal || isSidebandVal) {
        const next = new Set(this.checkedGB);
        next.add(val);
        next.delete("谐波光标");
        this.checkedGB = Array.from(next);
      } else if (isHarmonicVal) {
        this.checkedGB = [val];
      } else {
        this.checkedGB = [val];
      }

      const isSidebandChecked = this.checkedGB.includes("边带光标");
      const isHarmonicChecked = this.checkedGB.includes("谐波光标");
      const isSinglePointerChecked = this.checkedGB.includes("单指针");

      isSidebandChecked
        ? this.enableSidebandCursor()
        : this.disableSidebandCursor();
      isHarmonicChecked
        ? this.enableHarmonicCursor()
        : this.disableHarmonicCursor();
      if (!isSinglePointerChecked) {
        this.disableSinglePointer();
      } else if (isSidebandChecked) {
        // 保留单指针线，冻结单指针点击
        this.unbindSinglePointerClick();
      } else {
        this.enableSinglePointer();
      }
    },
    // 更新图表数据
    updateChart(data, labels) {
      if (!this.chartInstance) return; // Check if chartInstance is available
      console.log(this.timeList, "updataChart  时域图");
      const option = {
        // title: {
        //   text: this.timeList.title,
        //   left: "center",
        // },
        grid: {
          left: 60, // 原来是100，适当缩小左右边距
          right: 60,
          //   bottom: 90, // 给推拽条和坐标轴腾出空间
          top: 30,
          bottom: 50,
        },
        toolbox: {
          right: 10,
          // top: 55, // 👈 工具栏在最上面
          feature: {
            dataZoom: { yAxisIndex: "none" },
            restore: {},
            saveAsImage: {},
            // myCustomTool3: {
            //   show: true,
            //   title: "特征值",
            //   icon: `image://${require("@/assets/analyse/10.png")}`,
            //   onclick: () => this.Show(),
            // },
          },
        },
        xAxis: {
          type: "value",
          name: this.timeList.xaxis,
          nameLocation: "center",
          nameTextStyle: {
            fontSize: 12,
            color: "#333",
            padding: [15, 0, 0, 0], // 增加X轴标题和轴线的距离
          },
          axisLabel: {
            margin: 1, // 增加数值标签和轴线的间距
            formatter: (value) => value,
          },
          axisTick: {
            show: true,
          },
          axisLine: {
            show: true,
          },
        },
        yAxis: {
          type: "value",
          name: this.timeList.yaxis,
          nameTextStyle: {
            fontSize: 12,
            color: "#333",
            padding: [0, 10, 0, 0], // 根据需要微调
          },
          axisLabel: {
            margin: 10,
            formatter: (value) => value,
          },
          axisTick: {
            show: true,
          },
          axisLine: {
            show: true,
          },
        },
        tooltip: {
          trigger: "axis",
          formatter: (params) => {
            const xValue = params[0].value[0];
            const yValue = params[0].value[1];
            return `X: ${xValue}<br/>Y: ${yValue}`;
          },
          axisPointer: {
            type: "line",
          },
        },
        dataZoom: [
          {
            type: "inside",
            xAxisIndex: 0,
            filterMode: "none",
            zoomOnMouseWheel: false,
            moveOnMouseMove: false,
            moveOnMouseWheel: false,
          },
        ],
        // dataZoom: [
        //   {
        //     type: "inside",
        //     start: 0,
        //     end: 10,
        //   },
        //   {
        //     type: "slider",
        //     start: 0,
        //     end: 10,
        //     handleSize: "80%",
        //     showDataShadow: false,
        //     top: 30, // 👈 放到顶部
        //     height: 20, // 👈 控制高度（可选）
        //   },
        // ],
        series: [
          {
            id: "MAIN_SERIES", // ✅ 必须加
            name: "数据系列",
            type: "line",
            data: labels.map((item, index) => [item, data[index]]),
            // data: (labels || []).map((item, index) => [item, data?.[index]])
            symbol: "none",
            symbolSize: 8,
            lineStyle: {
              color: "#162961",
              width: 1,
            },
            itemStyle: {
              color: "#162961",
              borderColor: "#fff",
              borderWidth: 1,
            },
            large: true,
            progressive: 2000,
          },
        ],
      };

      this.chartInstance.setOption(option, true);
      this.$nextTick(() => {
        this.renderTZFeatures(); // ✅ 防止被覆盖
        this.applySinglePointerSeries();
        this.applySidebandSeries();
      });
    },
    generateSeries(featureLines) {
      const createMarkLine = (dataSource, color) => ({
        type: "line",
        markLine: {
          silent: false,
          lineStyle: { color, type: "dashed", width: 1 },
          symbol: ["none", "none"],
          label: {
            show: true,
            position: "end",
            formatter: ({ data }) => data.val,
          },
          emphasis: {
            symbol: ["none", "none"],
            lineStyle: { color: "#FF6A00", width: 2 },
            label: {
              show: true,
              formatter: ({ value }) => `特征值: ${value}`,
              color: "#000",
            },
          },
          data: dataSource.map(({ Xaxis, val }) => ({ xAxis: Xaxis, val })),
        },
      });

      const markLines = [
        { data: featureLines.Fr, color: "#A633FF" },
        { data: featureLines.BPFI, color: "#23357e" },
        { data: featureLines.BPFO, color: "#42a0ae" },
        { data: featureLines.BSF, color: "#008080" },
        { data: featureLines.FTF, color: "#af254f" },
        { data: featureLines.B3P, color: "#FFD700" },
      ].map(({ data, color }) => createMarkLine(data, color));

      return [
        {
          name: "数据系列",
          type: "line",
          data: this.spectrumList.x.map((x, i) => [x, this.spectrumList.y[i]]),
          symbol: "none",
          lineStyle: { color: "#162961", width: 1 },
          itemStyle: { color: "#162961", borderColor: "#fff", borderWidth: 1 },
          large: true,
        },
        ...markLines,
      ];
    },
    renderFeatureSeries(featureLines) {
      if (!this.chartInstance) return;

      const currentOption = this.chartInstance.getOption();

      // 保留光标
      const cursorLineSeries =
        currentOption.series.find((s) => s && s.id === "CURSOR_LINE_SERIES") ||
        {};
      const cursorPointSeries =
        currentOption.series.find((s) => s && s.id === "CURSOR_POINT_SERIES") ||
        {};
      const cursorHighLineSeries =
        currentOption.series.find((s) => s && s.id === "PEAK_REFERENCE_LINE") ||
        {};

      const featureSeries = this.generateSeries(featureLines);

      this.chartInstance.setOption(
        {
          series: [
            (currentOption.series || []).find(
              (s) => s && (s.id === "MAIN_SERIES" || s.name === "数据系列"),
            ) || (currentOption.series || []).find((s) => s),
            ...featureSeries.slice(1),
            cursorLineSeries,
            cursorPointSeries,
            cursorHighLineSeries,
          ].filter((s) => s && s.type),
        },
        { replaceMerge: ["series"] },
      );
    },
    getTime() {
      this.$emit("handleLoading", {
        id: this.chartId,
        currentRow: this.currentRow,
        loading: true,
      });
      const params = {
        ids: this.ids,
        analysisType: "time",
        windCode: this.windCode,
      };
      axios
        .post("/AnalysisMulti/analysis/time", params)
        .then((res) => {
          this.timeList = JSON.parse(res.data);

          console.log(this.timeList, "timeList");
        })
        .catch((error) => {})
        .finally(() => {
          this.$emit("handleLoading", {
            id: this.chartId,
            currentRow: this.currentRow,
            loading: false,
          });
        });
    },
    Show() {
      this.TZshow = !this.TZshow;
    },
  },
};
</script>

<style lang="scss" scoped>
.line-chart {
  width: 100%;
  height: 400px;
}
.FD {
  width: 100%;
  height: 1px;
  position: relative;
}

.eigenvalue {
  position: absolute;
  top: 30px;
  right: 0;
  font-size: 10px;
  width: 100px;
  border: 1px solid black;
  padding: 5px;
  background: #fff;

  z-index: 99;
  h5 {
    line-height: 16px;
    height: 16px;
  }
}
.control-panel {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  padding: 8px 12px;
  background: #f5f7fa;
  border: 1px solid #ddd;
  border-radius: 6px;
  margin-bottom: 10px;
}
.panel-block {
  display: flex;
  align-items: center;
  gap: 6px;
}

.label {
  font-size: 12px;
  color: #666;
}

.btn-group {
  display: flex;
  gap: 6px;
}

.btn {
  padding: 2px 8px;
  font-size: 12px;
  border: 1px solid #ccc;
  border-radius: 3px;
  cursor: pointer;
}

.btn.active {
  background: #409eff;
  color: #fff;
}
</style>
