<template>
  <div v-if="spinning" class="spinning">
    <a-spin :spinning="true" />
  </div>
  <div v-if="!spinning" ref="chartRef" :style="{ height, width }"></div>
</template>
<script lang="ts">
import { defineComponent, PropType, ref, Ref, reactive, watchEffect, watch, nextTick, onMounted } from 'vue';
import { useECharts } from '/@/hooks/web/useECharts';
import { getTableHeaderColumns } from '/@/hooks/web/useWebColumns';
import EchartsUtil from '/@/utils/echartsUtil';
import { merge } from 'lodash-es';
type ChartColumn = {
  legend: string;
  seriesName: string;
  ymax: number;
  yname: string;
  linetype: string;
  yaxispos: string;
  color: string;
  sort: number;
  xRotate: number;
  dataIndex: string;
};
type RegValueItem = {
  type: string;
  value: number | string;
  name: string;
  color: string;
  lineType: 'dashed' | 'solid';
};
export default defineComponent({
  name: 'BarAndLine',
  props: {
    chartsColumns: {
      type: Array as PropType<ChartColumn[]>,
      default: () => [],
    },
    chartsColumnsType: {
      type: String,
    },
    chartsType: {
      type: String,
      default: '',
    },
    dataSource: {
      type: Array,
      default: () => [],
    },
    option: {
      type: Object,
      default: () => ({}),
    },
    xAxisPropType: {
      type: String,
      required: true,
    },
    width: {
      type: String as PropType<string>,
      default: '100%',
    },
    height: {
      type: String as PropType<string>,
      default: 'calc(100vh - 78px)',
    },
    regValues: {
      type: Array as PropType<RegValueItem[]>,
      default: () => [],
    },
  },
  emits: ['refresh'],
  setup(props, { emit }) {
    const spinning = ref<boolean>(true);
    const chartRef = ref<HTMLDivElement | null>(null);
    const chartType = ref<string>('');
    const { setOptions, echarts } = useECharts(chartRef as Ref<HTMLDivElement>);
    const chartData = props.chartsColumnsType ? getTableHeaderColumns(props.chartsColumnsType) : [];
    let chartsColumns = (props.chartsColumns.length > 0 ? props.chartsColumns : chartData) as ChartColumn[];
    let tempYmax: number[] = [];
    let tempYmin: number[] = [];
    // let groupedByColumns = {};
    const option = reactive({
      name: '',
      color: ['#7B68EE', '#0000CD', '#6495ED', '#00BFFF', '#AFEEEE', '#008080', '#00FA9A', '#2E8B57', '#FAFAD2', '#DAA520'],
      tooltip: {},
      grid: {},
      toolbox: {
        feature: {
          saveAsImage: {
            iconStyle: {
              borderColor: '#ffffff',
            },
            show: false,
          },
        },
      },
      dataZoom: {},
      legend: {
        textStyle: {
          color: '#ffffff', // 字体颜色
        },
        top: '20',
      },
      timeline: null,
      xAxis: {},
      yAxis: null,
      series: null,
    });
    let optionUtil;
    onMounted(() => {
      // 组件挂载后强制初始化一次（兜底，避免监听漏触发）
      if (props.dataSource && props.regValues) {
        initCharts(true);
      }
    });
    watchEffect(() => {
      props.dataSource && props.xAxisPropType && option.series && initCharts();
    });
    watch([() => props.chartsType, () => props.chartsColumns], ([newChartsType, newChartsColumns]) => {
      spinning.value = true;
      chartsColumns = newChartsColumns;
      optionUtil.initChartOption(newChartsType, newChartsColumns);
      spinning.value = false;
      initCharts(true);
      emit('refresh');
    });
    watch(
      () => [props.regValues],
      (newVal) => {
        if (props.regValues && props.regValues.length > 0) {
          initCharts(true);
        }
        // 数据变化时重新渲染图表
      },
      { deep: true, immediate: true }
    );
    function initChartsOption() {
      // debugger;
      optionUtil = new EchartsUtil(merge(option, props.option));
      optionUtil.initChartOption(props.chartsType, chartsColumns);
    }
    initChartsOption();

    function initCharts(isRefresh = false) {
      if (props.dataSource.length < 1) return;
      //轴数据
      let isFresh = false;
      if (option.series && option.series.length === chartsColumns.length) {
        let xAxisData = props.dataSource.map((item) => item[props.xAxisPropType]);
        chartsColumns = [...chartsColumns].filter((propType: any, index) => {
          if (!propType) return;
          if (props.chartsType == 'listMonitor') {
            option.series[index].type = 'bar';
          }
          console.log(option.series[index], '000===');
          option.series[index].data = props.dataSource.map((item) => Number(item[propType.dataIndex]) || 0);
          if (props.regValues && props.regValues.length > 0) {
            // 筛选匹配的regValues
            const matchRegValues = props.regValues
              .filter((e) => propType.dataIndex == e.type) // 匹配当前dataIndex
              .filter((item) => {
                //过滤value为null
                if (item.value === null || item.value === undefined || item.value === '') return false;
                const numValue = Number(item.value);
                return !isNaN(numValue); // 确保是有效数字
              });
            if (matchRegValues.length > 0) {
              option.series[index].markLine = {
                lineStyle: { width: 4 },
                // 多个匹配项生成多条标线
                data: matchRegValues
                  .map((item, index) => [
                    {
                      yAxis: Number(item.value) ? Number(item.value) : 0,
                      xAxis: 0,
                      label: {
                        show: true,
                        position: 'end',
                        formatter: item.name,
                        color: '#fff',
                        fontSize: 14,
                        offset: [-80, 15],
                      },
                      lineStyle: {
                        color: item.color,
                        type: item.lineType,
                      },
                    },
                    {
                      yAxis: Number(item.value) ? Number(item.value) : 0,
                      xAxis: 'max',
                      label: {
                        show: true,
                        position: 'end',
                        formatter: item.value,
                        color: '#fff',
                        fontSize: 14,
                        offset: [-80, -10],
                      },
                      lineStyle: {
                        color: item.color,
                        type: item.lineType,
                        width: 4,
                      },
                    },
                  ])
                  .flat(),
              };
            }
          }
          // console.log('nnn', option.series[index].data);
          // 这里动态计算echarts y轴最大值
          const regValuesNum =
            props.regValues && props.regValues.length > 0
              ? props.regValues.filter((e) => propType.dataIndex == e.type).map((item) => Number(item.value) || 0)
              : [];
          const max = Math.max(...option.series[index].data, ...regValuesNum);
          const min = Math.min(...option.series[index].data, ...regValuesNum);
          const digitCount = Math.ceil(Number(max));
          const minDigitCount = Math.floor(Number(min));

          // if (props.chartsType === 'history') {
          //   const disLen = Math.abs(max - min);
          //   propType.ymax = digitCount + disLen / 3;
          //   propType.ymin = minDigitCount - disLen / 3 > 0 || minDigitCount < 0 ? minDigitCount - disLen / 3 : 0;
          // } else {
          //   let yMax = 0,
          //     yMin = 0;
          //   if (digitCount < 2) {
          //     if (max < 0.5) {
          //       yMax = 1;
          //     } else if (max < 0.9) {
          //       yMax = 1.5;
          //     } else if (max < 5) {
          //       yMax = 5;
          //     } else if (max < 10) {
          //       yMax = 10;
          //     }
          //   } else if (digitCount < 3) {
          //     const n = Number((Number(max.toFixed(0)) / 10).toFixed(0));
          //     if (max < n * 10 + 5) {
          //       yMax = (n + 1) * 10;
          //     } else {
          //       yMax = (n + 2) * 10;
          //     }
          //   } else if (digitCount < 4) {
          //     const n = Number((Number(max.toFixed(0)) / 100).toFixed(0));
          //     if (max < n * 100 + 50) {
          //       yMax = (n + 1) * 100;
          //     } else {
          //       yMax = (n + 2) * 100;
          //     }
          //   } else if (digitCount < 5) {
          //     const n = Number((Number(max.toFixed(0)) / 1000).toFixed(0));
          //     if (max < n * 1000 + 500) {
          //       yMax = (n + 1) * 1000;
          //     } else {
          //       yMax = (n + 1) * 1000 + 500;
          //     }
          //   } else if (digitCount < 6) {
          //     const n = Number((Number(max.toFixed(0)) / 10000).toFixed(0));
          //     if (max < n * 10000 + 5000) {
          //       yMax = (n + 1) * 10000;
          //     } else {
          //       yMax = (n + 1) * 10000 + 5000;
          //     }
          //   }

          //   if (minDigitCount < 2) {
          //     if (min > 1.5) {
          //       yMin = 1.0;
          //     } else if (min > 5) {
          //       yMin = 5;
          //     } else {
          //       yMin = 0;
          //     }
          //   } else if (minDigitCount < 3) {
          //     const n = Number((Number(min.toFixed(0)) / 10).toFixed(0));
          //     if (n > 1) {
          //       yMin = (n - 1) * 10;
          //     } else {
          //       yMin = 10;
          //     }
          //   } else if (digitCount < 4) {
          //     const n = Number((Number(min.toFixed(0)) / 100).toFixed(0));
          //     if (n > 1) {
          //       yMin = (n - 1) * 100;
          //     } else {
          //       yMin = 100;
          //     }
          //   } else if (digitCount < 5) {
          //     const n = Number((Number(min.toFixed(0)) / 1000).toFixed(0));
          //     if (n > 1) {
          //       yMin = (n - 1) * 1000;
          //     } else {
          //       yMin = 1000;
          //     }
          //   } else if (digitCount < 6) {
          //     const n = Number((Number(min.toFixed(0)) / 10000).toFixed(0));
          //     if (n > 1) {
          //       yMin = (n - 1) * 10000;
          //     } else {
          //       yMin = 10000;
          //     }
          //   }

          //   propType.ymax = yMax;
          //   propType.ymin = yMin;
          // }
          const disLen = Math.abs(max - min);
          if (propType.ymax && propType.ymin >= 0) {
            if (max > propType.ymax || min < propType.ymin) {
              propType.ymax = digitCount + disLen / 3;
              propType.ymin = minDigitCount - disLen / 3 > 0 || minDigitCount < 0 ? minDigitCount - disLen / 3 : 0;
            } else {
              propType.ymax = digitCount + digitCount / 4;
              propType.ymin = minDigitCount - digitCount / 4;
            }
          } else {
            propType.ymax = digitCount + disLen / 3;
            propType.ymin = minDigitCount - disLen / 3 > 0 || minDigitCount < 0 ? minDigitCount - disLen / 3 : 0;
          }
          if (propType.ymax == propType.ymin && propType.ymin == 0) {
            propType.ymax = 10;
          }

          return true;
        });
        // debugger;
        // 根据sort分组
        const groupedBy = {};
        for (const item of chartsColumns) {
          if (groupedBy[item.sort]) {
            groupedBy[item.sort].push(item);
          } else {
            groupedBy[item.sort] = [item];
          }
        }
        // 根据分组找ymax最大值
        const newChartsColumns: ChartColumn[] = [];
        let index = 0;
        for (let sortId in groupedBy) {
          const group = groupedBy[sortId];
          let ymax = group[0].ymax;
          let ymin = group[0].ymin;
          for (let i = 1; i < group.length; i++) {
            if (group[i].ymax > ymax) {
              ymax = group[i].ymax;
            }
          }
          for (let i = 1; i < group.length; i++) {
            if (group[i].ymin < ymin) {
              ymin = group[i].ymin;
            }
          }
          if (!tempYmax[index] || tempYmax[index] < ymax) {
            tempYmax[index] = ymax;
            isFresh = true;
          }
          if (tempYmin[index] > ymin) {
            tempYmin[index] = ymin;
            isFresh = true;
          }
          for (let i = 0; i < group.length; i++) {
            group[i].ymax = ymax;
            group[i].ymin = ymin;
            newChartsColumns.push(group[i]);
          }
          ++index;
        }
        chartsColumns = newChartsColumns;
        option.xAxis[0].data = xAxisData;
        if (isFresh) {
          spinning.value = true;
          optionUtil.initChartOption(props.chartsType, chartsColumns);
          spinning.value = false;
          initCharts(true);
          nextTick(() => {
            setOptions(option, true);
            emit('refresh');
          });
        } else {
          // console.log('echarts监测列表数据', option.xAxis[0].data);
          setOptions(option, isRefresh);
        }
        setOptions(option, isRefresh);
      }
    }
    setTimeout(() => {
      spinning.value = false;
      initCharts(true);
    }, 1000);
    return { chartRef, spinning };
  },
});
</script>
<style lang="less" scoped>
.spinning {
  display: flex;
  width: 100%;
  height: 100%;
  justify-content: center;
  align-items: center;
}
</style>
