<script lang="ts" setup>
import { computed, onMounted, ref } from 'vue';
import { getStoreData, loading } from '@/utils/composition';
import { showFailedMessage } from '@/utils/composition';
import { getErrorTranslate, traduction } from '@/utils/language';
import {
  getpowerSupply,
  setPowerSupply,
  getEnergySavingService,
  getEnergySavingServiceScenes,
  setEnergyServiceScenes,
  setBiosSettings,
} from '../../services/power.services';
import { IconAlarm } from '@computing/opendesign-icons';
import { showElMessage } from '@/utils/utils';
import { IBiosTabs, IOption } from '@/model/System/bios-interface';
import { intelligentUpdate } from '@/pages/System/Info/service/system.service';
import type { TableColumnCtx } from 'element-plus';
import { IconCaretUp } from '@computing/opendesign-icons';
interface SpanMethodProps {
  row: any;
  column: TableColumnCtx<any>;
  rowIndex: number;
  columnIndex: number;
}
enum Profile {
  HPC = 'HPC',
  LIGHTWORK = 'LightWork',
  DEFAULT = 'Default',
  CUSTOM = 'Custom',
  LOADBALANCING = 'LoadBalancing',
  ACTIVESTANDBY = 'Active/Standby',
  ENERGYSAVING = 'EnergySaving',
  HIGHPERFORMANCE = 'HighPerformance',
  LOWNOISE = 'LowNoise',
  LIQUIDCOOLING = 'LiquidCooling',
  SMARTCOOLINGMODE = 'SmartCoolingMode',
  POWERWORKINGMODE = 'PowerWorkingMode',
  EFFICIENCY = 'Efficiency',
  PERFORMANCE = 'Performance',
  POWERPOLICY = 'PowerPolicy'
}
const ProfileTextMapping = new Map<Profile, string>([
  [Profile.HPC, 'HPC_CONFIGURATION'],
  [Profile.LIGHTWORK, 'LIGHT_WORK'],
  [Profile.DEFAULT, 'DEFAULT_CONFIGURATION'],
  [Profile.CUSTOM, 'FAN_MODEL_TITLE4'],
  [Profile.LOADBALANCING, 'POWER_LOAD_BALANCING'],
  [Profile.ACTIVESTANDBY, 'POWER_MAIN_STANDBY'],
  [Profile.ENERGYSAVING, 'FAN_MODEL_TITLE1'],
  [Profile.HIGHPERFORMANCE, 'FAN_MODEL_TITLE3'],
  [Profile.LOWNOISE, 'FAN_MODEL_TITLE2'],
  [Profile.LIQUIDCOOLING, 'FAN_LIQUID_COOLING'],
  [Profile.SMARTCOOLINGMODE, 'FAN_HEAT_NAME'],
  [Profile.POWERWORKINGMODE, 'HOME_POWER_MODE'],
  [Profile.EFFICIENCY, 'FAN_MODEL_TITLE1'],
  [Profile.PERFORMANCE, 'FAN_MODEL_TITLE3'],
  [Profile.POWERPOLICY, 'HOME_POWER_POLICY'],
]);
const isLocked = computed(() => {
  return getStoreData('glob', 'systemLocked');
});
const showDialog = ref(false);
let activePSU = ref<any>([]);
let powerList = ref<{ id: string; Name: string }[]>([]);
let checkList = ref([]);
let checkedPSU = ref('');
let oldConfig = ref({
  Thermal: [] as any,
  Power: [] as any,
  BIOS: [] as any,
});
const spanArr = ref<any>([]);
const pos = ref(0);
const energyConfig = ref({
  label: 'Preformance Profile',
  value: 'Null',
  options: [] as IOption[],
});
let lastPowerIndex = ref(-1);
let thermalLastIndex = ref(-1);
let biosLastIndex = ref(-1);
let tableData = ref<IBiosTabs[]>([]);
const privil = getStoreData('loct', 'privil');
const powerControlEnabled = privil.includes('PowerControlEnabled');
function saveEngry() {
  let p = {
    DynamicEnergySavingScene: {
      CurrentValue: energyConfig.value.value,
    },
  };
  setEnergyServiceScenes(p)
    .then(
      () => {
        showElMessage('success', traduction('COMMON_SUCCESS'));
        queryConfig();
      },
      (err) => {
        const errorCode = err?.data?.error?.[0]?.code;
        if (errorCode) {
          showFailedMessage(getErrorTranslate(errorCode));
        } else {
          showElMessage('error', traduction('COMMON_FAILED'));
        }
      },
    )
    .finally(() => {});
}
function savePower() {
  let power = tableData.value.filter(
    (v) => v.id === 'Power' && v.modeName === 'PowerWorkingMode',
  );
  if (!power.length) {
    return;
  }
  if (power.every((v) => v.mode === v.nextMode)) {
    return;
  }
  let params = {
    PowerMode: power[0].nextMode === 'LoadBalancing' ? 'Sharing' : power[0].nextMode,
  };
  let isStandby = 1;
  activePSU.value.forEach((item: any) => {
    if (item.Mode !== 'Active') {
      isStandby = 0;
    }
  });
  if (params.PowerMode === 'Active/Standby') {
    Object.assign(params, {
      SupplyList: activePSU.value.map((v: any) => {
        return  {
          Mode: v.Mode,
          Name: v.Name,
        };
      }),
    });
  }
  if (isStandby === 1) {
    showElMessage('error', traduction('POWER_NO_STAND'));
    return;
  }
  setPowerSupply(params).then((res) => {
    if (res.data.error) {
      showFailedMessage(getErrorTranslate(res.data.error[0]?.code));
    }
  });
}
function saveBios() {
  let Bios = tableData.value.filter((v: { id: string }) => v.id === 'Bios');
  if (!Bios.length) {
    return;
  }
  let p = {
    Attributes: {
      PowerPolicy: Bios[0].nextMode,
    },
  };
  setBiosSettings(p)
    .then(
      () => {},
      (err) => {
        const errorCode = err?.data?.error?.[0]?.code;
        if (errorCode) {
          showFailedMessage(getErrorTranslate(errorCode));
        } else {
          showElMessage('error', traduction('COMMON_FAILED'));
        }
      },
    )
    .finally(() => {});
}
function saveThermal() {
  let fan = tableData.value.filter(
    (v: any) => v.id === 'Thermal' && v.modeName === 'SmartCoolingMode',
  );
  if (!fan.length) {
    return;
  }
  if (fan.every((v) => v.mode === v.nextMode)) {
    return;
  }
  let params = {
    SmartCooling: {
      Mode: fan[0].nextMode,
    },
  };
  intelligentUpdate(params).then(
    (res) => {
      if (res.data.error) {
        showFailedMessage(getErrorTranslate(res.data.error[0]?.code));
      }
    },
    (error) => {
      showFailedMessage(getErrorTranslate(error?.data?.error[0]?.code));
    },
  );
}
function saveAllEngryConfig() {
  showDialog.value = false;
  savePower();
  saveBios();
  saveThermal();
  setTimeout(() => {
    saveEngry();
  }, 500);
}
let dialogBtnDisabled = computed(() => {
  let power = tableData.value.filter((v: { id: string }) => v.id === 'Power');
  if (!power.length) {
    return false;
  }
  return (
    power.some((v) => v.nextMode === 'Active/Standby') &&
    !checkList.value.length &&
    checkedPSU.value === ''
  );
});
let showChecklist = computed(() => {
  let power = tableData.value.filter((v: { id: string }) => v.id === 'Power');
  if (!power.length) {
    return false;
  }
  return power.some((v) => v.nextMode === 'Active/Standby');
});
function handleSave() {
  if (!energyConfig.value.value) {
    return;
  }
  showDialog.value = true;
}
function radioChange(value: string) {
  if (value) {
    getDialoagScenes();
  }
}
function getDialoagScenes() {
  tableData.value.forEach((v) => {
    v.nextMode = '';
  });
  getEnergySavingServiceScenes(energyConfig.value.value)
    .then((res: any) => {
      const { BiosMode, PowerMode, ThermalMode } = res.data;
      if (ThermalMode && ThermalMode.length) {
        ThermalMode.forEach((v: any) => {
          let item = tableData.value.find((data) => data.modeName === v.Mode);
          if (item) {
            item.nextMode = v.Value;
          }
        });
      }
      if (PowerMode && PowerMode.length) {
        PowerMode.forEach((v: any) => {
          let item = tableData.value.find((data) => data.modeName === v.Mode);
          if (item) {
            item.nextMode = v.Value;
          }
        });
      }
      if (BiosMode && BiosMode.length) {
        BiosMode.forEach((v: any) => {
          let item = tableData.value.find((data) => data.modeName === v.Mode);
          if (item) {
            item.nextMode = v.Value;
          }
        });
      }
    })
    .finally(() => {});
}
function getTableData(CurrentMode: any) {
  tableData.value = [];
  if (CurrentMode.Thermal && CurrentMode.Thermal.length) {
    CurrentMode.Thermal.forEach((item: any) => {
      tableData.value.push({
        id: 'Thermal',
        component: traduction('HEAT_DISSIPATION'),
        modeName: item.Mode,
        mode: item.Value,
        nextMode: '',
      });
    });
  }
  if (CurrentMode.Power && CurrentMode.Power.length) {
    CurrentMode.Power.forEach((item: any) => {
      tableData.value.push({
        id: 'Power',
        component: traduction('POWER_SUPPLY'),
        modeName: item.Mode,
        mode: item.Value,
        nextMode: '',
      });
    });
  }
  if (CurrentMode.Bios && CurrentMode.Bios.length) {
    CurrentMode.Bios.forEach((item: any) => {
      tableData.value.push({
        id: 'Bios',
        component: 'BIOS',
        modeName: item.Mode,
        mode: item.Value,
        nextMode: '',
      });
    });
  }
  tableData.value.forEach((v, idx) => (v.index = idx));
  let powerArr = tableData.value
    .filter((v) => v.id === 'Power')
    .map((v) => {
      return v.index;
    });
  lastPowerIndex.value = Math.max.apply(Math, powerArr);
  let thermalArr = tableData.value
    .filter((v) => v.id === 'Thermal')
    .map((v) => {
      return v.index;
    });
  thermalLastIndex.value = Math.max.apply(Math, thermalArr);
  let biosArr = tableData.value
    .filter((v) => v.id === 'Bios')
    .map((v) => {
      return v.index;
    });
  biosLastIndex.value = Math.max.apply(Math, biosArr);
  if (energyConfig.value.value) {
    getDialoagScenes();
  }
  getSpanArr(tableData.value);
}
function queryConfig() {
  getEnergySavingService()
    .then((res: any) => {
      const { CurrentMode, CurrentValue, OptionSupported } =
        res.data.DynamicEnergySavingScene;
      oldConfig.value.Thermal = CurrentMode.Thermal || [];
      oldConfig.value.Power = CurrentMode.Power || [];
      oldConfig.value.BIOS = CurrentMode.Bios || [];
      energyConfig.value.value = CurrentValue || '';
      getTableData(CurrentMode);
      let opt = OptionSupported.map((v: string) => ({
        label: v,
        value: v,
      }));
      energyConfig.value.options = opt;
    })
    .finally(() => {
      loading(false);
    });
}
function checkgroupChange() {
  if (powerList.value.length === 2) {
    activePSU.value.forEach((item: any) => {
      if (checkedPSU.value === item.Name) {
        item.Mode = 'Active';
      } else {
        item.Mode = 'StandBy';
      }
    });
  } else {
    activePSU.value.forEach((item: any) => {
      if (checkList.value.includes(item.Name as never)) {
        item.Mode = 'Active';
      } else {
        item.Mode = 'Standby';
      }
    });
  }
}
function getPower() {
  getpowerSupply().then((res) => {
    powerList.value.slice(0);
    powerList.value = res?.data?.SupplyList || [];
    res?.data?.ExpectedSupplyList.forEach((item: any) => {
      if (item.Mode === 'Active') {
        (checkList.value as any).push(item.Name);
        checkedPSU.value = item.Name;
      }
      activePSU.value.push(item);
    });
  });
}
function getRowKeys(row: any) {
  return row.index;
}
const getSpanArr = (data: any) => {
  spanArr.value = []; // tip: 后台获取完成数据后，一定要重置spanArr=[],避免出现合并混乱！！！！！
  for (let i = 0; i < data.length; i++) {
    // 当为第一行时
    if (i === 0) {
      spanArr.value.push(1);
      pos.value = 0;
    } else {
      // 判断当前值是否与上一行的【名称】相等，相等则进行合并
      if (data[i].id === data[i - 1].id) {
        spanArr.value[pos.value] += 1; // 合并单元格：合并的行数 +1
        spanArr.value.push(0); // 0代表单元格是不需要显示, 已经被合并的单元格
      } else {
        spanArr.value.push(1); // 1代表当前这行的数据需要被显示
        pos.value = i;
      }
    }
  }
};

const objectSpanMethod = ({
  row,
  column,
  rowIndex,
  columnIndex,
}: SpanMethodProps): any => {
  if (columnIndex === 1) {
    const _row = spanArr.value[rowIndex]; // 合并行数
    const _col = spanArr.value[rowIndex] > 0 ? 1 : 0; // 合并的列数
    return {
      rowspan: _row,
      colspan: _col,
    };
  }
  return;
};
const getShowExpandClassName = ({
  row,
  rowIndex,
}: {
  row: any;
  rowIndex: number;
}) => {
  if (row.id === 'Power' && rowIndex === thermalLastIndex.value + 1) {
    if (tableData.value.filter((v) => v.id === 'Power').length === 1) {
      return 'show-right-border';
    } else {
      return 'show-right-border no-expand';
    }
  } else if (row.id === 'Power' && rowIndex === lastPowerIndex.value) {
    return '';
  } else if (row.id === 'Thermal' && rowIndex === thermalLastIndex.value) {
    return '';
  } else if (row.id === 'Bios' && rowIndex === biosLastIndex.value) {
    return 'show-right-border';
  } else {
    return 'no-expand';
  }
};

const disabled = computed(() => {
  return tableData.value.every((v: IBiosTabs) => v.mode === v.nextMode);
});
const showExpandList = computed(() => {
  if (showChecklist.value) {
    return [lastPowerIndex.value];
  }
  return [];
});
onMounted(() => {
  getPower();
  queryConfig();
});
</script>
<template>
  <div id="energy-saving" class="right-container">
    <div class="cur-value">
      <div class="title">{{ $t('POWER_CURRENT_SETTING_MODE') }}</div>
      <div v-if="oldConfig.Thermal" class="item">
        <div class="l">{{ $t('HEAT_DISSIPATION') }}</div>
        <div v-if="oldConfig.Thermal.length" class="r">
          <span v-for="(v, i) in oldConfig.Thermal" :key="i" class="advice">
            <span v-if="ProfileTextMapping.get(v.Mode)" class="key">{{ $t(ProfileTextMapping.get(v.Mode)) }}</span>
            <span v-else class="key">{{ v.Mode }}</span>
            <span v-if="ProfileTextMapping.get(v.Value)">{{ $t(ProfileTextMapping.get(v.Value)) }}</span>
            <span v-else>{{ v.Value }}</span>
            <el-divider
              v-if="i !== (oldConfig.Thermal as any).length - 1"
              class="console-divider"
              direction="vertical"
            ></el-divider>
          </span>
        </div>
        <div v-else class="r">--</div>
      </div>
      <div v-if="oldConfig.Power" class="item">
        <div class="l">{{ $t('POWER_SUPPLY') }}</div>
        <div v-if="oldConfig.Power.length" class="r">
          <span v-for="(v, i) in oldConfig.Power" :key="i" class="advice">
            <span v-if="ProfileTextMapping.get(v.Mode)" class="key">{{ $t(ProfileTextMapping.get(v.Mode)) }}</span>
            <span v-else class="key">{{ v.Mode }}</span>
            <span v-if="ProfileTextMapping.get(v.Value)">{{ $t(ProfileTextMapping.get(v.Value)) }}</span>
            <span v-else>{{ v.Value }}</span>
            <el-divider
              v-if="i !== (oldConfig.Power as any).length - 1"
              class="console-divider"
              direction="vertical"
            ></el-divider>
          </span>
        </div>
        <div v-else class="r">--</div>
      </div>
      <div v-if="oldConfig.BIOS" class="item">
        <div class="l">BIOS</div>
        <div v-if="oldConfig.BIOS.length" class="r">
          <span v-for="(v, i) in oldConfig.BIOS" :key="i" class="advice">
            <span v-if="ProfileTextMapping.get(v.Mode)" class="key">{{ $t(ProfileTextMapping.get(v.Mode)) }}</span>
            <span v-else class="key">{{ v.Mode }}</span>
            <span v-if="ProfileTextMapping.get(v.Value)">{{ $t(ProfileTextMapping.get(v.Value)) }}</span>
            <span v-else>{{ v.Value }}</span>
            <el-divider
              v-if="i !== (oldConfig.BIOS as any).length - 1"
              class="console-divider"
              direction="vertical"
            ></el-divider>
          </span>
        </div>
        <div v-else class="r">--</div>
      </div>
    </div>
    <el-form label-width="136px" label-position="left" class="energy-form">
      <el-form-item :label="$t('HOME_PREFORMANCE_PROFILE')">
        <el-select
          v-model="energyConfig.value"
          v-addId.select="'energySelectId'"
          placeholder="Select"
          :fit-input-width="true"
          :suffix-icon="IconCaretUp"
          :disabled="isLocked || !powerControlEnabled"
          style="width: 240px"
          @change="radioChange"
        >
          <el-option
            v-for="item in energyConfig.options"
            :id="item.value"
            :key="item.value"
            :label="$t(ProfileTextMapping.get(item.label))"
            :value="item.value"
          />
        </el-select>
      </el-form-item>
      <el-form-item v-if="powerControlEnabled" class="item-no-margin" :label="''" label-width="0px">
        <el-button
          id="energySaveId"
          v-privil.baseConfig
          type="primary"
          :disabled="isLocked || disabled"
          @click="handleSave"
        >
          {{ $t('COMMON_SAVE') }}
        </el-button>
      </el-form-item>
    </el-form>
  </div>
  <el-dialog
    v-model="showDialog"
    :close-on-click-modal="false"
    :title="$t('COMMON_CONFIRM')"
    class="second-pwd"
    width="656"
    @close="showDialog = false"
  >
    <div class="dialog-contain">
      <div class="tip">
        <el-icon size="24">
          <IconAlarm />
        </el-icon>
        <span>
          {{
            $t('POWER_CONFIRM_MODE', [
              $t(ProfileTextMapping.get(energyConfig.value)),
            ])
          }}
        </span>
      </div>
      <el-table
        :data="tableData"
        resizable
        border
        class="reset-table special-table"
        :span-method="objectSpanMethod"
        :row-key="getRowKeys"
        :expand-row-keys="[showExpandList]"
        :row-class-name="getShowExpandClassName"
      >
        <el-table-column type="expand">
          <template #default="props">
            <div v-if="showChecklist" class="main-power">
              <el-form
                label-width="108px"
                label-position="left"
                class="energy-form"
              >
                <el-form-item :label="$t('POWER_SELECT_MAIN')" required>
                  <el-radio-group
                    v-if="powerList.length === 2"
                    v-model="checkedPSU"
                    @change="checkgroupChange"
                  >
                    <el-radio
                      v-for="(item, index) in powerList"
                      :key="item.Name"
                      v-addId.radio="'power' + index"
                      :label="item.Name">
                      {{ item.Name }}
                    </el-radio>
                  </el-radio-group>
                  <el-checkbox-group
                    v-else
                    v-model="checkList"
                    @change="checkgroupChange"
                  >
                    <el-checkbox
                      v-for="(item,index) in powerList"
                      :key="item.id"
                      v-addId.checkbox="'power' + index"
                      :label="item.Name"
                      :value="item.Name"
                    />
                  </el-checkbox-group>
                </el-form-item>
              </el-form>
            </div>
          </template>
        </el-table-column>
        <el-table-column width="110" prop="component" :label="$t('SYSTEM')" />
        <el-table-column prop="mode" :label="$t('POWER_CURRENT_MODE')">
          <template #default="scope">
            <template v-if="ProfileTextMapping.get(scope.row.mode)">
              {{ $t(ProfileTextMapping.get(scope.row.mode)) }}
            </template>
            <template v-else> {{ scope.row.mode }}</template>
          </template>
        </el-table-column>
        <el-table-column prop="nextMode" :label="$t('POWER_EFFECTIVE_MODE')">
          <template #default="scope">
            <template v-if="ProfileTextMapping.get(scope.row.nextMode)">
              {{ $t(ProfileTextMapping.get(scope.row.nextMode)) }}
            </template>
            <template v-else> {{ scope.row.nextMode }}</template>
          </template>
        </el-table-column>
        <el-table-column prop="modeName" :label="$t('FDM_TYPE')">
          <template #default="scope">
            <template v-if="ProfileTextMapping.get(scope.row.modeName)">
              {{ $t(ProfileTextMapping.get(scope.row.modeName)) }}
            </template>
            <template v-else> {{ scope.row.modeName }}</template>
          </template>
        </el-table-column>
      </el-table>
    </div>
    <template #footer>
      <div class="center footer">
        <el-button
          id="confirmOk"
          type="primary"
          :disabled="isLocked || dialogBtnDisabled"
          size="small"
          @click="saveAllEngryConfig"
        >
          {{ $t('COMMON_OK') }}
        </el-button>
        <el-button id="secondCancel" size="small" @click="showDialog = false">
          {{ $t('COMMON_CANCEL') }}
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>
<style lang="scss" scoped>
.right-container {
  padding: 16px 24px 24px 24px;
}

.item-no-margin{
  margin-bottom: 0px;
}
.cur-value {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin-bottom: 24px;
  padding: 16px;
  border-radius: var(--o-border-radius);
  background-color: var(--o-bg-color-light);

  .title {
    font-size: 12px;
    color: #000000;
    font-weight: bold;
    line-height: 16px;
  }

  .item {
    display: flex;

    .l {
      flex-basis: 120px;
    }

    .key {
      margin-right: 8px;
      color: #4e5865;
    }
  }
}

.energy-form {
  :deep(label) {
    // word-break: break-all;
  }
}

.tip {
  margin-bottom: 16px;
  display: flex;
  .el-icon {
    vertical-align: -0.1em;
  }

  span {
    margin-top: 2px;
    margin-left: 8px;
    vertical-align: super;
  }
}

:deep(.el-select__wrapper) {
  border-radius: 2px;
}

.main-power {
  margin-left: 45px;
  min-height: 50px;
  :deep(.el-form-item) {
    margin-bottom: 0;
  }
}

.special-table {
  --o-table-td-bg-color_hover: transparent !important;

  :deep(.no-expand) {
    .el-table__expand-column {
      border-bottom: none !important;
    }
  }

  :deep(.show-right-border) {
    .el-table__cell {
      &:nth-child(2) {
        border-right: 1px solid #dfe5ef !important;
      }
    }
  }

  :deep(.el-table__row) {
    .el-table__expand-column {
      .cell {
        display: none;
      }
    }

    .el-table__cell {
      background: transparent !important;
    }

    &:nth-child(1) {
      .el-table__cell {
        &:nth-child(2) {
          border-right: 1px solid #dfe5ef !important;
        }
      }
    }
  }
}
</style>
