<script setup lang="ts">
import { checkPrivil } from '@/apps/app-bmc/router/routes';
import '@/assets/common/style/echarts-formatter-style/index.scss';
import Editor from '@/components/Editor/Editor.vue';
import SingleLineFailurePrompt from '@/components/SingleLineFailurePrompt/SingleLineFailurePrompt.vue';
import TableNoData from '@/components/TableNoData/TableNoData.vue';
import { UserPrivil, SeriesName } from '@/model/base-enum';
import { IconDate, IconDelete, IconDownload } from '@computing/opendesign-icons';
import { downloadFileWithResponse } from '@/utils/common-service';
import { loading } from '@/utils/composition';
import Date from '@/utils/date';
import { traduction } from '@/utils/language';
import { showElMessage } from '@/utils/utils';
import { rangeVerification } from '@/validators/validation-functions';
import { AxiosResponse } from 'axios';
import { LineChart } from 'echarts/charts';
import {
  GridComponent,
  LegendComponent,
  MarkLineComponent,
  TooltipComponent,
  VisualMapComponent,
} from 'echarts/components';
import * as echarts from 'echarts/core';
import { UniversalTransition } from 'echarts/features';
import { CanvasRenderer } from 'echarts/renderers';
import {computed, onMounted, reactive, ref, shallowRef, toRefs, watch, nextTick } from 'vue';
import { useI18n } from 'vue-i18n';
import useStore from '@/stores';
import { IPowerHistoryData } from '@/model/System/power-interface';
import {
  clearHistoryData,
  downloadData,
  downLoadHistory,
  queryProgress,
  setPower,
} from '../../services/power.services';
import { W_TO_BTU_COEFF, wattstoBTUs } from '../../utils/common';
import Download from './Download.vue';
import { EChartsType } from 'echarts/core';

echarts.use([
  TooltipComponent,
  GridComponent,
  VisualMapComponent,
  LineChart,
  CanvasRenderer,
  UniversalTransition,
  MarkLineComponent,
  LegendComponent,
]);

const FIXED_LABEL_WIDTH = 100;
const AXIS_LABEL_MARGIN = 15;

const store = useStore();
const isSystemLock = computed(() => {
  return store.state.glob.systemLocked;
});
const isPrivileges = checkPrivil(UserPrivil.powerControl);
const isDownning = ref(false);
const delDialogRef = ref();
const cappingCharts = ref();
let initCharts: EChartsType | null = null;
const showCharts = ref(true);
const dummyCncRef = ref<{ canvas: HTMLCanvasElement, context: CanvasRenderingContext2D } | null>(null);
const leftMarginRef = ref(0);
const leftPaddingMap = ref<Map<SeriesName, number>>(new Map([
  [SeriesName.AVG, FIXED_LABEL_WIDTH],
  [SeriesName.PEAK, FIXED_LABEL_WIDTH],
  [SeriesName.WATTS, FIXED_LABEL_WIDTH],
]));

const props = defineProps({
  data: {
    required: true,
    type: Object,
    default: () => {
      return {};
    },
  },
  activeUnit: {
    required: true,
    type: String,
    default: 'W',
  },
  type: {
    required: true,
    type: String,
    default: 'System',
  },
  showWarnLimit: {
    required: false,
    type: Boolean,
    default: () => false,
  },
  hostNumber: {
    required: false,
    type: String,
    default: () => '',
  },
});

const i18n = useI18n();
const langOptions = computed(() => {
  return store.state.glob.langOptions;
});
const curLang = langOptions.value.filter((lang: any) => lang.id === i18n.locale.value)[0].label;

const gridLeftAndLegendSetting = [
  {
    // 语种
    label: 'English',
    // 单位选W、有线展示时图表左边距
    wLeft: '16px',
    // 单位选W、无线展示时图表左边距
    noLineWLeft: '38px',
    // 单位选BTU、有线展示时图表左边距
    btuLeft: '19px',
    // 单位选BTU、无线展示时图表左边距
    noLineBtuLeft: '48px',
    // 单位选W时legend的left值
    wLegendLeft: 100,
    // 单位选BTU时legend的left值
    btuLegendLeft: 128,
  },
  {
    label: '简体中文',
    wLeft: '16px',
    noLineWLeft: '38px',
    btuLeft: '24px',
    noLineBtuLeft: '53px',
    wLegendLeft: 98,
    btuLegendLeft: 128,
  },
  {
    label: '日本語',
    wLeft: '16px',
    noLineWLeft: '38px',
    btuLeft: '34px',
    noLineBtuLeft: '53px',
    wLegendLeft: 98,
    btuLegendLeft: 150,
  },
  {
    label: 'Français',
    wLeft: '18px',
    noLineWLeft: '40px',
    btuLeft: '34px',
    noLineBtuLeft: '96px',
    wLegendLeft: 118,
    btuLegendLeft: 150,
  },
  {
    label: 'Русский',
    wLeft: '20px',
    noLineWLeft: '43px',
    btuLeft: '34px',
    noLineBtuLeft: '53px',
    wLegendLeft: 118,
    btuLegendLeft: 150,
  },
];

const gridLeftSettingItem = gridLeftAndLegendSetting.find(item => item.label === curLang);
const isWUnit = computed(() => props.activeUnit === 'W');

const delConfig = reactive({
  content: traduction('COMMON_ASK_OK'),
});

function showMessage() {
  if (isSystemLock.value) {
    return;
  }
  delDialogRef.value.show();
}

function closeModal(reason: boolean) {
  if (reason) {
    clearHistory();
  }
  delDialogRef.value.hide();
}

const { data } = toRefs(props);
const unit = ref('W');
const yAxis = ref(
  unit.value === 'W'
    ? traduction('OTHER_POWER')
    : traduction('HOME_POWERW').split('\n')[1] + '(BTU/h)',
);
const highPowerThresholdWatts = ref(0);
let oldHighPowerThresholdWatts = 0;
let powerHistoryData = data?.value?.powerHistoryData;
const searchDataValue = ref([]);
const powerInfo = reactive({
  statisticsCollected: '',
  segmentedPeakPower: null,
});
const powerHistoryChartsData: IPowerHistoryData = reactive({
  powerPeakWattsList: [],
  powerAverageWattsList: [],
  powerWattsList: [],
  timeList: [],
  timeListLen: null,
  start: '',
  end: '',
});

const searchDataMin = ref('');
const searchDataMax = ref('');
const maxLimitInWatts = ref(0);

function init() {
  maxLimitInWatts.value = data?.value.maxLimitInWatts;
  threshold.validationWRules.max = maxLimitInWatts.value as any;
  threshold.validationBTURules.max = ((maxLimitInWatts.value as any) / W_TO_BTU_COEFF).toFixed(1);
  threshold.popoverWSetting.popoverSlotSetting.data = traduction('VALIDTOR_INTER_INTGER_RANGE', [
    1,
    maxLimitInWatts.value,
  ]);
  threshold.popoverWSetting.content = traduction('VALIDTOR_INTGER_RANGE', [
    1,
    maxLimitInWatts.value,
  ]);
  threshold.popoverBTUSetting.popoverSlotSetting.data = traduction('VALID_VALUE_RANGE_TIP', [
    minPowerValue.value,
    ((maxLimitInWatts.value as any) / W_TO_BTU_COEFF).toFixed(1),
  ]);
  threshold.popoverBTUSetting.content = traduction('VALID_VALUE_RANGE_TIP', [
    minPowerValue.value,
    ((maxLimitInWatts.value as any) / W_TO_BTU_COEFF).toFixed(1),
  ]);
  for (let key in powerHistoryChartsData) {
    if ({}.hasOwnProperty.call(powerHistoryChartsData, key)) {
      powerHistoryChartsData[key] = powerHistoryData[key];
    }
  }
  const timeListSource = powerHistoryChartsData.timeList;
  // 一天中有144个十分钟，多于一天的数据量最多选择一天
  const defaultCount = 144;
  if (timeListSource.length > defaultCount) {
    const len = timeListSource.length - defaultCount;
    powerHistoryChartsData.timeList = powerHistoryData.timeList.slice(len);
    powerHistoryChartsData.powerPeakWattsList = powerHistoryData.powerPeakWattsList.slice(len);
    powerHistoryChartsData.powerWattsList = powerHistoryData.powerWattsList.slice(len);
    powerHistoryChartsData.powerAverageWattsList =
      powerHistoryData.powerAverageWattsList.slice(len);
  } else {
    powerHistoryChartsData.timeList = timeListSource;
  }
  if (timeListSource.length) {
    const min = timeListSource[0].split(' ')[0] + ' 00:00:00';
    const max = timeListSource[timeListSource.length - 1].split(' ')[0] + ' 23:59:59';
    searchDataMin.value = new Date(min);
    searchDataMax.value = new Date(max);
    (searchDataValue.value as string[]) = [
      new Date(powerHistoryChartsData.timeList[0]),
      new Date(powerHistoryChartsData.timeList[powerHistoryChartsData.timeList.length - 1]),
    ];
  }
}

// 默认选择时间
const dateTimePicker = reactive({
  searchDataOK: () => {
    const beginTime = new Date(searchDataValue.value[0]).pattern('yyyy/MM/dd HH:mm');
    const endTime = new Date(searchDataValue.value[1]).pattern('yyyy/MM/dd HH:mm');
    const beginTimeBadged = getBeginTime(beginTime);
    const endTimeBadged = getEndTime(endTime);
    if (beginTimeBadged > -1 && endTimeBadged > -1 && endTimeBadged >= beginTimeBadged) {
      powerHistoryChartsData.timeList = powerHistoryData.timeList.slice(
        beginTimeBadged,
        endTimeBadged + 1,
      );
      powerHistoryChartsData.powerAverageWattsList = powerHistoryData.powerAverageWattsList.slice(
        beginTimeBadged,
        endTimeBadged + 1,
      );
      powerHistoryChartsData.powerPeakWattsList = powerHistoryData.powerPeakWattsList.slice(
        beginTimeBadged,
        endTimeBadged + 1,
      );
      powerHistoryChartsData.powerWattsList = powerHistoryData.powerWattsList.slice(
        beginTimeBadged,
        endTimeBadged + 1,
      );
      powerHistoryChartsData.timeListLen = powerHistoryChartsData.timeList.length;
      showCharts.value = true;
      nextTick(() => {
        chartResize();
      });
    } else {
      powerInfo.segmentedPeakPower = null;
      powerInfo.statisticsCollected = '--';
      showCharts.value = false;
    }
  },
  disabledDate: (time: any) => {
    return time < searchDataMin.value || time > searchDataMax.value;
  },
});

function reg(rule: any, valParams: string | number, callback: any) {
  let val = valParams;
  const { max, min, message, required, isInteger } = rule;
  // 为空校验
  if (required && !val && val !== 0) {
    callback(new Error(message));
    return false;
  }
  if (val || val === 0) {
    // 输入的要是数字字符串 或者 数字
    const reg1 = /^[+-]?(0|([1-9]\d*))(\.\d+)?$/;
    const reg0 = /^((\d+)|(\d+\.\d))$/;
    if (!reg0.test(String(val))) {
      callback(new Error(message));
      return false;
    }
    if (!reg1.test(String(val))) {
      callback(new Error(message));
      return false;
    }

    // 判断是否是整数
    if (isInteger && (String(val)).indexOf('.') >= 0) {
      callback(new Error(message));
      return false;
    }

    val = Number(val);

    if (!rangeVerificationOfMinMax({ max, min, val, callback, message })) {
      return false;
    }
  }
  callback();
  return true;
}
// 数字区间校验-最大值-最小值
function rangeVerificationOfMinMax(actions: any) {
  const { max, min, val, callback, message } = actions;
  // 最小值
  if ((min || min === 0) && val < min) {
    callback(new Error(message));
    return false;
  }
  // 最大值
  if ((max || max === 0) && val > max) {
    callback(new Error(message));
    return false;
  }
  return true;
}

// 门限值编辑
const threshold = reactive({
  validationWRules: {
    required: true,
    min: 1,
    max: null,
    isInteger: true,
    trigger: 'change',
    validator: (vRule: any, value: any, callback: any) => {
      const res = rangeVerification(vRule, value, callback);
      if (res) {
        threshold.popoverWSetting.type = 'ordinary';
      } else {
        threshold.popoverWSetting.type = 'complex';
      }
    },
  },
  validationBTURules: {
    required: true,
    min: 1,
    max: '',
    isInteger: false,
    trigger: 'change',
    validator: (vRule: any, value: any, callback: any) => {
      const reg0 = /^((\d+)|(\d+\.\d))$/;
      let res = reg(vRule, value, callback) && rangeVerification(vRule, value, callback);

      if (!rangeVerification(vRule, value, callback)) {
        threshold.popoverBTUSetting.content = traduction('VALID_VALUE_RANGE_TIP', [
          minPowerValue.value,
          ((maxLimitInWatts.value as any) / W_TO_BTU_COEFF).toFixed(1),
        ]);
        threshold.popoverBTUSetting.popoverSlotSetting.data = traduction('VALID_VALUE_RANGE_TIP', [
          minPowerValue.value,
          ((maxLimitInWatts.value as any) / W_TO_BTU_COEFF).toFixed(1),
        ]);
      } else if (!reg(vRule, value, callback)) {
        threshold.popoverBTUSetting.content = traduction('VALID_OUT_DECIMAL_PPOINT');
        threshold.popoverBTUSetting.popoverSlotSetting.data = traduction(
          'VALID_OUT_DECIMAL_PPOINT',
        );
      } else {
        threshold.popoverBTUSetting.content = traduction('VALID_VALUE_RANGE_TIP', [
          minPowerValue.value,
          ((maxLimitInWatts.value as any) / W_TO_BTU_COEFF).toFixed(1),
        ]);
        threshold.popoverBTUSetting.popoverSlotSetting.data = traduction('VALID_VALUE_RANGE_TIP', [
          minPowerValue.value,
          ((maxLimitInWatts.value as any) / W_TO_BTU_COEFF).toFixed(1),
        ]);
      }
      if (res) {
        threshold.popoverBTUSetting.type = 'ordinary';
        return true;
      } else {
        threshold.popoverBTUSetting.type = 'complex';
        return false;
      }
    },
  },
  popoverWSetting: {
    show: true,
    type: 'ordinary',
    popoverSlotSetting: {
      component: shallowRef(SingleLineFailurePrompt),
      data: '',
    },
    width: 'auto',
    popperClass: 'no-wrap-popover',
    content: '',
    placement: 'top',
    trigger: 'focus',
  },
  popoverBTUSetting: {
    show: true,
    type: 'ordinary',
    popoverSlotSetting: {
      component: shallowRef(SingleLineFailurePrompt),
      data: '',
    },
    width: 'auto',
    popperClass: 'no-wrap-popover',
    content: '',
    placement: 'top',
    trigger: 'focus',
  },
  editor: () => {
    oldHighPowerThresholdWatts = highPowerThresholdWatts.value;
  },
  cancel: () => {
    highPowerThresholdWatts.value = oldHighPowerThresholdWatts;
  },
  confirm: (value: number) => {
    let currentThresholdWatts = Number(value);
    if (currentThresholdWatts && unit.value !== 'W') {
      currentThresholdWatts = Math.ceil(currentThresholdWatts * W_TO_BTU_COEFF);
    }
    const param: { HighPowerThresholdWatts: number } = {
      HighPowerThresholdWatts: currentThresholdWatts,
    };
    setPower(param)
      .then(res => {
        highPowerThresholdWatts.value = Number(value);
        thresholdChange();
        showElMessage('success', traduction('COMMON_SUCCESS'));
      })
      .catch(error => {
        showElMessage('error', traduction('COMMON_FAILED'));
      });
  },
});

const minPowerValue = computed(() => {
  if (unit.value === 'W') {
    threshold.validationBTURules.min = 1;
    return 1;
  } else {
    threshold.validationBTURules.min = wattstoBTUs(1);
    return wattstoBTUs(1);
  }
});

const emits = defineEmits(['thresholdChange', 'clear']);

function thresholdChange() {
  emits('thresholdChange', highPowerThresholdWatts.value);
}

// 获取开始时间
function getBeginTime(startTime: any): any {
  const dataRange = powerHistoryData.timeList;
  if (!dataRange.length) {
    return -1;
  }
  const startCount = dataRange.indexOf(startTime);
  if (startCount < 0) {
    let time = new Date(startTime).getTime();
    time = time + (60 * 1000);
    const arr0 = new Date(dataRange[dataRange.length - 1]).getTime();
    if (time > arr0) {
      return -1;
    } else {
      const _time = new Date(time).pattern('yyyy/MM/dd HH:mm');
      return getBeginTime(_time);
    }
  } else {
    return startCount;
  }
}
// 获取结束时间
function getEndTime(endTime: any): any {
  const dataRange = powerHistoryData.timeList;
  if (!dataRange.length) {
    return -1;
  }
  const endCount = dataRange.lastIndexOf(endTime);
  if (endCount < 0) {
    let time = new Date(endTime).getTime();
    time = time - (60 * 1000);
    const arr0 = new Date(dataRange[0]).getTime();
    if (time < arr0) {
      return -1;
    } else {
      const _time = new Date(time).pattern('yyyy/MM/dd HH:mm');
      return getEndTime(_time);
    }
  } else {
    return endCount;
  }
}

function timeArr(timeArray: any) {
  let arr = [];
  if (timeArray.length === 1) {
    arr = timeArray;
  } else {
    arr = timeArray.map((item: any) => {
      const time = new Date(item);
      const _time =
      time.getTime() - ((time.getMinutes() % 10) * 60 * 1000) - (time.getSeconds() * 1000);
      return _time;
    });
  }
}

function generateXLabels(timeArray: any) {
  let interval = 0;
  const start = new Date(timeArray[timeArray.length - 1]).getTime();
  const end = new Date(timeArray[0]).getTime();
  const len = Math.ceil((start - end) / 600000);
  switch (true) {
    case len < 11:
      // 10分钟
      interval = 600 * 1000;
      return interval;
    case len < 16:
      // 15分钟
      interval = 900 * 1000;
      return interval;
    case len < 31:
      // 30分钟
      interval = 1800 * 1000;
      return interval;
    case len < 61:
      // 1个小时
      interval = 3600 * 1000;
      return interval;
    case len < 121:
      // 2个小时
      interval = 2 * 3600 * 1000;
      return interval;
    case len < 361:
      // 6个小时
      interval = 6 * 3600 * 1000;
      return interval;
    case len < 721:
      // 12个小时
      interval = 12 * 3600 * 1000;
      return interval;
    case len < 1009:
      // 24个小时
      interval = 24 * 3600 * 1000;
      return interval;
    default:
      interval = Math.ceil((start - end) / 9);
      return interval;
  }
}

function getTooltip() {
  return {
    trigger: 'axis',
    backgroundColor: '#fff',
    textStyle: {
      color: 'rgba(27, 25, 25, 1)',
      lineHeight: 28,
    },
    extraCssText: 'box-shadow: 0 4px 8px 0 rgba(0,0,0,0.20)',
    padding: [12, 16, 12, 16],
    borderRadius: '2',
    axisPointer: {
      lineStyle: {
        type: 'solid',
        color: 'var(--o-border-color-base)',
      },
    },
    formatter(param: any) {
      let val = '';
      for (let i = 0; i < param.length; i++) {
        let sp = '<span class="echarts-formatter-block default-color"></span>';
        let className = 'default-color';
        if (param[i].seriesIndex === 0) {
          className =
            param[i].data[1] >= highPowerThresholdWatts.value && props.type === 'System'
              ? 'red'
              : 'default-color';
        }
        if (param[i].seriesIndex === 1) {
          className =
            param[i].data[1] >= highPowerThresholdWatts.value && props.type === 'System'
              ? 'red'
              : 'sec-color';
        }
        if (param[i].seriesIndex === 2) {
          className = 'third-color';
        }
        sp = `<span class="echarts-formatter-block ${className}"></span>`;
        val += `<div class="echarts-formatter-other-row-value-box">
                    ${sp}
                    <span class="echarts-formatter-key mr-8">${param[i].seriesName}</span>
                    <span class="echarts-formatter-value">${param[i].data[1]}</span>
                  </div>`;
      }
      return `<span class="echarts-formatter-first-row">${new Date(param[0].data[0]).pattern(
        'yyyy/MM/dd HH:mm',
      )}</span><br>${val}`;
    },
  };
}
function getSeriesWattes() {
  const options = {
    name: traduction('POWER_WATTS'),
    data:
      powerHistoryChartsData?.powerWattsList?.map((item: any, index: any, arr: any) => {
        if (arr.length === 1) {
          return item;
        }
        return [new Date(item[0]).getTime(), item[1]];
      }) || [],
    type: 'line',
    smooth: true,
    showSymbol: false,
    areaStyle: {
      color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
        {
          offset: 0,
          color: 'rgba(168,67,205,0.39)',
        },
        {
          offset: 0.34,
          color: 'rgba(168,67,205,0.25)',
        },
        {
          offset: 1,
          color: 'rgba(168,67,205,0.00)',
        },
      ]),
    },
  };
  getYaxisLabelWidth(SeriesName.WATTS, options);
  return options;
}
function getSeriesAvg() {
  const options = {
    name: traduction('POWER_AVG'),
    data:
      powerHistoryChartsData?.powerAverageWattsList?.map((item: any, index: any, arr: any) => {
        if (arr.length === 1) {
          return item;
        }
        return [new Date(item[0]).getTime(), item[1]];
      }) || [],
    type: 'line',
    smooth: true,
    showSymbol: false,
    areaStyle: {
      color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
        {
          offset: 0,
          color: 'rgba(0,119,255,0.39)',
        },
        {
          offset: 0.34,
          color: 'rgba(0,119,255,0.25)',
        },
        {
          offset: 1,
          color: 'rgba(0,119,255,0.00)',
        },
      ]),
    },
  };
  const extern = {
    markLine: {
      symbol: 'none',
      lineStyle: {
        type: 'dashed',
        color: '#E32020',
      },
      label: {
        show: false,
      },
      data: [{ yAxis: highPowerThresholdWatts.value || '' }],
    },
  };
  if (props.type === 'System') {
    Object.assign(options, extern);
  }
  getYaxisLabelWidth(SeriesName.AVG, options);
  return options;
}
function getSeriesPeak() {
  const options = {
    name: traduction('POWER_PEAK'),
    data:
      powerHistoryChartsData?.powerPeakWattsList?.map((item: any, index: any, arr: any) => {
        if (arr.length === 1) {
          return item;
        }
        return [new Date(item[0]).getTime(), item[1]];
      }) || [],
    type: 'line',
    smooth: true,
    showSymbol: false,
  };
  const extern = {
    areaStyle: {
      color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
        {
          offset: 0,
          color: 'rgba(41,163,112,0.39)',
        },
        {
          offset: 0.34,
          color: 'rgba(41,163,112,0.25)',
        },
        {
          offset: 1,
          color: 'rgba(41,163,112,0.00)',
        },
      ]),
    },
  };
  Object.assign(options, extern);
  getYaxisLabelWidth(SeriesName.PEAK, options);
  return options;
}
function getXAxis() {
  return {
    type: 'category',
    data: timeArr(powerHistoryChartsData.timeList),
    interval: generateXLabels(powerHistoryChartsData.timeList),
    boundaryGap: false,
    axisLine: {
      lineStyle: {
        color: ['var(--o-text-color-tertiary)'],
      },
    },
    axisTick: {
      show: false,
    },
    axisLabel: {
      margin: AXIS_LABEL_MARGIN,
      color: '#9EA4B3',
      fontSize: 10,
      formatter(item: any) {
        if (powerHistoryChartsData.timeList.length === 1) {
          return item.replace(' ', '\n');
        }
        return ' ' + new Date(parseInt(item, 10)).pattern('yyyy/MM/dd HH:mm').replace(' ', '\n');
      },
    },
  };
}
function getYAxis() {
  return {
    name: yAxis.value,
    type: 'value',
    splitLine: {
      lineStyle: {
        type: 'dashed',
      },
      interval: 1,
    },
    nameTextStyle: {
      fontFamily: 'HarmonyOS Sans SC Medium',
      align: 'left',
    },
    axisLabel: {
      margin: AXIS_LABEL_MARGIN,
    },
  };
}
function getVisualMap() {
  return [
    {
      show: false,
      seriesIndex: 0,
      pieces: [
        {
          gte: highPowerThresholdWatts.value,
          color: '#E32020',
        },
        {
          lt: highPowerThresholdWatts.value,
          gte: 0,
          color: '#0077FF',
        },
      ],
    },
    {
      show: false,
      seriesIndex: 1,
      pieces: [
        {
          gte: highPowerThresholdWatts.value,
          color: '#E32020',
        },
        {
          lt: highPowerThresholdWatts.value,
          gte: 0,
          color: '#29A370',
        },
      ],
    },
  ];
}
// 图表
function chartsOptions() {
  powerInfo.segmentedPeakPower = null;
  powerHistoryChartsData?.powerPeakWattsList?.forEach(element => {
    if (Number(element[1]) >= Number(powerInfo.segmentedPeakPower)) {
      powerInfo.statisticsCollected = element[0];
      powerInfo.segmentedPeakPower = element[1];
    }
  });
  const options = {
    color: ['#0077FF', '#29A370', '#A843CD'],
    tooltip: getTooltip(),
    legend: {
      type: 'scroll',
      data: [traduction('POWER_AVG'), traduction('POWER_PEAK'), traduction('POWER_WATTS')],
      top: '6',
      itemHeight: '0',
    },
    grid: {
      left: 0,
      right: 0,
      top: '40px',
      bottom: '0px',
      containLabel: true,
    },
    xAxis: getXAxis(),
    yAxis: getYAxis(),
    series: [getSeriesAvg(), getSeriesPeak(), getSeriesWattes()],
  };
  updateLegendLeft(options.legend, [SeriesName.AVG, SeriesName.PEAK, SeriesName.WATTS]);
  if (highPowerThresholdWatts.value !== null && props.type === 'System') {
    Object.assign(options, { visualMap: getVisualMap() });
  }
  if (initCharts) {
    initCharts.clear();
    initCharts.setOption(options, true);
  } else {
    initCharts = echarts.init(cappingCharts.value);
    initCharts.setOption(options, true);
  }
  initCharts.resize();
  legendEventBinding();
}

// 点击legend
function legendEventBinding(): void {
  if (!initCharts) {
    return;
  }
  // 解决重复触发
  initCharts.off('legendselectchanged');
  // 点击的时候修改左边距
  initCharts.on('legendselectchanged', (e: any) => {
    const selected = e.selected;
    const selectedIndex = Object.keys(selected)
      .map((key, idx) => [idx, selected[key]])
      .filter(([_, sel]) => sel)
      .map(([idx]) => idx) as SeriesName[];

    if (!initCharts) {
      return;
    }
    const option = initCharts.getOption();
    updateLegendLeft(option.legend[0], selectedIndex);
    if (selectedIndex.length === 0) {
      option.grid[0].left = '32px';
    } else {
      option.grid[0].left = 0;
    }
    initCharts.clear();
    initCharts.setOption(option, true);
  });
}

function chartResize(): void {
  if (initCharts) {
    initCharts.resize();
  }
}

function getChartId(): string {
  const handler = {
    System: 'powerCharts',
    Cpu: 'cpuCharts',
    Fan: 'fanCharts',
    Memory: 'MemoryCharts',
  };
  return handler?.[props.type || 'System'];
}

// 清除历史功率
function clearHistory() {
  loading(true);
  clearHistoryData(props.type, props.hostNumber)
    .then(() => {
      showElMessage('success', traduction('COMMON_SUCCESS'));
      setTimeout(() => {
        emits('clear', props.type);
        loading(false);
      }, 2000);
    })
    .catch(() => {
      showElMessage('error', traduction('COMMON_FAILED'));
      loading(false);
    });
}

// 下载历史功率
function downloadHistory() {
  if (isDownning.value) {
    return;
  }
  isDownning.value = true;
  downLoadHistory(props.type, props.hostNumber).then(
    (res: AxiosResponse) => {
      const url = res.data.url;
      queryTask(url);
    },
    () => {
      isDownning.value = false;
      showElMessage('error', traduction('COMMON_FAILED'));
    },
  );
}

// 查询下载进度
function queryTask(url: string) {
  queryProgress(url).then(
    (res: AxiosResponse) => {
      const item = res.data;
      if (item) {
        if (item.prepare_progress === 100 && item.state === 'Completed') {
          beginDownLoad();
        } else if (item.state === 'Exception') {
          isDownning.value = false;
          showElMessage('error', traduction('COMMON_FAILED'));
        } else {
          setTimeout(() => {
            queryTask(url);
          }, 3000);
        }
      }
    },
    () => {
      isDownning.value = false;
      showElMessage('error', traduction('COMMON_FAILED'));
    },
  );
}

// 开始下载
function beginDownLoad() {
  downloadData(props.type)
    .then((res: any) => {
      const fileName = res.headers['content-disposition'].split('=')[1];
      downloadFileWithResponse(res.data, fileName);
      isDownning.value = false;
      showElMessage('success', traduction('COMMON_SUCCESS'));
    })
    .catch(() => {
      isDownning.value = false;
    });
}

function updateLegendLeft(legend: any, selectedIndex: SeriesName[]) {
  let leftLabelPadding = Math.max(...selectedIndex.map((name) => leftPaddingMap.value.get(name) as number));
  if (leftLabelPadding < 0) {
    leftLabelPadding = 24;
  }
  legend.left = leftLabelPadding + leftMarginRef.value + AXIS_LABEL_MARGIN + 8;
}

function calcMargin() {
  const context = dummyCncRef.value?.context;
  if (!context) {
    leftMarginRef.value = (isWUnit.value ? gridLeftSettingItem?.wLegendLeft : gridLeftSettingItem?.btuLegendLeft) as number;
  } else {
    context.font = '12px "HarmonyOS Sans SC Medium"';
    leftMarginRef.value = context.measureText(yAxis.value).width;
  }
}

function getYaxisLabelWidth(name: SeriesName, options: { data: [string, number][] }) {
  const context = dummyCncRef.value?.context;
  const maxValue = Math.max(...options.data.map(item => item[1]));
  const preProcessed = maxValue < 0 ? 0 : Math.trunc(maxValue);
  const stringized = `${preProcessed}`;
  const digits = stringized.length;
  const clampedVal = Math.ceil(preProcessed / Math.pow(10, digits - 1)) * Math.pow(10, digits - 1);
  const toBeMeasure = `${clampedVal}`;
  if (context) {
    context.font = '12px sans-serif';
    let calcVal = context.measureText(toBeMeasure).width;
    calcVal = Math.max(calcVal, 20);
    leftPaddingMap.value.set(name, calcVal);
  }
}

onMounted(() => {
  try {
    const canvas = document.createElement('canvas');
    const context = canvas.getContext('2d');
    dummyCncRef.value = { canvas, context };
  } catch {
    // do nothing
  }
});

defineExpose({
  resize: () => {
    chartResize();
  },
});
// 监听props
watch(
  () => props.data,
  newVal => {
    powerHistoryData = newVal?.powerHistoryData;
    unit.value = newVal?.activeUnit;
    highPowerThresholdWatts.value = newVal?.highPowerThresholdWatts;
    yAxis.value =
      unit.value === 'W'
        ? traduction('OTHER_POWER')
        : traduction('HOME_POWERW').split('\n')[1] + '(BTU/h)';
    init();
    calcMargin();
    chartsOptions();
  },
  { deep: true },
);
// 监听图表数据
watch(
  powerHistoryChartsData,
  () => {
    if (highPowerThresholdWatts.value || highPowerThresholdWatts.value === 0) {
      chartsOptions();
    }
  },
  { deep: true },
);
</script>

<template>
  <div class="power-capping-history">
    <Download :state="isDownning" />
    <div class="card-header">
      <div class="header-left">
        <span class="title">{{ $t('POWER_HISTORY') }}</span>
      </div>
      <div class="header-right">
        <div class="text">
          <span>{{ $t('POWER_PEAK_OCCURRED') }}</span>
          <span>{{ powerInfo.statisticsCollected }}</span>
        </div>
        <div class="data-picker">
          <el-date-picker
            id="searchData"
            v-model="searchDataValue"
            type="datetimerange"
            range-separator="-"
            :prefix-icon="IconDate"
            :disabled-date="dateTimePicker.disabledDate"
            @change="dateTimePicker.searchDataOK()"
          ></el-date-picker>
        </div>
        <el-tooltip placement="top" :content="$t('COMMON_CLEAR')" trigger-keys>
          <div v-if="isPrivileges" class="icon-border" style="margin-right: 4px">
            <el-icon
              id="powerHistoryClear"
              size="16px"
              class="clear"
              :class="isSystemLock && 'locking'"
              @click="showMessage"
            >
              <IconDelete />
            </el-icon>
          </div>
        </el-tooltip>
        <el-tooltip placement="top" :content="$t('COMMON_DOWN')" trigger-keys>
          <div v-if="isPrivileges" class="icon-border">
            <el-icon id="powerHistoryDown" size="16px" class="down" @click="downloadHistory">
              <IconDownload />
            </el-icon>
          </div>
        </el-tooltip>
      </div>
    </div>
    <div class="card-header power-history-header">
      <div class="header-left">
        <slot></slot>
      </div>
    </div>
    <div class="charts-header">
      <div class="header-left">
        <div v-if="showWarnLimit" class="threshold">
          <span class="title">{{ $t('THRESHOLD_INFO') }}</span>
          <span v-if="!threshold.editor || !isPrivileges" class="num">
            {{ highPowerThresholdWatts + unit }}
          </span>
          <Editor
            v-if="unit === 'W' && isPrivileges"
            :disabled="isSystemLock"
            :input-style="{ width: '56px' }"
            :id-str="'alarmThresholdEditor'"
            :input-type="'text'"
            :value="highPowerThresholdWatts"
            :unit="unit"
            :rule="threshold.validationWRules"
            :popover-setting="threshold.popoverWSetting"
            @editor="threshold.editor"
            @cancel="threshold.cancel"
            @confirm="threshold.confirm"
          />
          <Editor
            v-if="unit !== 'W' && isPrivileges"
            :disabled="isSystemLock"
            :input-style="{ width: '56px' }"
            :id-str="'alarmThresholdEditor'"
            :input-type="'text'"
            :value="highPowerThresholdWatts"
            :unit="unit"
            :rule="threshold.validationBTURules"
            :popover-setting="threshold.popoverBTUSetting"
            @editor="threshold.editor"
            @cancel="threshold.cancel"
            @confirm="threshold.confirm"
          />
        </div>
      </div>
      <div class="header-right">
        <div id="peakPower" class="text">
          <div>{{ $t('POWER_SEGMENTED_PEAK_POWER2') }}</div>
          <div>{{ unit }}</div>
        </div>
        <div class="number">
          {{ powerInfo?.segmentedPeakPower !== null ? powerInfo?.segmentedPeakPower : '--' }}
        </div>
      </div>
    </div>
    <div v-show="showCharts" :id="getChartId()" ref="cappingCharts" class="chart"></div>
    <div v-show="!showCharts" class="no-data">
      <TableNoData />
    </div>
  </div>

  <Dialog ref="delDialogRef" :config="delConfig" @close="closeModal"></Dialog>
</template>

<style lang="scss" scoped>
.power-capping-history {
  width: 100%;
  position: relative;
  .title {
    display: inline-block;
    height: 24px;
    font-size: 16px;
    font-weight: 600;
    color: var(--o-text-color-primary);
    text-align: center;
    line-height: 24px;
  }
  .icon-border {
    border: 1px solid var(--o-border-color-lighter);
    border-radius: 2px;
    padding: 7px;
  }
  .power-history-header {
    margin: 16px 0 20px 0;
    height: 40px !important;
  }
  .card-header {
    height: 32px;
    line-height: 32px;
    display: flex;
    justify-content: space-between;
    margin-bottom: 8px;
    .header-left,
    .header-right {
      display: inline-block;
      .el-icon {
        color: var(--o-text-color-tertiary);
        vertical-align: middle;
        &:nth-child(2n) {
          margin-left: 8px;
        }
      }
    }
    div {
      display: inline-block;
    }
    .text {
      font-size: 12px;
      color: var(--o-text-color-secondary);
      margin-right: 24px;
    }
    .data-picker {
      margin-right: 16px;
      border-radius: 2px;
      height: 32px;
      :deep(.el-range__icon) {
        margin-right: 0;
      }
      :deep(.el-range__close-icon) {
        margin-right: 16px;
      }
    }
  }
  .charts-header {
    display: flex;
    justify-content: space-between;
    .header-left {
      .threshold {
        display: flex;
        .title {
          color: var(--o-text-color-secondary);
        }
      }
      .title {
        font-size: 12px;
        height: 16px;
        color: var(--o-text-color-secondary);
        margin-right: 8px;
        display: inline-flex;
      }
      .num {
        font-size: 16px;
        height: 24px;
        line-height: 24px;
        color: var(--o-text-color-primary);
        margin-right: 4px;
        display: inline-flex;
      }
      .el-input {
        width: 50px;
        margin-right: 4px;
        :deep(.el-input__inner) {
          padding: 0;
          text-align: center;
          height: 24px;
        }
      }
      .editor-icon {
        cursor: pointer;
      }
      .capping {
        height: 16px;
        line-height: 16px;
        margin-top: 13px;
        .title {
          margin-right: 16px;
        }
        .line {
          display: inline-block;
          width: 16px;
          height: 3px;
          background: #0062dc;
          vertical-align: middle;
        }
        .power-avg {
          margin-left: 8px;
          color: var(--o-text-color-secondary);
        }
      }
    }
    .header-right {
      display: flex;
      height: 40px;
      .text {
        color: var(--o-text-color-secondary);
        margin: auto;
        div {
          text-align: right;
        }
      }
      .number {
        font-size: 32px;
        color: var(--o-text-color-primary);
        line-height: 40px;
        margin-left: 8px;
      }
    }
  }
  .chart {
    height: 450px;
    width: 100%;
  }
  :deep(.el-form-item__error) {
    display: none;
  }
  :deep(.el-icon) {
    cursor: pointer;
  }
  :deep(.el-icon:hover) {
    color: var(--o-color-primary-secondary) !important;
  }
  .locking {
    cursor: not-allowed !important;
  }
  .no-data {
    display: flex;
    justify-content: center;
    align-items: center;
    text-align: center;
    width: 100%;
    height: 450px;
  }
}
</style>
