<template>
  <div class="echart_content" style="position: relative">
    <div class="is_show_all" v-if="showCheckBox">
      <el-checkbox
        v-model="checkAll"
        :indeterminate="isIndeterminate"
        @change="ChangeCheckAll"
      >
        显示全部
      </el-checkbox>
    </div>

    <div class="title_right" v-if="selectBarNum === 1">
      <div
        :class="['right_item', { item_active: selectValue === item.value }]"
        v-for="item in selectOptions"
        :key="item.value"
        @click="ChangeOrder(item.value)"
      >
        {{ item.label }}
      </div>
    </div>

    <div ref="barChartsRef" class="chart_width" />
  </div>
</template>

<script setup lang="ts">
import { ref, watch, onMounted, onBeforeUnmount, nextTick } from "vue";
import throttle from "lodash/throttle";
// 修复：替换不存在的 LegendOption
import type { ECharts, EChartsOption, LegendComponentOption } from "echarts";
import * as echarts from "echarts";
import { getScorePerformanceAnalysis } from "@/utils/common";

// ==================== Types ====================
type SelectOption = {
  value: string;
  label: string;
};

type ChartDataRow = (string | number)[];
type ChartDatasetSource = ChartDataRow[];

// 组件 Props
interface Props {
  showCheckBox?: boolean;
  color?: string[];
  data?: ChartDatasetSource;
  title?: string;
  legendList?: string[];
  showBarLegendIndex?: number;
  showSortSelectbox?: boolean;
}

const props = withDefaults(defineProps<Props>(), {
  showCheckBox: true,
  color: () => [],
  data: () => [],
  title: "",
  legendList: () => [],
  showBarLegendIndex: 1,
  showSortSelectbox: true,
});

// Emits
interface Emits {
  (e: "HandleChartClick", index: number, name: string): void;
  (
    e: "ChangeChartOrder",
    val: string,
    legendData: string[],
    selectedBarIndex: number,
  ): void;
}
const emit = defineEmits<Emits>();

// ==================== Ref State ====================
const barChartsRef = ref<HTMLDivElement | null>(null);
let echartInstance: ECharts | null = null;

const selectValue = ref<string>("1");
const selectOptions = ref<SelectOption[]>([
  { value: "1", label: "默认" },
  { value: "2", label: "升序" },
  { value: "3", label: "降序" },
]);
const selectBarNum = ref<number>(0);
const checkAll = ref<boolean>(true);
const isIndeterminate = ref<boolean>(false);
const colors = ref<string[]>(getScorePerformanceAnalysis());
const legendSelected = ref<Record<string, boolean>>({});
const legenSelectList = ref<string[]>([]);
const legenAllList = ref<string[]>([]);
const dataZoomEnd = ref<number>(0);
const dataZoomNum = ref<number>(5);

// ==================== Methods ====================
/** 销毁实例 + 移除监听 */
function disposeEchart() {
  if (echartInstance) {
    echartInstance.dispose();
    echartInstance = null;
  }
}

/** X轴文字悬浮提示（全局div） */
function LabelMouseOver() {
  // 填入你原有DOM逻辑
}
function ShowXAxisTooltip() {
  // 填入你原有DOM逻辑
}

/** 加载渲染图表 */
async function LoadEchart() {
  if (!barChartsRef.value) return;
  disposeEchart();

  echartInstance = echarts.init(barChartsRef.value, null, {
    devicePixelRatio: 2,
  });

  // 修复：转换为 string[]，消除TS2322类型报错
  if (props.legendList.length > 0) {
    legenSelectList.value = [...props.legendList];
  } else {
    legenSelectList.value =
      props.data[0]?.slice(1).map((item) => String(item)) ?? [];
  }
  legenAllList.value =
    props.data[0]?.slice(1).map((item) => String(item)) ?? [];

  // dataset
  const dataset = { source: props.data };
  let constColorAll = getScorePerformanceAnalysis();
  if (props.color.length > 0) constColorAll = props.color;

  // 初始化图例选中状态
  const legendMap: Record<string, boolean> = {};
  const dims = dataset.source[0]?.slice(1) ?? [];
  dims.forEach((dim) => {
    legendMap[String(dim)] = false;
  });
  legenSelectList.value.forEach((item) => {
    legendMap[item] = true;
  });
  legendSelected.value = legendMap;

  checkAll.value = legenSelectList.value.length === legenAllList.value.length;
  isIndeterminate.value =
    legenSelectList.value.length > 0 &&
    legenSelectList.value.length < legenAllList.value.length;

  const numSeries = Object.values(legendSelected.value).filter(Boolean).length;
  const totalWidth = barChartsRef.value.clientWidth;
  const dataxCount = props.data.length;

  dataZoomNum.value = Math.floor((totalWidth - 60) / (50 * numSeries));
  const xAxisTotal = dataset.source.length - 1 || 1;
  dataZoomEnd.value = Math.floor((100 / xAxisTotal) * dataZoomNum.value);

  const dataZoom = {
    start: 0,
    end: dataZoomEnd.value,
    type: "slider",
    show: true,
    borderColor: "transparent",
    borderCap: "round",
    xAxisIndex: [0],
    height: 8,
    left: 20,
    right: 20,
    bottom: 0,
    fillerColor: "transparent",
    zoomLock: true,
    handleSize: "0",
    handleStyle: {
      color: "#b8b8b8",
      borderWidth: 2,
    },
    backgroundColor: "transparent",
    showDataShadow: false,
    showDetail: false,
    filterMode: "filter",
  };

  // series 构建
  const series = dims.map((item, index) => {
    const name = String(item);
    if (index < props.showBarLegendIndex) {
      return {
        type: "bar",
        name,
        barGap: 0,
        barCategoryGap: "30%",
        barMinWidth: 8,
        barMaxWidth: 50,
        itemStyle: {
          color: constColorAll[index] ?? "#ccc",
        },
        label: {
          position: "top",
          color: "#666",
          fontSize: 12,
          formatter: (params: any) => {
            const val = params.value[params.seriesIndex + 1];
            return `${val}%`;
          },
        },
      };
    } else {
      return {
        type: "line",
        name,
        label: { show: false },
        symbol: "emptyCircle",
        showSymbol: true,
        smooth: false,
        itemStyle: {
          color: constColorAll[index] ?? "#ccc",
          borderColor: constColorAll[index] ?? "#ccc",
          borderWidth: 3,
        },
      };
    }
  });

  const option: EChartsOption = {
    dataset,
    tooltip: {
      axisPointer: { type: "line" },
      trigger: "axis",
      confine: true,
      extraCssText:
        "border-radius: 4px;padding:5px 0px 5px 5px;white-space:normal;word-wrap:break-word;max-width: 400px;",
      enterable: true,
      formatter: (params: any[]) => {
        let tooltip = `<div class='tooltip_content'>`;
        const title = params[0].name;
        tooltip += `<div class='tooltip_title'>${title}</div>`;
        params.forEach((item) => {
          const className = item.seriesName;
          const rate = item.data[item.seriesIndex + 1];
          const iconClass =
            item.seriesType === "bar"
              ? "tooltip_rect_icon"
              : "tooltip_line_icon";
          tooltip += `<div class='tooltip_student'><span class='${iconClass}' style='background:${item.color}'></span>${className}${props.title}：${rate}%</div>`;
        });
        tooltip += `</div>`;
        return tooltip;
      },
    },
    legend: {
      show: true,
      top: 0,
      left: "110px",
      width:
        props.showSortSelectbox && selectBarNum.value === 1 ? "70%" : "auto",
      itemGap: 20,
      itemHeight: 10,
      itemWidth: 20,
      textStyle: { fontSize: 12, color: "#333" },
      selectedMode: true,
      selected: legendSelected.value,
      type: "scroll",
      pageButtonItemGap: 5,
      pageButtonPosition: "end",
      orient: "horizontal",
      alignTo: "none",
      pageIconColor: "#999",
      pageIconInactiveColor: "#ccc",
      formatter: (name: string) => name.replace(/g/g, "G"),
    } as LegendComponentOption, // 修复类型
    // dataZoom: [dataZoom],
    grid: {
      top: 50,
      left: 20,
      right: 40,
      bottom: 0,
      containLabel: true,
    },
    yAxis: {
      type: "value",
      axisLabel: {
        formatter: "{value}%",
        fontSize: 14, color: "#666", fontWeight: 400
      },
    },
    xAxis: {
      type: "category",
      axisLabel: {
        interval: 0,
        rotate: totalWidth / dataxCount < 80 ? 45 : 0,
        fontSize: 14, color: "#666", fontWeight: 400,
        formatter: (value: string) => {
          const singleSeriesWidth = totalWidth / dataxCount;
          const valueWidth = value.length * 16;
          if (valueWidth > singleSeriesWidth) {
            if (valueWidth > 100) return value.slice(0, 6) + "...";
            if (singleSeriesWidth < 80) return value;
            const maxLength = Math.floor(singleSeriesWidth / 16);
            return value.slice(0, maxLength + 3) + "...";
          }
          return value;
        },
      },
    },
    series,
  };

  echartInstance.setOption(option);

  LabelMouseOver();
  ShowXAxisTooltip();

  // 绑定图例切换事件
  echartInstance.off("legendselectchanged");
  echartInstance.on("legendselectchanged", HandleLegendSelectChanged);

  // 窗口 resize 监听
  window.addEventListener("resize", handleResize);

  // 点击事件
  echartInstance.off("click");
  echartInstance.on("click", (params: any) => {
    if (params.seriesType === "bar") {
      const index = params.dataIndex;
      const name = params.name;
      emit("HandleChartClick", index, name);
    }
  });
}

/** 全选复选框切换 */
function ChangeCheckAll() {
  ToggleChangeAll(checkAll.value);
}
function ToggleChangeAll(show: boolean) {
  if (!props.showCheckBox || !echartInstance) return;
  const legendData = legenAllList.value;
  legendData.forEach((name) => {
    echartInstance?.dispatchAction({
      type: show ? "legendSelect" : "legendUnSelect",
      name,
    });
  });
  checkAll.value = show;
  isIndeterminate.value = false;
}

/** 图例切换回调 */
function HandleLegendSelectChanged(params: any) {
  const selected: Record<string, boolean> = params.selected;
  legendSelected.value = selected;
  const allKeys = legenAllList.value;
  const allSelected = allKeys.every((k) => selected[k]);
  const noneSelected = allKeys.every((k) => !selected[k]);
  const someSelected = !allSelected && !noneSelected;

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

  // 排序相关 emit
  if (props.showSortSelectbox) {
    const barLegendData =
      props.data[0]?.slice(1, props.showBarLegendIndex + 1) ?? [];
    const barSelectData = barLegendData.filter(
      (item) => selected[String(item)],
    );
    selectBarNum.value = barSelectData.length;
    if (selectBarNum.value > 1) {
      selectValue.value = "1";
    } else {
      const selectedVal = barLegendData.map((item) => selected[String(item)]);
      const selectedBarIndex = selectedVal.indexOf(true);
      const legendData = Object.keys(selected).filter((k) => selected[k]);
      emit("ChangeChartOrder", selectValue.value, legendData, selectedBarIndex);
    }
  }
}

/** 窗口大小节流 */
const handleResize = throttle(async () => {
  await nextTick();
  echartInstance?.resize();
}, 500);

/** 排序切换 */
function ChangeOrder(val: string) {
  selectValue.value = val;
  const barLegendData =
    props.data[0]?.slice(1, props.showBarLegendIndex + 1) ?? [];
  const barLegendVal = barLegendData.map(
    (item) => legendSelected.value[String(item)],
  );
  const selectedBarIndex = barLegendVal.indexOf(true);
  const legendData = Object.keys(legendSelected.value).filter(
    (k) => legendSelected.value[k],
  );
  emit("ChangeChartOrder", val, legendData, selectedBarIndex);
}
const ChangeSelectValue = () => {
  selectValue.value = "1";
};
// ==================== Watch ====================
watch(
  () => props.data,
  () => {
    if (props.showSortSelectbox) {
      const legenedList =
        props.data[0]?.slice(1, props.showBarLegendIndex + 1) ?? [];
      const barLegendList = legenedList.filter((item) =>
        props.legendList.includes(String(item)),
      );
      selectBarNum.value = barLegendList.length;
    }
    LoadEchart();
  },
  { deep: true },
);

// ==================== Lifecycle ====================
onMounted(() => {
  if (props.showSortSelectbox) {
    const legenedList =
      props.data[0]?.slice(1, props.showBarLegendIndex + 1) ?? [];
    const barLegendList = legenedList.filter((item) =>
      props.legendList.includes(String(item)),
    );
    selectBarNum.value = barLegendList.length;
    selectValue.value = "1";
  }
  LoadEchart();
});

onBeforeUnmount(() => {
  window.removeEventListener("resize", handleResize);
  disposeEchart();
  document
    .querySelectorAll("#tooltipContent, #x-axis-tooltip")
    .forEach((el) => el.remove());
});
defineExpose({
  ChangeSelectValue
});
</script>

<style lang="scss" scoped>
.echart_content {
  position: relative;
  width: 100%;
  margin: auto;
  min-height: 360px;
  height: auto;
  .is_show_all {
    position: absolute;
    top: -4px;
    left: 5px;
  }
}
.chart_width {
  width: 100%;
  height: 400px;
}
.title_right {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 10px;
  position: absolute;
  top: -5px;
  right: 0;
  z-index: 99;
  .right_item {
    font-size: 14px;
    color: #999;
    font-weight: 400;
    cursor: pointer;
    height: 30px;
    line-height: 32px;
    margin-right: 5px;
    border-bottom: 2px solid #ffffff;
  }
  .item_active {
    font-size: 14px;
    color: #2e64fa;
    font-weight: 500;
    cursor: pointer;
  }
}
</style>
