<script setup lang="ts">
import { traduction, getErrorTranslate } from '@/utils/language';
import { ref, reactive, computed, onMounted, onUnmounted, onBeforeUnmount, nextTick } from 'vue';
import useStore from '@/stores';
import Dialog from '@/components/Dialog/Dialog.vue';
import FileUpload from '@/components/FileUpload/FileUpload.vue';
import { UploadFile } from 'element-plus/es/components/upload/src/upload';
import { ElNotification as elNotification } from 'element-plus';
import UploadingIcon from '@/components/UploadingIcon/UploadingIcon.vue';
import SecondPassword from '@/components/SecondPassword/SecondPassword.vue';
import { SecondAuthorityFail, UserPrivil } from '@/model/base-enum';
import {
  getPowerControl,
  importUpgradeFile,
  queryParallelUpdateProgress,
  reauth,
  importParallelUpdate,
} from '../../upgrade.services';
import Date from '@/utils/date';
import { checkPrivil } from '@/apps/app-bmc/router/routes';
import { getStoreData, setStoreData } from '@/utils/composition';
import { showElMessage, getMessageId, escapeHeader } from '@/utils/utils';
import { IconSuccess, IconRemind } from '@computing/opendesign-icons';
import { UI_REST_FIRMWAREINVENTORY } from '@/api/api';
import { ITableStep2 } from '@/model/Manager/upgrade-interface';
import { ITableColumns } from '@/model/base-interface';
import axios from 'axios';
 
const store = useStore();
const isSystemLock = computed(() => {
  return store.state.glob.systemLocked;
});
const step = ref(1);
const multihost = computed(() => getStoreData('loct', 'multihost'));
const productLabel = store.state.loct.sn;
const loct: any = localStorage.getItem('loct');
const dialogRef = ref();
const tipRef = ref();
const uploadRef = ref();
const currentPage = ref(1);
const pageSize = ref(10);
let hpmUpload: any = null;
let formData = ref(); // 表单数据
// 表示进度条的显示状态
const onUpgrade = ref(false);
const submitDisabled = ref(true);
const uploadDisabled = ref(false);
const taskUrl = ref('');
const progress = ref(0);
// 升级进度查询
let taskInterval: any = null;
let taskStateErrorAmount = 0;
// 记录网络失败次数
let networkErrorAmount = 0;
let bmcUpdating = false;
const upgradeResult = reactive({
  result: '',
  msg: '',
});
const upgradeModeData = ref<any>(null);
const uploadError = ref('');
// 是否支持生效分离
const upgradeActiveModeSupported = ref(false);
const filteredTable = ref<ITableStep2[]>([]);
const isInit = ref<boolean>(true);
const failCount = ref<number>(0);
 
// CPLD白名单
const CPLDList = ['DPUCpld'];
 
let fileItem: any = null;
 
const hasUserConfig = checkPrivil(UserPrivil.userConfig);
// 保留配置
let configSelected = ref('yes');
 
const props = defineProps<{
  upgradeMode: boolean;
  activeMode: boolean;
}>();
 
const emits = defineEmits(['nextStep']);
const mode = ref(props.upgradeMode);
const modeDisabled = ref(false);
 
// 生效分离勾选状态
const activeMode = ref(props.activeMode);
 
const columns: ITableColumns[] = [
  {
    title: 'TABLE_TITLE_NUM',
    width: '5%',
    content: 'index',
  },
  {
    title: 'UPDATE_FIRMWARE_TYPE',
    width: '5%',
    content: 'name',
  },
  {
    title: 'UPDATE_STATUS',
    width: '10%',
    content: 'state',
  },
  {
    title: 'UPDATE_PROGRESS',
    width: '20%',
    content: 'progress',
  },
  {
    title: 'UPDATE_PACKAGE_NAME',
    width: '10%',
    content: 'firmwareName',
  },
  {
    title: 'UPDATE_RESULT_DETAIL',
    width: '10%',
    content: 'description',
  },
];
 
const tableData: ITableStep2[] = reactive([]);
 
const tipClose = (val: boolean) => {
  tipRef.value.hide();
  if (val) {
    dialogRef.value.show();
  }
};
// 是否保留配置项按钮禁用
const configRadioDisabled = ref(isSystemLock.value);
const retainedDisabled = ref(isSystemLock.value);
const changeActiveMode = (value: boolean) => {
  if (value) {
    configSelected.value = 'yes';
    configRadioDisabled.value = true;
  } else {
    configRadioDisabled.value = false;
  }
};
// 文件上传
const message = 'insufficient memory capacity for the upload.';
const uploadConfig = reactive({
  action: UI_REST_FIRMWAREINVENTORY,
  headers: {
    'X-CSRF-Token': escapeHeader(loct ? JSON.parse(loct).to : ''),
    From: 'WebUI',
    Accept: '*/*',
  },
  width: 320,
  disabled: isSystemLock.value || uploadDisabled.value,
  method: 'POST',
  name: 'imgfile',
  isAutoUpload: false,
  accept: '.hpm',
  isNeedClearError: false,
  id: 'uploadConfig',
  onAddItem: (file: UploadFile, list: UploadFile[], msg?: any, upload?: any): boolean => {
    hpmUpload = upload;
    uploadError.value = '';
    const subfix = file.name.split('.').reverse()[0];
    const size = file.size;
    // 文件格式错误
    if (subfix !== 'hpm') {
      uploadError.value = traduction('IBMC_UP_FILE_FORMAT_ERROR');
      return false;
    } else if (size && size > 1024 * 1024 * 90) {
      uploadError.value = traduction('IBMC_UPLOAD_FILE_90M_ERROR');
      return false;
    } else {
      fileItem = file;
      submitDisabled.value = false;
      return true;
    }
  },
  onError: (err: any, file: UploadFile, fileList: UploadFile[]) => {
    const errorId = getMessageId(JSON.parse(err.message));
    const errorMsg = getErrorTranslate(errorId[0]?.code as string) || traduction('COMMON_FAILED');
    // 文件名错误不需要提示右上角信息
    if (errorId[0]?.message === message) {
      showElMessage('error', traduction('IBMC_UPGRADE_FIRMWARE_TIP'));
      uploadError.value = traduction('IBMC_UPGRADE_FIRMWARE_TIP');
    } else if (errorId[0]?.code && errorId[0]?.code !== 'FileNameError') {
      showElMessage('error', errorMsg);
      uploadError.value = errorMsg;
    }
    onUpgrade.value = false;
    elNotification.closeAll();
    uploadRef.value.clear();
    retainedDisabled.value = false;
    configRadioDisabled.value = false;
    uploadDisabled.value = isSystemLock.value;
    uploadConfig.disabled = isSystemLock.value || uploadDisabled.value;
  },
  onBeforeUpload: (file: UploadFile) => {
    if (upgradeActiveModeSupported.value) {
      (file as any).formData = {
        ActiveMode: activeMode.value ? 'Immediately' : 'ResetBMC',
      };
    }
  },
  onSuccess: (res: any, file: UploadFile, fileList: UploadFile[]) => {
    beginImportUpgradeFile(fileItem.name);
  },
  onProgress: (event: any, file: UploadFile, fileList: UploadFile[]) => {
    uploadDisabled.value = true;
    uploadConfig.disabled = isSystemLock.value || uploadDisabled.value;
    retainedDisabled.value = true;
    configRadioDisabled.value = true;
    // 设置上传文件进度
    progress.value = Math.floor(event.percent);
    if (!onUpgrade.value) {
      elNotification({
        title: traduction('IBMC_UPGRADE_UPLOADING'),
        message: traduction('IBMC_UPGRADE_UPLOADING_TIP'),
        icon: UploadingIcon as any,
        position: 'bottom-right',
        duration: 0,
        offset: 10,
      });
    }
    onUpgrade.value = true;
    submitDisabled.value = true;
  },
});
// 开始执行升级流程
async function beginImportUpgradeFile(name: any) {
  onUpgrade.value = false;
  elNotification.closeAll();
  elNotification({
    title: traduction('IBMC_UPGRADE_UPLOAD_SUCCESS'),
    message: traduction('IBMC_UPGRADE_UPLOAD_COMPLETE'),
    position: 'bottom-right',
    type: 'success',
    offset: 10,
  });
 
  // 设置导入文件进度，并开始导入文件
  progress.value = 0;
  const importAction = mode.value ? importParallelUpdate : importUpgradeFile;
  try {
    taskUrl.value = (await importAction(name, configSelected.value))?.data?.url;
    onUpgrade.value = false;
    elNotification.closeAll();
    elNotification({
      title: traduction('IBMC_UPGRADE_UPLOAD_SUCCESS'),
      message: traduction('IBMC_UPGRADE_UPLOAD_COMPLETE'),
      position: 'bottom-right',
      type: 'success',
      offset: 10,
    });
    if (!taskInterval) {
      await queryParallelTask();
    } else {
      nextTick(() => {
        elNotification({
          title: traduction('IBMC_AUTOMATIC_PROCEED'),
          message: traduction('IBMC_FIMWARE_UPDATE_TIP'),
          icon: UploadingIcon as any,
          position: 'bottom-right',
          duration: 0,
          offset: 10,
        });
        bmcUpdating = true;
      });
    }
  } catch (err) {
    onUpgrade.value = false;
    elNotification.closeAll();
    uploadRef.value.clear();
    uploadDisabled.value = isSystemLock.value;
    retainedDisabled.value = false;
    configRadioDisabled.value = false;
    uploadConfig.disabled = isSystemLock.value || uploadDisabled.value;
    const errorId = getMessageId(err.data);
    const errorMsg = getErrorTranslate(errorId[0]?.code as string) || traduction('COMMON_FAILED');
    uploadError.value = errorMsg;
    // 文件名错误不需要提示右上角信息
    if (errorId[0]?.code && errorId[0]?.code !== 'FileNameError') {
      showElMessage('error', errorMsg);
    }
  }
}
 
// 升级前确认弹窗
const dialogConfig = reactive({
  id: '',
  content: traduction('COMMON_ASK_OK'),
  title: traduction('ALARM_OK'),
});
 
const tipConfig = {
  id: 'tipConfig',
  content: traduction('COMMON_ASK_OK'),
  title: traduction('ALARM_OK'),
};
 
const user = {
  loginWithoutPassword: getStoreData('loct', 'nopwd') || false,
};
let minPwdLength: number = 8;
const loginWithoutPassword = ref(user.loginWithoutPassword);
 
const secondRef = ref();
function resetDialog() {
  if (configSelected.value === 'no' && !mode.value) {
    // 不保留配置项升级：三次弹窗，先风险提示弹窗，再确认操作弹窗，再输入密码确认
    tipRef.value.show();
  } else {
    // 保留配置项升级：一次弹窗，直接确认操作弹窗
    dialogRef.value.show();
  }
}
// 二次密码确认弹窗
function confirmReset(param: { reason: boolean; password: string }) {
  if (!param.reason ) {
    secondRef.value.hide();
    return;
  } else {
    startToUpload(param.password);
  }
}
 
function startToUpload(key?: string) {
  // 点击确定后，开始升级，并将进度清0, 升级状态复位, 升级失败次数重置
  progress.value = 10;
  upgradeResult.result = '';
  upgradeResult.msg = '';
  taskStateErrorAmount = 0;
  networkErrorAmount = 0;
  if (key) {
    reauth(key).then(
      res => {
        secondRef.value.hide();
        hpmUpload.submit();
      },
      err => {
        const errorCode = err.data.error[0].code;
        if (
          errorCode === SecondAuthorityFail.REAUTHFAILED ||
          errorCode === SecondAuthorityFail.AUTHORIZATIONFAILED
        ) {
          secondRef.value.setErrorId();
          secondRef.value.clearPassword();
        }
      },
    );
  } else {
    hpmUpload.submit();
  }
}
// 开始升级按钮点击
function submitUpload(reason: any) {
  dialogRef.value.hide();
  const condition = configSelected.value === 'yes' || (configSelected.value === 'no' && mode.value);
  if (reason && condition) {
    startToUpload();
    return;
  }
  if (reason && configSelected.value === 'no') {
    if (!loginWithoutPassword.value) {
      secondRef.value.show();
    } else {
      startToUpload();
    }
  }
}

function taskParallelCompleted() {
  clearQueryProgress();
  configSelected.value = 'yes';
  bmcUpdating = false;
  elNotification.closeAll();
  onUpgrade.value = false;
  retainedDisabled.value = false;
  configRadioDisabled.value = false;
  modeDisabled.value = false;
  uploadDisabled.value = isSystemLock.value;
  uploadConfig.disabled = isSystemLock.value;
  uploadRef.value.clear();
  if (!isInit.value) {
    elNotification({
      title: traduction('IBMC_FIMWARE_UPDATE_FIND'),
      type: 'success',
      position: 'bottom-right',
      offset: 10,
    });
  }
  isInit.value = false;
}

async function getTipResult() {
  if (!multihost.value && !upgradeModeData.value) {
    upgradeModeData.value = (await getPowerControl())?.data;
  }
}

function getSuccessMessage(componentName: string): string {
  const isBIOS = ['Bios', 'Teeos'].includes(componentName);
  const isCPLD = componentName?.toLowerCase()?.indexOf('cpld') > -1 && !CPLDList.includes(componentName);
  if (isBIOS || isCPLD) {
    if (upgradeModeData.value?.PowerState[0].State !== 'Off') {
      return isCPLD ? 'IBMC_AFTER_CPLD' : 'IBMC_AFTER_REBOOT';
    }
  }
  return 'IBMC_FIMWARE_UPDATE_FIND';
}

function filterTable() {
  const start = (currentPage.value - 1) * pageSize.value;
  const end = start + pageSize.value;
  filteredTable.value = tableData.slice(start, end);
}

function handleReqError(err: any) {
  failCount.value += 1;
  if (failCount.value < 10) {
    taskInterval = setTimeout(queryParallelTask, 2000);
  } else {
    clearQueryProgress();
    modeDisabled.value = false;
    bmcUpdating = false;
    elNotification.closeAll();
    onUpgrade.value = false;
    retainedDisabled.value = false;
    configRadioDisabled.value = false;
    modeDisabled.value = false;
    uploadDisabled.value = isSystemLock.value;
    uploadConfig.disabled = isSystemLock.value;
    uploadRef.value.clear();
    isInit.value = false;
    tableData.splice(0);
    filteredTable.value.splice(0);
    failCount.value = 0;
    elNotification({
      title: traduction('IBMC_FIMWARE_FAILED'),
      position: 'bottom-right',
      type: 'error',
      offset: 10,
    });
  }
}
  
function formatEta(eta?: number): string {
  if (typeof eta !== 'number' || isNaN(eta)) {
    return '';
  }
  const m = Math.floor(eta / 60);
  const s = eta % 60;
  if (m > 0) {
    return traduction('IBMC_ETA_MIN_SEC', [m, s]);
  } else {
    return traduction('IBMC_ETA_SEC', [s]);
  }
}

async function queryParallelTask() {
  await getTipResult();
  let res: any;
  const CancelToken = axios.CancelToken;
  const source = CancelToken.source();
  const timeoutId = setTimeout(() => {
    source.cancel('Request timeout');
  }, 3000);
  try {
    res = await queryParallelUpdateProgress(source);
    clearTimeout(timeoutId);
  } catch (err) {
    handleReqError(err);
    return;
  }
  tableData.splice(0);
  res.data?.UpgradeTasks.forEach((item: any, index: number) => {
    const errCode = item.TaskState === 'Exception' && item.ErrorCode === 0 ? 255 : item.ErrorCode;
    const task: ITableStep2 = {
      index: index + 1,
      name: Boolean(item.Component) ? item.Component : '--',
      state: item.TaskState,
      progress: item.Percentage ? Number(item.Percentage.split('%')[0]) : 0,
      firmwareName: item.FileName ?? '--',
      description: errCode ? getErrMsg(errCode) : '--',
      eta: item.EstimatedRemainingTime,
    };
    if (task.state === 'Completed') {
      task.description = traduction(getSuccessMessage(task.name));
    }
    tableData.push(task);
  });
  filterTable();
  setStoreData('glob', 'isUpgrading', !tableData.every(item => ['Exception', 'Completed'].includes(item.state)));
  uploadDisabled.value = !mode.value || isSystemLock.value;
  uploadConfig.disabled = !mode.value || isSystemLock.value;
  retainedDisabled.value = true;
  configRadioDisabled.value = true;
  modeDisabled.value = tableData.some(item => ['Pending', 'Running'].includes(item.state));
  if (modeDisabled.value) {
    if (!bmcUpdating) {
      elNotification({
        title: traduction('IBMC_AUTOMATIC_PROCEED'),
        message: traduction('IBMC_FIMWARE_UPDATE_TIP'),
        icon: UploadingIcon as any,
        position: 'bottom-right',
        duration: 0,
        offset: 10,
      });
    }
    bmcUpdating = true;
    taskInterval = setTimeout(queryParallelTask, 2000);
  } else if (tableData.every(item => item.state === 'Completed')) {
    taskParallelCompleted();
  } else {
    clearQueryProgress();
    elNotification.closeAll();
    modeDisabled.value = false;
    retainedDisabled.value = false;
    configRadioDisabled.value = false;
    uploadDisabled.value = isSystemLock.value;
    uploadConfig.disabled = isSystemLock.value;
    uploadRef.value.clear();
  }
}
 
// 记录升级失败日志
function recordUpgradeErrorLogs(errorMsg: string) {
  const upgradeError = JSON.parse(localStorage.getItem('upgradeError') as string) || {};
  const curTime = new Date().pattern('yyyy-MM-dd HH:mm:ss');
  upgradeError[curTime] = errorMsg;
  localStorage.setItem('upgradeError', JSON.stringify(upgradeError));
}
 
// 清除定时查询任务
function clearQueryProgress() {
  if (taskInterval) {
    clearTimeout(taskInterval);
    taskInterval = null;
  }
}
 
function getErrMsg(errorCode: number): string {
  let msg = traduction('IBMC_FIMWARE_FAILED');
  switch (errorCode) {
    case 2:
      msg = traduction('IBMC_UP_FILE_NOT_EXIST');
      break;
    case 3:
      msg = traduction('IBMC_UP_COMM_FILE_ERROR');
      break;
    case 4:
      msg = traduction('IBMC_UP_COMM_LITTLE_MEM');
      break;
    case 8:
      msg = traduction('IBMC_UP_OS_POWER_ERROR');
      break;
    case 9:
      msg = traduction('IBMC_UP_FIRMWARE_MISMATCH');
      break;
    case 12:
      msg = traduction('IBMC_UP_FIRMWARE_FILE_MISMATCH');
      break;
    case 13:
      msg = traduction('IBMC_UP_FIRMWARE_ERR_WRONG_ME_STATUS');
      break;
    case 27:
      msg = traduction('IBMC_UP_WHITEBRAND_FILE_MISMATCH');
      break;
    case 28:
      msg = traduction('IBMC_UP_FIRMWARE_ERR_RETRY');
      break;
    case 33:
      msg = traduction('IBMC_UP_COMM_FILE_TOO_EARLY');
      break;
    case 34:
      msg = traduction('IBMC_UP_OS_POWER_MCU_ERROR');
      break;
    case 35:
      msg = traduction('IBMC_UP_FIRMWARE_REVOKED');
      break;
    case 40:
      msg = traduction('IBMC_UP_COMPROCESSOR_FIRMWARE_UPGRADE_FAILED');
      break;
    case 70:
      msg = traduction('IBMC_UP_COMM_FILE_TOO_EARLY');
      break;
    case 205:
      msg = traduction('IBMC_UP_POWER_SUPPLY_INSUFFICIENT');
      break;
    case 248:
      msg = traduction('IBMC_UP_VRD_UPGRADE_IS_IN_PROGRESS');
      break;
    default:
      msg = traduction('IBMC_FIMWARE_FAILED');
      break;
  }
  recordUpgradeErrorLogs(msg);
  return msg;
}
 
// 固件升级状态提示
function displayUpgradeState(state: 'success' | 'failed' | 'clear', msg: string) {
  elNotification.closeAll();
  if (state === 'failed') {
    uploadError.value = msg;
    showElMessage('error', msg);
  } else if (state === 'success') {
    showElMessage('success', traduction('IBMC_FIMWARE_UPDATE_FIND'));
  }
}
 
function init() {
  if (upgradeActiveModeSupported.value && activeMode.value) {
    configRadioDisabled.value = true;
  } else {
    configSelected.value = 'yes';
    configRadioDisabled.value = isSystemLock.value;
  }
 
  modeDisabled.value = true;
  queryParallelTask();
}
 
function next() {
  emits('nextStep');
}
 
function handlePageChange(page: number) {
  currentPage.value = page;
  filterTable();
}
 
onMounted(() => {
  init();
});
onBeforeUnmount(() => {
  if (hpmUpload) {
    hpmUpload.abort();
  }
});
onUnmounted(() => {
  clearQueryProgress();
  elNotification.closeAll();
});
</script>
 
<template>
  <div class="step1-choose-mode">
    <el-form label-width="auto" label-position="left">
      <el-form-item class="upload-item" :label="$t('UPDATE_MODE')">
        <el-switch id="parallelEnable" v-model="mode" :disabled="modeDisabled || isSystemLock"></el-switch>
      </el-form-item>
      <el-form-item class="upload-item" :error="uploadError" :label="$t('IBMC_MANUAL_UPDATE')">
        <div class="upload-and-res">
          <FileUpload
            ref="uploadRef"
            class="upload-style"
            :data="uploadConfig"
            @set-error="displayUpgradeState"
          ></FileUpload>
          <div v-if="upgradeResult.result === 'success'" id="upgradeResult" class="upload-res">
            <el-icon v-if="upgradeResult.result === 'success'" :size="16">
              <IconSuccess />
            </el-icon>
            <span class="res-msg">{{ $t(upgradeResult.msg) }}</span>
          </div>
        </div>
        <el-progress v-if="onUpgrade" id="proUpdate" stroke-width="4" :percentage="progress" />
      </el-form-item>
      <!-- 生效分离 -->
      <el-form-item
        v-if="upgradeActiveModeSupported"
        id="activeModeSupported"
        class="active-mode-item"
        :label="$t('IBMC_MANUAL_SEPARATION')"
        size="default"
      >
        <el-checkbox
          v-model="activeMode"
          v-addId.checkbox="'activeMode'"
          :label="$t('IBMC_MANUAL_EFFECTIVE_MODE')"
          :disabled="isSystemLock"
          @change="changeActiveMode"
        />
        <span id="manualTip" class="manualTip">{{ $t('IBMC_MANUAL_TIP') }}</span>
      </el-form-item>
      <el-form-item v-if="hasUserConfig" :label="$t('CONFIG_SAVED_LABLE')">
        <!-- 是否保留配置升级 -->
        <div id="configSavedInfo">
          <el-radio
            v-model="configSelected"
            v-addId.radio="'configSave'"
            size="middle"
            label="yes"
            :disabled="retainedDisabled || mode || isSystemLock"
          >
            {{ $t('CONFIG_SAVED_YES') }}
          </el-radio>
          <el-radio
            v-model="configSelected"
            v-addId.radio="'configChange'"
            size="middle"
            label="no"
            :disabled="configRadioDisabled || mode || isSystemLock"
          >
            {{ $t('CONFIG_SAVED_NO') }}
          </el-radio>
          <!-- 是否保留配置升级说明Tip -->
          <span id="configSavedTip">{{ $t('CONFIG_SAVED_TIP', { softwareName: store.state.loct.sn }) }}</span>
        </div>
      </el-form-item>
      <el-form-item class="submit-item" label="">
        <el-button
          id="upgradeButton"
          :disabled="submitDisabled || (onUpgrade && progress !== 100)"
          type="primary"
          @click="resetDialog"
        >
          {{ $t('IBMC_UPGRADE_CONGIF_BTN') }}
        </el-button>
        <el-button
          id="next" 
          :disabled="tableData.length !== 0 &&
            tableData.some(item => !['Completed', 'Exception'].includes(item.state))" 
          @click="next"
        >
          {{ $t('UPDATE_NEXT') }}
        </el-button>
        <Dialog ref="dialogRef" :config="dialogConfig" @close="submitUpload"></Dialog>
        <!-- 不保留配置项提示弹窗 -->
        <Dialog ref="tipRef" :config="tipConfig" class="config-dialog" @close="tipClose">
          <div slot="other">
            <div class="tip-title">
              <div class="d-icon">
                <el-icon :size="16">
                  <IconRemind />
                </el-icon>
              </div>
              <div class="d-container">
                <div>{{ $t('CONFIG_SAVED_IBMC_RISK', { softwareName: store.state.loct.sn }) }}</div>
                <div>{{ $t('CONFIG_SAVED_BIOS_RISK') }}</div>
              </div>
            </div>
            <div class="tip-word">{{ $t('COMMON_ASK_OK') }}</div>
          </div>
        </Dialog>
      </el-form-item>
    </el-form>
    <div class="step1-check-status">
      <div class="step2-title">{{ $t('UPDATE_FIRMWARE_STATUS') }}</div>
    
      <div id="upgradeTableBox">
        <el-table
          v-addId.table="'upgradeTable'"
          :data="filteredTable"
          border
          resizable
        >
          <el-table-column
            v-for="item in columns"
            :key="item.title"
            :label="$t(item.title)"
            :min-width="item.width!"
            :sortable="item.sortable"
          >
            <template #default="scope">
              <span
                v-if="item.content === 'progress'"
                :id="item.content + scope.row.index"
                :class="['progress-bar-cell', item.content]"
              >
                <el-progress
                  id="proUpdate" stroke-width="8" :percentage="scope.row[item.content]"
                  v-bind="{status: scope.row.state === 'Exception' ? 'exception' : undefined}"
                  class="progress-bar"
                />
                <!-- ETA 信息，紧跟在进度条右侧 -->
                <span
                  v-if="typeof scope.row.eta === 'number'"
                  class="eta-info"
                >
                  {{ formatEta(scope.row.eta) }}
                </span>
              </span>
              <div
                v-else-if="item.content === 'state'"
                :id="item.content + scope.row.index"
                :class="item.content"
              >
                <el-tag v-if="scope.row[item.content] === 'Completed'" type="success">
                  {{ $t('IBMC_AUTOMATIC_SUCCESS') }}
                </el-tag>
                <el-tag v-else-if="scope.row[item.content] === 'Exception'" type="danger">
                  {{ $t('IBMC_AUTOMATIC_FAILED') }}
                </el-tag>
                <el-tag v-else-if="scope.row[item.content] === ''" type="info">{{ $t('UPDATE_BE_UPGRADED') }}</el-tag>
                <el-tag v-else type="primary">{{ $t('IBMC_AUTOMATIC_PROCEED') }}</el-tag>
              </div>
              <div v-else :id="item.content + scope.row.index" :class="item.content">
                {{ scope.row[item.content] }}
              </div>
            </template>
          </el-table-column>
          <template #empty>
            <TableNoData />
          </template>
        </el-table>
        <el-pagination
          v-if="tableData.length"
          v-model:page-size="pageSize"
          :current-page="currentPage"
          :page-sizes="[10, 15, 30, 50]"
          :total="tableData.length"
          layout="total, sizes, prev, pager, next, jumper"
          @current-change="handlePageChange"
        />
      </div>
    </div>
    <SecondPassword ref="secondRef" @close="confirmReset" />
  </div>
</template>

<style lang="scss" scoped>
$language-widths: (
  zh: 140px,
  ja: 140px,
  en: 140px,
  fr: 180px,
  ru: 200px,
);

.step1-choose-mode {
  height: calc(100% - 104px);
  .step1-check-status {
    height: calc(100% - 221px);
    #upgradeTableBox {
      height: calc(100% - 112px);
    }
  }
}
.step-container {
  width: 100%;
  height: 48px;
  position: relative;
  overflow: hidden;
  background-color: transparent;
  padding-top: 16px;
  .bg {
    width: 100%;
    height: 32px;
    position: relative;
    background-color: var(--o-bg-color-light);
    .active-bg {
      position: absolute;
      height: 100%;
      left: 0;
      top: 0;
      background-color: var(--o-color-brand);
      z-index: 1;
    }
    .text-content {
      position: absolute;
      width: 100%;
      height: 100%;
      left: 0;
      top: 0;
      z-index: 1;
      .box {
        position: relative;
        width: 100%;
        height: 100%;
        img {
          position: absolute;
          bottom: 0;
          width: 48px;
          height: 48px;
        }
        & > .text {
          position: absolute;
          font-size: 12px;
          line-height: 16px;
          font-weight: 600;
          color: var(--o-text-color-secondary);
          top: 8px;
          &.active {
            color: #fffffe;
          }
        }
      }
    }
  }
}
 
.step2-title {
  font-size: 16px;
  color: #000000;
  font-weight: bolder;
  line-height: 24px;
  margin: 16px 0;
}
.step2-button {
  margin-bottom: 16px;
}
 
.el-form {
  margin-top: 16px;
 
  :deep(.el-input) {
    max-width: 320px;
  }
}
 
.upload-item {
  :deep(.el-form-item__content) {
    display: block;
 
    .upload-and-res {
      display: flex;
      align-items: center;
 
      .upload-res {
        margin-left: 8px;
        display: flex;
        align-items: center;
 
        .res-msg {
          margin-left: 4px;
        }
      }
    }
  }
}
 
:deep(.active-mode-item) {
  .el-form-item__label {
    padding-top: 0;
    padding-bottom: 0;
  }
 
  .el-checkbox {
    height: auto;
  }
}
 
.submit-item {
  margin-bottom: 0;
}
 
.el-progress {
  margin-top: 8px;
  width: 320px;
}
 
.manualTip {
  margin-left: 8px;
  color: var(--o-text-color-tertiary);
}
.eta-info {
  text-align: right;
  color: var(--o-text-color-tertiary);
  font-size: 12px;
  flex-shrink: 0;
  display: inline-block;
  margin-left: 8px;
}
.progress-bar-cell {
  display: flex;
  align-items: center;
  :deep(.el-progress) {
    margin-top: 0 !important;
  }
}

@each $lang, $width in $language-widths {
  .#{$lang} {
    .eta-info {
      width: $width;
    }
    .progress-bar {
      width: calc(100% - #{$width});
    }
  }
}

</style>
<style lang="scss">
.step1-title {
  font-size: 16px;
  color: #000000;
  font-weight: bolder;
  line-height: 24px;
  margin-top: 16px;
}
</style>