<template>
  <div class="echart_content">
    <div class="is_show_all" v-if="showCheckBox">
      <el-checkbox
        v-model="checkAll"
        :indeterminate="isIndeterminate"
        @change="toggleChangeAll"
      >
        显示全部
      </el-checkbox>
    </div>
    <div
      ref="lineChartRef"
      class="chart_box"
      :style="{ height: reportHeight || '400px' }"
    ></div>
  </div>
</template>

<script setup lang="ts">
import { ref, watch, onMounted, onBeforeUnmount, nextTick } from "vue";
import _ from "lodash";
import * as echarts from "echarts";
import { getScorePerformanceAnalysis } from "@/utils/common";

// 定义 props 类型
interface Props {
  gridRight?: number;
  gridTop?: number | string;
  legendWidth?: number | string;
  showCheckBox?: boolean;
  extraText?: boolean;
  datax?: string[];
  datay?: number[][];
  tooltipData?: any[]; // 复杂结构，可进一步定义
  colors?: string[];
  unit?: string;
  title?: string[];
  markNumber?: number[];
  isSmooth?: boolean;
  showBackground?: boolean;
  isShowLabel?: boolean;
  labelColor?: string;
  showMarkPoint?: boolean;
  legendList?: string[];
  yInverse?: boolean;
  updateKey?: number;
  gridLeft?: number;
  fontSize?: number | string;
  fontColor?: string;
  reportHeight?: string;
}

const props = withDefaults(defineProps<Props>(), {
  gridRight: 0,
  gridTop: "",
  legendWidth: "auto",
  showCheckBox: true,
  extraText: true,
  datax: () => ["G10", "G9", "G8", "G7", "G6", "G5", "G4", "G3", "G2", "G1"],
  datay: () => [],
  tooltipData: () => [],
  colors: () => getScorePerformanceAnalysis(),
  unit: "",
  title: () => [],
  markNumber: () => [],
  isSmooth: false,
  showBackground: true,
  isShowLabel: false,
  labelColor: "",
  showMarkPoint: false,
  legendList: () => [],
  yInverse: false,
  updateKey: 0,
  gridLeft: 20,
  fontSize: "",
  fontColor: "",
  reportHeight: "",
});

// 定义 emits
const emit = defineEmits<{
  (e: "SelectLegend", selected: string[]): void;
}>();

// DOM 引用
const lineChartRef = ref<HTMLElement | null>(null);

// 数据状态
let echart: echarts.ECharts | null = null;
const checkAll = ref(true);
const isIndeterminate = ref(false);
const legendSelected = ref<Record<string, boolean>>({});
const legenSelectList = ref<string[]>([]);
const legenAllList = ref<string[]>([]);

// 辅助函数 - 辅助线配置
const markLine = (index: number) => {
  if (!props.markNumber.length) return {};
  return {
    data: [
      {
        type: "average" as const,
        name: "平均值",
        yAxis: props.markNumber[index] ?? null,
      },
    ],
    label: {
      position: "end",
      formatter: (params: any) => {
        return props.markNumber[index] ?? params.value;
      },
    },
    lineStyle: {
      type: "dashed",
      color: props.colors[index],
    },
  };
};

// 加载 / 重绘图表
const loadEchart = () => {
  // 更新图例选择列表
  legenSelectList.value =
    props.legendList.length > 0 ? [...props.legendList] : [];
  legenAllList.value = [...props.title];

  // 销毁旧实例
  if (echart) {
    echart.dispose();
    echart = null;
  }

  if (!lineChartRef.value) return;

  // 初始化新实例（提高清晰度）
  echart = echarts.init(lineChartRef.value, undefined, { devicePixelRatio: 2 });

  // 初始化图例选中状态
  legendSelected.value = {};
  props.title.forEach((name) => {
    legendSelected.value[name] = legenSelectList.value.includes(name);
  });

  // 更新全选按钮状态
  checkAll.value = legenSelectList.value.length === legenAllList.value.length;
  isIndeterminate.value =
    legenSelectList.value.length > 0 &&
    legenSelectList.value.length < legenAllList.value.length;

  // 计算最大值/最小值用于Y轴刻度隐藏
  const allValues = props.datay.flat();
  const maxValue = Math.max(...allValues);
  const minValue = Math.min(...allValues);
  const hideTick = minValue < 0 || props.yInverse;

  // 获取当前显示图例对应数据中的最大值（用于Y轴范围，原代码中注释未启用，这里保留计算）
  // const visibleSeriesIndices = legenSelectList.value.map(name => props.title.indexOf(name))
  // const visibleData = visibleSeriesIndices.filter(i => i !== -1).map(i => props.datay[i])
  // const visibleMax = visibleData.length ? Math.max(...visibleData.flat()) : maxValue

  const extraTextStr = props.extraText ? "占比" : "";
  const dataCount = props.datax.length;
  const containerWidth = lineChartRef.value.clientWidth;
  const singleSeriesWidth = (containerWidth - 100) / dataCount;

  let gridTop = props.showMarkPoint ? 45 : 20;
  if (props.title.length > 0) gridTop = 70;
  const option: echarts.EChartsOption = {
    tooltip: {
      trigger: "axis",
      axisPointer: { type: "line" },
      renderModel: "html",
      confine: true,
      extraCssText:
        "border-radius: 4px;padding:5px 0px 5px 5px;white-space:normal;word-warp:break-word;max-width: 400px;",
      enterable: true,
      formatter: (params: any) => {
        if (!params || !params.length) return "";
        let tooltip = `<div class='tooltip_content'>`;
        tooltip += `<div class='tooltip_title'>${params[0].name}</div>`;
        params.forEach((item: any, idx: number) => {
          const name = item.seriesName;
          const rate = item.value + props.unit;
          if (props.tooltipData.length > 0) {
            const tooltipItem =
              props.tooltipData?.[item.seriesIndex]?.[item.dataIndex] || {};
            tooltip += `<div class='tooltip_student'>
                            <div class='tooltip_line_icon' style='background:${item.color}'></div>
                            <div class='tooltip_student_name'>${tooltipItem.name}：${tooltipItem.value}</div>
                        </div>`;
          } else {
            tooltip += `<div class='tooltip_student'>
                            <div class='tooltip_line_icon' style='background:${item.color}'></div>
                            <div class='tooltip_student_name'>${name}${extraTextStr}：${rate || "-"}</div>
                        </div>`;
          }
        });
        tooltip += `</div>`;
        return tooltip;
      },
    },
    legend: {
      show: props.title.length > 0,
      top:0,
      left: props.showCheckBox ? "110px" : "0px",
      width: props.legendWidth,
      itemGap: 20,
      itemHeight: 10,
      itemWidth: 25,
      data: props.title,
      textStyle: {
        fontSize: 12,
        color: "#333",
        lineHeight: 30,
      },
      selectedMode: true,
      selected: legendSelected.value,
      type: "scroll",
      pageIconColor: "#999",
      pageIconInactiveColor: "#ccc",
      pageButtonItemGap: 5,
      pageButtonPosition: "end",
      orient: "horizontal",
      alignTo: "none",
    },
    grid: {
      left: props.gridLeft,
      right: props.gridRight,
      top: props.gridTop || gridTop,
      bottom: 0,
      containLabel: true,
    },
    xAxis: {
      type: "category",
      data: props.datax,
      boundaryGap: true,
      triggerEvent: true,
      axisTick: {
        alignWithLabel: true,
        show: !hideTick,
        inside: false,
        length: 8,
      },
      axisLine: { show: !props.yInverse },
      axisLabel: {
        interval: 0,
        rotate: singleSeriesWidth < 60 ? 45 : 0,
        fontSize: props.fontSize ? Number(props.fontSize) : 14,
        color: props.fontColor || "#666",
        fontWeight: 400,
        formatter: (value: string) => {
          const valueWidth = value.length * 14;
          if (valueWidth > singleSeriesWidth) {
            if (singleSeriesWidth < 80) return value;
            const maxLength = Math.floor(singleSeriesWidth / 14);
            return value.slice(0, maxLength) + "...";
          }
          return value;
        },
      },
    },
    yAxis: {
      type: "value",
      axisLabel: {
        margin: 20,
        formatter: `{value}${props.unit}`,
        interval: 0,
        fontSize: props.fontSize ? Number(props.fontSize) : 14,
        color: props.fontColor || "#666",
        fontWeight: 400,
      },
      splitNumber: 5,
      axisTick: { interval: 0 },
      splitLine: {
        show: true,
        lineStyle: { color: "#E4E7ED", width: 1, type: "solid" },
      },
      splitArea: {
        show: true,
        areaStyle: { color: ["#fafafa", "#ffffff"] },
      },
      inverse: props.yInverse,
    },
    graphic: {
      elements: [
        {
          type: "group",
          key: "mark-point-group",
          z: 10,
        },
      ],
    },
    series: props.datay.map((data, index) => ({
      type: "line",
      name: props.title[index],
      symbol: "emptyCircle",
      showSymbol: true,
      symbolSize: 8,
      label: {
        show: props.isShowLabel,
        color: props.labelColor || props.colors[index],
        formatter: `{c}${props.unit}`,
      },
      smooth: props.isSmooth,
      markLine: markLine(index),
      markPoint: props.showMarkPoint
        ? {
            data: [
              { type: "max", name: "最大值", label: { color: "#fff" } },
              { type: "min", name: "最小值", label: { color: "#fff" } },
            ],
          }
        : undefined,
      itemStyle: {
        color: props.colors[index],
        borderColor: props.colors[index],
        borderWidth: 1,
        shadowColor: "rgba(0, 0, 0, .1)",
        shadowBlur: 0,
      },
      lineStyle: { width: 3 },
      areaStyle: props.showBackground
        ? {
            color: {
              type: "linear",
              x: 0,
              y: 0,
              x2: 0,
              y2: 1,
              colorStops: [
                { offset: 0, color: props.colors[index] + "30" },
                { offset: 1, color: props.colors[index] + "00" },
              ],
            },
          }
        : undefined,
      emphasis: {
        focus: "series",
        blurScope: "coordinateSystem",
      },
      data: data,
    })),
  };

  echart.setOption(option);

  // X轴文字过长悬浮提示
  setupXAxisTooltip();

  // 绑定图例切换事件
  echart.on("legendselectchanged", handleLegendSelectChanged);
};

// X轴标签悬浮显示完整文本
const setupXAxisTooltip = () => {
  let tooltipDiv = document.getElementById("x-axis-tooltip");
  if (!tooltipDiv) {
    tooltipDiv = document.createElement("div");
    tooltipDiv.id = "x-axis-tooltip";
    tooltipDiv.style.cssText = `
            position: absolute;
            z-index: 9999;
            background: #303133;
            color: #fff;
            padding: 6px 10px;
            border-radius: 4px;
            font-size: 12px;
            pointer-events: none;
            display: none;
            white-space: nowrap;
        `;
    document.body.appendChild(tooltipDiv);
  }

  if (!echart) return;
  echart.on("mouseover", (params: any) => {
    if (params.componentType === "xAxis") {
      const value = params.value;
      if (value && value.length > 5) {
        tooltipDiv!.style.display = "block";
        tooltipDiv!.innerText = value;
      }
    }
  });
  echart.on("mouseout", (params: any) => {
    if (params.componentType === "xAxis") {
      tooltipDiv!.style.display = "none";
    }
  });

  const container = lineChartRef.value;
  if (container) {
    container.addEventListener("mousemove", (e) => {
      if (tooltipDiv && tooltipDiv.style.display === "block") {
        tooltipDiv.style.left = `${e.pageX + 10}px`;
        tooltipDiv.style.top = `${e.pageY + 15}px`;
      }
    });
  }
};

// 图例切换处理
const handleLegendSelectChanged = (params: any) => {
  if (!echart) return;
  const option = echart.getOption();
  const legendData = (option.legend as any)[0].data as string[];
  const selected = params.selected;
  legendSelected.value = selected;

  const allSelected = legendData.every((seriesName) => selected[seriesName]);
  const noneSelected = legendData.every((seriesName) => !selected[seriesName]);
  const someSelected = !allSelected && !noneSelected;

  if (noneSelected) checkAll.value = false;
  if (allSelected) checkAll.value = true;
  isIndeterminate.value = someSelected;

  const legendSelectedList = Object.keys(selected).filter(
    (key) => selected[key],
  );
  emit("SelectLegend", legendSelectedList);
};

// 全选 / 全不选按钮点击
const toggleChangeAll = () => {
  if (!props.showCheckBox) return;
  if (!echart) return;
  const option = echart.getOption();
  const legendData = (option.legend as any)[0].data as string[];
  legendData.forEach((seriesName) => {
    echart!.dispatchAction({
      type: checkAll.value ? "legendSelect" : "legendUnSelect",
      name: seriesName,
    });
  });
  isIndeterminate.value = false;

  const legendSelectedList = checkAll.value ? [...props.title] : [];
  emit("SelectLegend", legendSelectedList);
};

// 窗口自适应（节流）
const handleResize = _.throttle(() => {
  nextTick(() => {
    loadEchart();
  });
}, 500);

// 监听 props 变化
watch(
  () => props.legendList,
  () => loadEchart(),
  { deep: true },
);
watch(
  () => props.updateKey,
  () => loadEchart(),
);
watch(
  () => props.datay,
  () => loadEchart(),
  { deep: true },
);

// 生命周期
onMounted(() => {
  loadEchart();
  window.addEventListener("resize", handleResize);
});

onBeforeUnmount(() => {
  window.removeEventListener("resize", handleResize);
  if (echart) {
    echart.dispose();
    echart = null;
  }
});
</script>

<style lang="scss" scoped>
//图标外层公共样式
.echart_content {
  position: relative;
  width: 100%;
  margin: auto;
  min-height: 360px;
  height: auto;
  // overflow-x: auto;
  .is_show_all {
    position: absolute;
    top: 10px;
    left: 5px;
  }
}

//弹窗悬浮层样式更改
.echart_content::-webkit-scrollbar {
  width: 100%;
  height: 8px;
  /* 设置滚动条宽度为8像素 */
  background-color: transparent;
}

/* 滑块样式 */
.echart_content::-webkit-scrollbar-thumb {
  background-color: #b8b8b8;
  /* 设置滑块颜色为深灰色 */
  border-radius: 4px;
  /* 设置滑块边角半径为4像素 */
  min-height: 40px; //设置手柄最小高度
}

/* 滚动条轨道内部空白区域样式 */
.echart_content::-webkit-scrollbar-track {
  background-color: #f0f0f0;
  /* 设置轨道背景色为浅灰色 */
}

/* 滚动条两端按钮样式 */
.echart_content::-webkit-scrollbar-button {
  display: none;
  /* 不显示按钮 */
}

/* 交叉点处的区域样式 */
.echart_content::-webkit-scrollbar-corner {
  background-color: transparent;
  /* 设置交叉点处的背景色为透明 */
}

/* 调整大小手柄样式 */
.echart_content::-webkit-resizer {
  display: none;
  /* 不显示调整大小手柄 */
}
</style>
