<template>
  <div class="echart_content" style="overflow: hidden;">
    <div class="is_show_all" v-if="props.showCheckBox">
      <el-checkbox v-model="allSeriesSelected" :indeterminate="isIndeterminate">
        显示全部
      </el-checkbox>
    </div>
    <!-- 雷达图 -->
    <div ref="radarChart" class="chart_box" :style="{ height: props.reportHeight || `${props.height}px` }"></div>
  </div>
</template>

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

// ================= 类型定义 =================
interface Props {
  showCheckBox?: boolean;
  height?: number;
  reportHeight?: number | string;
  showLegend?: boolean;
  legengAlign?: string;
  showTooltip?: boolean;
  showDataLabel?: boolean;
  unit?: string;
  legendList?: string[];
  legendLeft?: string;
  colorType?: string;
  color?: string[];
  data?: any[][];
  isClick?: boolean;
  showRadiusAxis?: boolean;
  fontSize?: number | string;
  fontColor?: string;
  legendWidth?: number | string;
}

// ================= Props & Emits =================
const props = withDefaults(defineProps<Props>(), {
  showCheckBox: true,
  height: 400,
  reportHeight: '',
  showLegend: true,
  legengAlign: '110px',
  showTooltip: true,
  showDataLabel: false,
  unit: '%',
  legendList: () => [],
  legendLeft: '110px',
  colorType: 'colors',
  color: () => [],
  data: () => [],
  isClick: false,
  showRadiusAxis: true,
  fontSize: '',
  fontColor: '',
  legendWidth: 'auto',
});

const emit = defineEmits<{
  (e: 'HandleChartClick', index: number, name: string): void;
}>();

// ================= 响应式数据 =================
const radarChart = ref<HTMLDivElement | null>(null);
let myChart: echarts.ECharts | null = null;

const allSeriesSelected = ref(false);
const isIndeterminate = ref(false);
const legendSelected = ref<Record<string, boolean>>({});
const legenSelectList = ref<string[]>([]);

// 常量数据
const gColors = getGGroupColor(); 
const colors = getScorePerformanceAnalysis();

// ================= 方法 =================
const initChart = () => {
  if (!radarChart.value || !props.data || props.data.length === 0) return;

  if (myChart) {
    myChart.dispose();
  }
  
  // 如果项目是全局挂载的 $echarts，可替换为 getCurrentInstance()?.appContext.config.globalProperties.$echarts
  myChart = echarts.init(radarChart.value, null, {
    devicePixelRatio: 2,
  });

  if (props.legendList && props.legendList.length > 0) {
    legenSelectList.value = props.legendList;
  } else {
    legenSelectList.value = props.data[0] ? props.data[0].slice(1) : [];
  }

  // 提取指示器数据
  const indicators = props.data.slice(1).map((row, index) => {
    const name = row[0];
    return {
      name: name,
      max: props.unit === '%' ? 100 : null,
      min: props.unit === '%' ? 0 : null,
      axisLabel: props.showRadiusAxis && index === 0 ? {
        show: true,
        formatter: (val: number) => `${val}${props.unit}`,
        fontSize: props.fontSize ? props.fontSize : 12,
        color: '#666'
      } : {
        show: false
      },
      color: props.isClick && index === 0 ? '#2e64fa' : (props.fontColor ? props.fontColor : '#666666'),
      nameTextStyle: { 
        fontSize: props.fontSize ? props.fontSize : 14, 
        fontWeight: props.isClick && index === 0 ? 'bold' : 'normal' 
      }
    };
  });

  // 提取图例数据
  const legendData = props.data[0] ? props.data[0].slice(1) : [];
  
  // 处理颜色
  let colorList: string[] = [];
  if (props.colorType === 'gColors') {
    colorList = legendData.map(item => {
      const gColor = gColors.find((gg: any) => gg.name === item);
      return gColor ? gColor.color : '#848BDC';
    });
  } else {
    colorList = props.color && props.color.length > 0 ? props.color : colors;
  }

  // 初始化 legendSelected
  legendSelected.value = legendData.reduce((acc: Record<string, boolean>, dim) => {
    acc[dim] = false;
    return acc;
  }, {});
  
  legenSelectList.value.forEach(item => {
    legendSelected.value[item] = true;
  });

  isIndeterminate.value = legenSelectList.value.length > 0 && legenSelectList.value.length < legendData.length;
  allSeriesSelected.value = legenSelectList.value.length === legendData.length;

  // 提取每个系列的数据
  const seriesData = legendData.map((grade, gradeIndex) => {
    const values = props.data.slice(1).map((row) => Number(row[gradeIndex + 1]));
    return {
      name: grade,
      value: values,
      label: {
        show: props.showDataLabel,
        position: 'outside',
        formatter: (params: any) => `${params.value}${props.unit}`
      }
    };
  });

  // 动态计算 max/min
  if (props.unit !== '%') {
    let maxValue = -Infinity;
    let minValue = Infinity;
    seriesData.forEach(item => {
      item.value.forEach(num => {
        if (num > maxValue) maxValue = num;
        if (num < minValue) minValue = num;
      });
    });
    indicators.forEach(item => {
      item.max = Math.ceil(maxValue);
      item.min = Math.floor(minValue);
    });
  }

  const option: echarts.EChartsOption = {
    emphasis: {
      blurScope: 'global'
    },
    legend: {
      show: props.showLegend,
      data: legendData,
      width: props.legendWidth,
      top:0,
      left: props.legendLeft,
      itemGap: 20,
      itemHeight: 10,
      itemWidth: 20,
      textStyle: { fontSize: 12, color: "#333" },
      icon: 'path://M352.64 526.336a158.272 158.272 0 0 0 2.56 17.664H96v-64h259.2a161.952 161.952 0 0 0-2.336 15.232A160 160 0 0 1 672 512a160.992 160.992 0 0 0-3.2-32H928v64h-259.2q1.12-5.504 1.824-11.104a160 160 0 0 1-318.016-6.4zM416 512a96 96 0 1 0 96-96 96 96 0 0 0-96 96z m254.72 20.224v-0.576z m-318.08-5.888v-1.664q-0.064 0.832 0 1.664z m-0.16-2.08v-1.248a5.44 5.44 0 0 0 0 1.248z m0-2.08v-0.928z m0-2.048zM352 518.08z m0-2.048zM352 512v-4.096V512z m0-5.344v-0.736 0.736z m0-2.56z m0.256-4.128z m0-1.664z m0-1.6v-0.992z',
      selectedMode: true,
      selected: legendSelected.value,
      type: 'scroll',
      pageButtonItemGap: 5,
      pageButtonPosition: 'end',
      orient: 'horizontal',
      alignTo: 'none',
      pageIconColor: '#999',
      pageIconInactiveColor: '#ccc',
    },
    tooltip: {
      show: props.showTooltip,
      triggerOn: "mousemove | click",
      renderMode: 'html',
      confine: true,
      extraCssText: 'border-radius: 4px;white-space:normal;word-warp:break-word;max-width: 400px;',
      enterable: true,
      formatter: (params: any) => {
        if (!myChart) return '';
        const chart = myChart.getOption();
        const indicator = (chart.radar as any)[0].indicator;
        let tooltipContent = `<div class='tooltip_content'>`;
        tooltipContent += `<div class='tooltip_title'>${params.name}</div>`;
        
        indicator.forEach((item: any, index: number) => {
          if (item.name) {
            tooltipContent += `<div class='tooltip_student'>${item.name}：${params.value[index]}${props.unit}</div>`;
          }
        });
        tooltipContent += `</div>`;
        return tooltipContent;
      },
    },
    color: colorList,
    radar: {
      indicator: indicators,
      shape: indicators.length < 3 ? 'circle' : '',
      splitNumber: 5,
      startAngle: 90,
      splitLine: { show: true },
      axisLabel: { show: false },
      splitArea: {
        show: true,
        areaStyle: {
          opacity: 0.1,
          color: ['#f0f8ff', '#e0f7fa', '#fff3e0', '#efebe9', '#f5f5f5']
        }
      },
      axisLine: {
        show: props.data.length < 3 ? false : true,
        lineStyle: { color: '#999' }
      },
      center: props.reportHeight ? ['50%', '50%'] : ['50%', '55%']
    },
    triggerEvent: true,
    series: [
      {
        type: "radar",
        symbol: 'circle',
        symbolSize: 7,
        data: seriesData,
        itemStyle: { opacity: 1 },
        emphasis: {
          symbol: 'none',
          focus: "self",
          itemStyle: { opacity: 1, borderWidth: 2 },
          areaStyle: { opacity: 0.1 }
        },
        blur: {
          symbol: 'none',
          itemStyle: { opacity: 0.2, color: 'red' },
          lineStyle: { opacity: 0.2 }
        },
      },
    ],
  };

  myChart.setOption(option);
  myChart.on("legendselectchanged", handleLegendSelectChanged);
  
  if (props.isClick) {
    bindChartNameEvents(indicators);
  }
};

const bindChartNameEvents = (indicators: any[]) => {
  if (!myChart) return;
  
  myChart.on('click', (params: any) => {
    if (params.componentType === 'radar' && params.targetType === 'axisName') {
      const name = params.name;
      const data = props.data.slice(1);
      const list = data.map(item => item[0]);
      const index = list.indexOf(name);
      
      const indicatorList = [...indicators];
      indicatorList.forEach((item, key) => {
        item.color = key === index ? '#2e64fa' : '#666666';
        item.nameTextStyle.fontWeight = key === index ? 'bold' : 'normal';
      });
      
      myChart?.setOption({
        radar: { indicator: indicatorList }
      });
      
      emit('HandleChartClick', index, name);
    }
  });
};

const handleLegendSelectChanged = (params: any) => {
  if (!myChart) return;
  const legendData = myChart.getOption().legend[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) allSeriesSelected.value = false;
  if (allSelected) allSeriesSelected.value = true;
  isIndeterminate.value = someSelected;
};

const resizeFn = () => {
  myChart?.resize();
};

const toggleChangeAll = (show: boolean) => {
  if (!props.showCheckBox || !myChart) return;
  const legendData = myChart.getOption().legend[0].data as string[];
  
  legendData.forEach((seriesName) => {
    myChart?.dispatchAction({
      type: show ? "legendSelect" : "legendUnSelect",
      name: seriesName,
    });
  });
  
  allSeriesSelected.value = show;
  isIndeterminate.value = false;
};

// ================= 监听器 =================
watch(allSeriesSelected, (newVal) => {
  toggleChangeAll(newVal);
});

watch(() => props.data, () => {
  initChart();
}, { deep: true });

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

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

<style lang="scss" scoped>
.echart_content {
  .is_show_all {
    top: -4px;
    left: 5px;
  }
}
</style>