<script setup lang="ts">
import * as echarts from 'echarts/core';
import { BarChart, BarSeriesOption } from 'echarts/charts';
import {
  TitleComponent,
  // 组件类型的定义后缀都为 ComponentOption
  TitleComponentOption,
  TooltipComponent,
  TooltipComponentOption,
  GridComponent,
  GridComponentOption,
  LegendComponent,
  // 数据集组件
  DatasetComponent,
  DatasetComponentOption,
  // 内置数据转换器组件 (filter, sort)
  TransformComponent,
} from 'echarts/components';
import { LabelLayout, UniversalTransition } from 'echarts/features';
import { CanvasRenderer } from 'echarts/renderers';
import { onMounted, PropType, watch, ref, computed } from 'vue';
import { IDiskCharts } from '@/model/System/monitor-interface';
import { visualMapLineColor, colors } from '@/model/colors';
import { initLeftDistance } from '@/pages/System/Monitor/monitorFunctions';
import { traduction } from '@/utils/language';
import mixins from '@/utils/watchSwitch';
import { getRealColor, getThemeMode } from '@/utils/utils';
import useStore from '@/stores';

// 通过 ComposeOption 来组合出一个只有必须组件和图表的 Option 类型
type ECOption = echarts.ComposeOption<
| BarSeriesOption
| TitleComponentOption
| TooltipComponentOption
| GridComponentOption
| DatasetComponentOption
>;

// 注册必须的组件
echarts.use([
  TitleComponent,
  TooltipComponent,
  GridComponent,
  DatasetComponent,
  TransformComponent,
  BarChart,
  LabelLayout,
  UniversalTransition,
  CanvasRenderer,
  LegendComponent,
]);

let { componentIsShowing } = mixins();

const barWidth = 8;
const fomatterTitle = traduction('MONITOR_USAGE');
const usedFomatterTitle = traduction('MOINTOR_HAS_USED');
const totalFomatterTitle = traduction('MOINTOR_TOTAL_SYSTEM_MEMORY_GIB');
const chartDom = ref();
let myChart: any = null;

const props = defineProps({
  title: {
    type: String,
    default: '',
    required: true,
  },
  chartsData: {
    type: Array as PropType<IDiskCharts[]>,
    default: () => [],
    required: true,
  },
  thresholdPercent: {
    type: Number,
    default: 0,
    required: true,
  },
});

const watchArr = [() => props.chartsData, () => props.thresholdPercent];

watch(watchArr, () => {
  if (componentIsShowing.value) {
    networkCharts();
  }
});

const store = useStore();
const systemTheme = computed(() => {
  return store.state.loct.systemTheme;
});

watch(systemTheme, () => {
  if (componentIsShowing.value) {
    networkCharts();
  }
});

function getSeriesItem(shadowColor: string, showData: any) {
  return {
    type: 'bar',
    stack: 'Total',
    barWidth: barWidth,
    itemStyle: {
      shadowColor: shadowColor,
      shadowBlur: 10,
      shadowOffsetX: 2,
      shadowOffsetY: 2,
    },
    emphasis: {
      focus: 'series',
    },
    markLine: {},
    data: showData,
  };
}

function changMarkLine(seriesItem: any, thresholdPercent: any) {
  seriesItem.markLine = {
    silent: true,
    symbol: 'none',
    emphasis: {
      // 因为只有一根markline，所以鼠标移动到除了第一根柱子外的柱子的时候会导致markline淡化，通过此属性设置markline不参与高亮变化
      disabled: true,
    },
    lineStyle: {
      width: 1,
      color: visualMapLineColor,
    },
    label: {
      show: true,
      position: 'start',
      distance: [initLeftDistance(String(thresholdPercent).length), 0],
      color: visualMapLineColor,
      fontSize: 16,
      fontWeight: '500',
    },
    data: [
      {
        type: 'now',
        yAxis: thresholdPercent,
        symbol: 'none',
      },
    ],
  };
}

/* eslint-disable-next-line max-lines-per-function*/
function getToolTip(
  chartsData: any,
  thresholdPercent: any,
  beyondColor: any,
  heleathColor: any,
): any {
  const tipBgColor = getThemeMode() === 'light' ? '#FFF' : '#2A2F37';
  return {
    trigger: 'axis',
    axisPointer: {
      type: '',
    },
    backgroundColor: tipBgColor,
    borderColor: tipBgColor,
    formatter(param: any) {
      const item = chartsData.find((e: any) => {
        return e.PartitionName === param[0].name;
      });
      let res = '';
      if (item) {
        const { UsedGB, CapacityGB, usagePercent } = item;
        const usedItemColor = usagePercent > thresholdPercent ? beyondColor : heleathColor;
        res = `<div class="formatter-box">
                    <div class="formatter-part-key">
                      <div class="key">
                        <span class="block" style="background:${usedItemColor}"></span>
                        ${fomatterTitle}
                      </div>
                      <div class="key">
                        ${usedFomatterTitle}
                      </div>
                      <div class="key">
                        ${totalFomatterTitle}
                      </div>
                    </div>
                    <div class="formatter-part-value">
                      <div class="value">
                        ${usagePercent}%
                      </div>
                      <div class="value">
                        ${UsedGB}GB
                      </div>
                      <div class="value">
                        ${CapacityGB}GB
                      </div>
                    </div>
                  </div>`;
      }
      return res;
    },
  };
}

function getTitle(): any {
  return {
    text: props.title,
    textStyle: {
      color: getRealColor('--o-text-color-secondary'),
      fontWeight: 'normal',
      fontSize: '12px',
      fontFamily: 'HarmonyOS Sans SC Medium',
    },
    left: '-5px',
    top: '-4px',
  };
}

function getGrid() {
  return {
    borderWidth: 0,
    containLabel: true,
    left: 12,
    top: props.title ? 36 : 12,
    right: 0,
    bottom: 0,
  };
}

function getXaxis(partitionNameList: any): any {
  return {
    type: 'category',
    data: partitionNameList,
    axisLine: {
      show: true,
      lineStyle: {
        width: 1,
        type: 'solid',
        color: getRealColor('--o-border-color-light'),
      },
    },
    axisTick: {
      show: false,
    },
    axisLabel: {
      margin: 10,
      color: getRealColor('--o-text-color-tertiary'),
      fontSize: 12,
      // 坐标轴刻度标签的显示间隔
      interval: 0,
    },
  };
}

function getYaxis(): any {
  return {
    type: 'value',
    splitLine: {
      lineStyle: {
        type: 'dashed',
        color: getRealColor('--o-border-color-base'),
      },
    },
    axisLabel: {
      margin: 8,
      textStyle: {
        align: 'right',
        verticalAlign: 'middle',
        color: getRealColor('--o-text-color-tertiary'),
        fontSize: 12,
      },
      // 刚好是门限值的刻度不显示,这样门限值的数值就不会与刻度值重叠
      formatter: (value: any, index: any) => {
        if (props.thresholdPercent === value) {
          return '';
        }
        return value;
      },
    },
  };
}

function getDataList(chartsData: any, partitionNameList: any, dataList: any) {
  chartsData.forEach((item: any) => {
    const { PartitionName, UsedGB, CapacityGB } = item;
    partitionNameList.push(PartitionName);
    const num = Number(((UsedGB / CapacityGB) * 100).toFixed(2));
    item.usagePercent = num;
    dataList.push(num);
  });
}

function getSeries(config: any) {
  const {
    dataList,
    thresholdPercent,
    beyondColor,
    heleathColor,
    beyondShadowColor,
    heleathShadowColor,
    series,
    showColors,
  } = config;
  for (let i = 0; i < dataList.length; i++) {
    const usedItemColor = dataList[i] > thresholdPercent ? beyondColor : heleathColor;
    const shadowColor = dataList[i] > thresholdPercent ? beyondShadowColor : heleathShadowColor;
    showColors.push(usedItemColor);

    let showData = [];
    for (let j = 0; j < dataList.length; j++) {
      showData[j] = 0;
    }
    showData[i] = dataList[i];

    let seriesItem = getSeriesItem(shadowColor, showData);

    // 控制只绘制一根markLine
    if (i === 0) {
      changMarkLine(seriesItem, thresholdPercent);
    }

    series.push(seriesItem);
  }
}

function networkCharts(): void {
  const { chartsData, thresholdPercent } = props;
  let partitionNameList: string[] = [];
  let dataList: number[] = [];
  if (chartsData) {
    getDataList(chartsData, partitionNameList, dataList);

    const { heleathColor, heleathShadowColor, beyondColor, beyondShadowColor } =
      colors.heleathAndBeyondColors;
    let series: any = [];
    let showColors: any = [];
    getSeries({
      dataList,
      thresholdPercent,
      beyondColor,
      heleathColor,
      beyondShadowColor,
      heleathShadowColor,
      series,
      showColors,
    });

    const option: ECOption = {
      title: getTitle(),
      tooltip: getToolTip(chartsData, thresholdPercent, beyondColor, heleathColor),
      legend: {},
      grid: getGrid(),
      xAxis: getXaxis(partitionNameList),
      yAxis: getYaxis(),
      color: showColors,

      /**
       * 当前是结合其emphasis.focus为series的时候，根据其功能特性进行数据的重新组装
       */
      series: series,
    };

    if (myChart) {
      myChart.clear();
      myChart.setOption(option, true);
    } else {
      myChart = echarts.init(chartDom.value);
      myChart.setOption(option, true);
    }
  }
}

onMounted(() => {
  networkCharts();
});
</script>

<template>
  <div ref="chartDom" class="chart"></div>
</template>

<style scoped lang="scss">
.chart {
  height: 240px;

  :deep(.formatter-box) {
    display: flex;
    padding: 0 5px;

    .formatter-part-key {
      margin-right: 8px;

      .key {
        font-size: 12px;
        color: var(--o-text-color-secondary);
        display: flex;
        align-items: center;
        line-height: 24px;

        .block {
          margin-right: 8px;
          display: inline-block;
          width: 12px;
          height: 12px;
        }
      }
    }

    .formatter-part-value {
      .value {
        font-size: 16px;
        color: var(--o-text-color-primary);
        text-align: right;
        line-height: 24px;
      }
    }
  }
}
</style>
