<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 CustomAlert from '@/components/CustAlert/CustAlert.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,
  upgradeStaged,
  deleteStaged,
  unpackFullImage,
} 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, IFirmwarePackage, IUpgradeTaskRaw } 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 multihost = computed(() => getStoreData('loct', 'multihost'));

const loct: any = localStorage.getItem('loct');
const dialogRef = ref();
const stagedDialogRef = ref();
const tipRef = ref();
const uploadRef = ref();
const isStage = ref(false);
const isUpgrade = ref(false);
const selectedStageFirmware = ref<ITableStep2[]>([]);
const currentPage = ref(1);
const pageSize = ref(10);
const isFullImage = ref(false);
let modeBeforeFullImage: boolean | null = null;
const fullImageDialogVisible = ref(false);
const firmwareList = ref<IFirmwarePackage[]>([]);
const firmwareSelection = ref<IFirmwarePackage[]>([]);
let hpmUpload: any = null;

// 表示进度条的显示状态
const onUpgrade = ref(false);
const submitDisabled = ref(true);
const uploadDisabled = ref(false);
const progress = ref(0);
// 升级进度查询
let checkClearTimeout: ReturnType<typeof setTimeout> | null = null;
// 延迟重查进行中标志，防止回调执行期间递归创建新的定时器
let isDelayedRequery = false;
let taskInterval: any = null;
let isUnmounted = false;

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 forceUpdate = ref(true);
const forceUpdateDisabled = 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,.zip',
  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 isZip = subfix === 'zip';
    const size = file.size;
    // 文件大小限制为 110M，大包升级限制只能并行升级，且不支持暂存升级
    const maxSize = 1024 * 1024 * 110;
    // 文件格式错误
    if (subfix !== 'hpm' && !isZip) {
      uploadError.value = traduction('IBMC_UP_FILE_FORMAT_ERROR');
      return false;
    } else if (size && size > maxSize) {
      uploadError.value = traduction('IBMC_UPLOAD_FILE_110M_ERROR');
      return false;
    } else {
      fileItem = file;
      submitDisabled.value = false;
      if (isZip) {
        isFullImage.value = true;
        modeBeforeFullImage = mode.value;
        mode.value = true;
      } else {
        resetFullImageMode();
      }
      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();
    resetFullImageMode();
    retainedDisabled.value = false;
    configRadioDisabled.value = false;
    uploadDisabled.value = false;
    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[]) => {
    notifyUploadSuccess();
    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;
  },
});
// 上传成功通知
function notifyUploadSuccess() {
  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,
  });
}

// 重置整包升级模式，恢复用户原有的并行/串行选择
function resetFullImageMode() {
  isFullImage.value = false;
  if (modeBeforeFullImage !== null) {
    mode.value = modeBeforeFullImage;
    modeBeforeFullImage = null;
  }
}

function handleFirmwareSelectionChange(val: IFirmwarePackage[]) {
  firmwareSelection.value = val;
}

function closeFullImageDialog(restoreUI = true) {
  fullImageDialogVisible.value = false;
  firmwareList.value = [];
  firmwareSelection.value = [];
  if (restoreUI) {
    resetFullImageMode();
    modeDisabled.value = false;
    forceUpdateDisabled.value = false;
    retainedDisabled.value = false;
    configRadioDisabled.value = false;
    uploadDisabled.value = false;
    uploadConfig.disabled = isSystemLock.value;
    uploadRef.value.clear();
  }
}

// 处理导入升级文件失败
function handleImportError(err: any) {
  onUpgrade.value = false;
  elNotification.closeAll();
  uploadRef.value.clear();
  resetFullImageMode();
  uploadDisabled.value = false;
  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);
  }
}

function handleFullImageUpgrade() {
  const selectedFiles = firmwareSelection.value.map((item: IFirmwarePackage) => item.FileName);
  closeFullImageDialog(false);
  // 整包升级必须走并行模式，保存当前模式以便升级完成后还原
  modeBeforeFullImage = mode.value;
  mode.value = true;
  showUpgradingNotification();
  beginImportUpgradeFile(fileItem?.name ?? 'fullImage.zip', selectedFiles, 'FullImage');
}

// 开始执行升级流程
async function beginImportUpgradeFile(name: any, selectedFirmwareNames?: string[], imageType?: string) {
  // 设置导入文件进度，并开始导入文件
  progress.value = 0;
  // 如果是大包升级，需要先解压文件
  try {
    let res;
    if (isFullImage.value) {
      isFullImage.value = false;
      res = await unpackFullImage(name);
    } else if (mode.value) {
      res = await importParallelUpdate({
        fileName: name,
        forceUpdate: forceUpdate.value,
        isStage: isStage.value,
        imageType,
        firmwareList: selectedFirmwareNames,
      });
    } else {
      res = await importUpgradeFile(
        name, configSelected.value, forceUpdate.value, isStage.value,
      );
    }
    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: any) {
    handleImportError(err);
  }
}

// 升级前确认弹窗
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,
};

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 upgrade(): void {
  isStage.value = false;
  resetDialog();
}

function tempStorage(): void {
  isStage.value = true;
  resetDialog();
}

function upgradeStagedFirmware(): void {
  isUpgrade.value = true;
  stagedDialogRef.value.show();
}

function deleteStagedFirmware(): void {
  isUpgrade.value = false;
  stagedDialogRef.value.show();
}

async function stagedFirmwareOperation(reason: boolean): Promise<void> {
  if (!reason) {
    stagedDialogRef.value.hide();
    return;
  }
  try {
    if (isUpgrade.value) {
      await upgradeStaged(selectedStageFirmware.value.map(item => item.firmwareId ?? ''));
    } else {
      await deleteStaged(selectedStageFirmware.value.map(item => item.firmwareId ?? ''));
    }
    elNotification.closeAll();
    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: any) {
    const errorId = getMessageId(err.data);
    const errorMsg = getErrorTranslate(errorId[0]?.code as string) || traduction('COMMON_FAILED');
    showElMessage('error', errorMsg);
  } finally {
    stagedDialogRef.value.hide();
  }
}

function startToUpload(key?: string) {
  // 点击确定后，开始升级，并将进度清0, 升级状态复位
  progress.value = 10;
  upgradeResult.result = '';
  upgradeResult.msg = '';
  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();
  resetFullImageMode();
  configSelected.value = 'yes';
  bmcUpdating = false;
  elNotification.closeAll();
  onUpgrade.value = false;
  retainedDisabled.value = false;
  configRadioDisabled.value = false;
  modeDisabled.value = false;
  forceUpdateDisabled.value = false;
  uploadDisabled.value = false;
  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;
  fullImageProgressMap.clear();
}

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);
  const isJBOGRetimer = ['JBOGRetimer'].includes(componentName);
  if (isBIOS || isCPLD || isJBOGRetimer) {
    if (upgradeModeData.value?.PowerState[0].State !== 'Off') {
      return isCPLD ? 'IBMC_AFTER_CPLD' : 'IBMC_AFTER_REBOOT';
    } else if (isJBOGRetimer) {
      return 'IBMC_FIMWARE_FAILED';
    }
  }
  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();
    bmcUpdating = false;
    elNotification.closeAll();
    onUpgrade.value = false;
    retainedDisabled.value = false;
    configRadioDisabled.value = false;
    modeDisabled.value = false;
    forceUpdateDisabled.value = false;
    uploadDisabled.value = false;
    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]);
  }
}

// 整包升级模拟解压进度记录（key 为 FileName）
const fullImageProgressMap = new Map<string, number>();

// 根据 TaskState 计算模拟进度百分比
function getSimulatedPercentage(fileName: string, taskState: string): string {
  const prev = fullImageProgressMap.get(fileName) ?? 0;
  let pct = prev;
  if (taskState === 'Completed') {
    pct = 100;
  } else if (taskState === 'Running') {
    const step = Math.floor(Math.random() * 6) + 3;
    pct = Math.min(prev + step, 90);
  }
  fullImageProgressMap.set(fileName, pct);
  return `${pct}%`;
}

// 将 FullImageUnpacking 模式的任务列表转换为 parseUpgradeTasks 所需的通用格式
function normalizeFullImageTasks(tasks: any[]): IUpgradeTaskRaw {
  const subTaskList: IUpgradeTaskRaw[] = tasks.map((item: any) => ({
    TaskState: item.TaskState ?? '',
    FileName: item.FileName ?? '',
    Firmware: item.Component ?? '',
    Component: item.Component ?? '',
    ErrorCode: 0,
    Percentage: '',
    EstimatedRemainingTime: '',
    FirmwareId: '',
  }));
  // 根据子任务状态推导整体状态
  const allCompleted = tasks.every((t: any) => t.TaskState === 'Completed');
  const hasException = tasks.some((t: any) => t.TaskState === 'Exception');
  let taskState = 'Running';
  if (allCompleted) {
    taskState = 'Completed';
  } else if (hasException) {
    taskState = 'Exception';
  }

  return {
    TaskState: taskState,
    FileName: '--',
    Component: 'FullImageUnpacking',
    ErrorCode: 0,
    Percentage: getSimulatedPercentage('FullImageUnpacking', taskState),
    EstimatedRemainingTime: '',
    FirmwareId: '',
    firmwareList: subTaskList,
  };
}

// 解析升级任务列表
function parseUpgradeTasks(tasks: any[]) {
  tableData.splice(0);
  tasks.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,
      firmwareId: item.FirmwareId ?? '',
    };
    if (task.state === 'Completed') {
      task.description = errCode === 0 ? traduction(getSuccessMessage(task.name)) : getErrMsg(errCode);
    }
    tableData.push(task);
  });
  filterTable();
}

// 重置升级相关 UI 状态
function resetUpgradeUI() {
  clearQueryProgress();
  elNotification.closeAll();
  resetFullImageMode();
  modeDisabled.value = false;
  forceUpdateDisabled.value = false;
  retainedDisabled.value = false;
  configRadioDisabled.value = false;
  // 如果当前没有上传进行中，才重置上传组件状态
  if (!onUpgrade.value) {
    uploadDisabled.value = false;
    uploadConfig.disabled = isSystemLock.value;
    uploadRef.value.clear();
  }
}

// 整包解压完成：清理相关状态 + 弹出固件选择对话框
function handleFullImageCompleted(res: any) {
  clearQueryProgress();
  bmcUpdating = false;
  elNotification.closeAll();
  fullImageProgressMap.clear();
  tableData.splice(0); // 清空升级记录表格
  filterTable();
  if (!fullImageDialogVisible.value) {
    fullImageDialogVisible.value = true;
  }
  firmwareList.value = res.data?.UpgradeTasks?.[0]?.firmwareList ?? [];
}

// 显示升级中通知
function showUpgradingNotification() {
  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;
}

// 升级完成/失败后，15秒延迟重新查询一次任务状态（防抖：轮询期间每次重置计时器，仅触发一次）
function scheduleDelayedRequery() {
  if (isDelayedRequery) {
    return;
  }
  const hasFinishedTask = tableData.some(item => ['Completed', 'Exception'].includes(item.state));
  if (!hasFinishedTask) {
    return;
  }
  // 取消上一次的延迟查询，避免重复请求
  if (checkClearTimeout) {
    clearTimeout(checkClearTimeout);
    checkClearTimeout = null;
  }
  checkClearTimeout = setTimeout(async () => {
    checkClearTimeout = null;
    if (isUnmounted) {
      return;
    }
    isDelayedRequery = true;
    await queryParallelTask();
    isDelayedRequery = false;
  }, 15000);
}

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);
    failCount.value = 0;
  } catch (err) {
    handleReqError(err);
    return;
  }
  // 如果是整包升级，则需要先处理任务列表，把任务列表处理为通用格式
  if (res.data?.UpgradeMode === 'FullImageUnpacking') {
    res.data.UpgradeTasks = [normalizeFullImageTasks(res.data.UpgradeTasks ?? [])];
  }
  parseUpgradeTasks(res.data?.UpgradeTasks ?? []);
  setStoreData(
    'glob',
    'isUpgrading',
    !tableData.every(item => ['Exception', 'Completed', 'Staged'].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));
  forceUpdateDisabled.value = modeDisabled.value;
  if (modeDisabled.value) {
    showUpgradingNotification();
    taskInterval = setTimeout(queryParallelTask, 2000);
  } else if (tableData.length > 0 && tableData.every(item => item.state === 'Completed')) {
    if (res.data?.UpgradeMode === 'FullImageUnpacking') {
      handleFullImageCompleted(res);
    } else {
      taskParallelCompleted();
    }
  } else {
    resetUpgradeUI();
  }
  scheduleDelayedRequery();
}

// 记录升级失败日志
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;
  }
}

// 错误码 → 国际化 key 映射
const errMsgMap: Record<number, string> = {
  2: 'IBMC_UP_FILE_NOT_EXIST',
  3: 'IBMC_UP_COMM_FILE_ERROR',
  4: 'IBMC_UP_COMM_LITTLE_MEM',
  8: 'IBMC_UP_OS_POWER_ERROR',
  9: 'IBMC_UP_FIRMWARE_MISMATCH',
  12: 'IBMC_UP_FIRMWARE_FILE_MISMATCH',
  13: 'IBMC_UP_FIRMWARE_ERR_WRONG_ME_STATUS',
  27: 'IBMC_UP_WHITEBRAND_FILE_MISMATCH',
  28: 'IBMC_UP_FIRMWARE_ERR_RETRY',
  33: 'IBMC_UP_COMM_FILE_TOO_EARLY',
  34: 'IBMC_UP_OS_POWER_MCU_ERROR',
  35: 'IBMC_UP_FIRMWARE_REVOKED',
  40: 'IBMC_UP_COMPROCESSOR_FIRMWARE_UPGRADE_FAILED',
  70: 'IBMC_UP_COMM_FILE_TOO_EARLY',
  72: 'IBMC_UP_BIOS_POST',
  73: 'IBMC_UP_STAGE_FAILED',
  74: 'IBMC_UP_STAGE_SUCCEED',
  75: 'IBMC_UP_DELETE_STAGE_FAILED',
  76: 'IBMC_UP_DELETE_STAGE_SUCCEED',
  205: 'IBMC_UP_POWER_SUPPLY_INSUFFICIENT',
  248: 'IBMC_UP_VRD_UPGRADE_IS_IN_PROGRESS',
};

function getErrMsg(errorCode: number): string {
  const msg = traduction(errMsgMap[errorCode] ?? 'IBMC_FIMWARE_FAILED');
  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;
  forceUpdateDisabled.value = true;
  queryParallelTask();
}

function next() {
  emits('nextStep');
}

function handlePageChange(page: number) {
  currentPage.value = page;
  filterTable();
}

onMounted(() => {
  init();
});
onBeforeUnmount(() => {
  if (hpmUpload) {
    hpmUpload.abort();
  }
});
onUnmounted(() => {
  isUnmounted = true;
  clearQueryProgress();
  elNotification.closeAll();

  if (checkClearTimeout) {
    clearTimeout(checkClearTimeout);
    checkClearTimeout = null;
  }
});
</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 || isFullImage"
        ></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="upload-item" :label="$t('FORCE_UPDATE_LABEL')">
        <el-switch id="forceUpdate" v-model="forceUpdate" :disabled="forceUpdateDisabled || isSystemLock"></el-switch>
        <span id="forceUpdateTip" class="forceUpdateTip">{{ $t('FORCE_UPDATE_TIP') }}</span>
      </el-form-item>
      <el-form-item class="submit-item" label="">
        <el-button
          id="upgradeButton"
          :disabled="submitDisabled || (onUpgrade && progress !== 100)"
          type="primary"
          @click="upgrade"
        >
          {{ $t('IBMC_UPGRADE_CONGIF_BTN') }}
        </el-button>
        <el-button
          id="tempStorageButton"
          :disabled="submitDisabled || (onUpgrade && progress !== 100) || isFullImage"
          @click="tempStorage"
        >
          {{ $t('IBMC_UPGRADE_TEMP_STORAGE_BTN') }}
        </el-button>
        <span id="delimiter"></span>
        <el-button
          id="next" 
          :disabled="tableData.length !== 0 &&
            tableData.some(item => !['Completed', 'Exception', 'Staged'].includes(item.state))" 
          @click="next"
        >
          {{ $t('UPDATE_NEXT') }}
        </el-button>
        <Dialog ref="dialogRef" :config="dialogConfig" @close="submitUpload"></Dialog>
        <Dialog ref="stagedDialogRef" :config="dialogConfig" @close="stagedFirmwareOperation"></Dialog>
        <!-- 不保留配置项提示弹窗 -->
        <Dialog ref="tipRef" :config="tipConfig" class="config-dialog" @close="tipClose">
          <template #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>
          </template>
        </Dialog>
      </el-form-item>
    </el-form>
    <div class="step1-check-status">
      <div class="step2-title">{{ $t('UPDATE_FIRMWARE_STATUS') }}</div>
      <div class="stageBtnGroup">
        <el-button
          :disabled="modeDisabled || isSystemLock || selectedStageFirmware.length === 0"
          @click="upgradeStagedFirmware"
        >
          {{ $t('IBMC_UPGRADE_STAGED_FIRMWARE_BTN') }}
        </el-button>
        <el-button
          :disabled="isSystemLock || selectedStageFirmware.length === 0"
          @click="deleteStagedFirmware"
        >
          {{ $t('IBMC_DELETE_STAGED_FIRMWARE_BTN') }}
        </el-button>
      </div>
      <div id="upgradeTableBox">
        <el-table
          v-addId.table="'upgradeTable'"
          :data="filteredTable"
          border
          resizable
          @selection-change="(rows: ITableStep2[]) => selectedStageFirmware = rows"
        >
          <el-table-column
            type="selection"
            width="55"
            :selectable="(row: ITableStep2) => !isSystemLock && row.state === 'Staged'"
          ></el-table-column>
          <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' && scope.row.state === 'Staged'">--</span>
              <span
                v-else-if="item.content === 'progress' && scope.row.state !== 'Staged'"
                :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] === 'Staged'" type="other">
                  {{ $t('IBMC_AUTOMATIC_STAGED') }}
                </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" />
    <!-- 整包升级选择固件包 -->
    <el-dialog
      v-model="fullImageDialogVisible"
      :title="$t('IBMC_SELECT_FIRMWARE_PACKAGE')"
      class="full-image-dialog"
      :close-on-press-escape="false"
      :close-on-click-modal="false"
      @close="closeFullImageDialog"
    >
      <CustomAlert id="alertType" :content="$t('IBMC_FIRMWARE_PACKAGE_SELECT_TIP')" />
      <div class="full-image-list-table-top">
        <span class="full-image-list-table-title">{{ $t('IBMC_FIRMWARE_PACKAGE_LIST') }}</span>
        <i18n-t keypath="IBMC_SELECTED_PACKAGES_COUNT" tag="span" class="full-image-list-table-info">
          <template #count>
            <span class="full-image-list-table-info-count">{{ firmwareSelection.length }}</span>
          </template>
        </i18n-t>
      </div>
      <div class="full-image-table-container">
        <el-table
          class="full-image-table"
          :header-row-style="{ backgroundColor: 'transparent', padding: 0 }"
          :header-cell-style="{ backgroundColor: 'transparent', padding: '4px 0'}"
          :row-style="{ backgroundColor: 'transparent'}"
          :cell-style="{ padding: '4px 0' }"
          :data="firmwareList"
          @selection-change="handleFirmwareSelectionChange"
        >
          <el-table-column type="selection" />
          <el-table-column property="FileName" :label="$t('UPDATE_PACKAGE_NAME')" />
          <el-table-column property="Firmware" :label="$t('COMMON_TYPE')" />
        </el-table>
      </div>
      <template #footer>
        <div class="dialog-footer">
          <el-button :disabled="firmwareSelection.length === 0" type="primary" @click="handleFullImageUpgrade">
            {{ $t('COMMON_OK') }}
          </el-button>
          <el-button @click="closeFullImageDialog">{{ $t('COMMON_CANCEL') }}</el-button>
        </div>
      </template>
    </el-dialog>
  </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 {
      margin-top: 14px;
      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 10px 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;
  }
}

#configSavedTip {
  color: var(--o-text-color-tertiary);
}

.forceUpdateTip {
  margin-left: 40px;
  vertical-align: middle;
  color: var(--o-text-color-tertiary);
}

#delimiter::after {
  content: ' ';
  margin: 0 16px;
  display: block;
  height: 32px;
  border-right: 1px solid var(--o-border-color-base);
}

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

:deep(.el-tag--other) {
  background-color: #2a739d;
  color: #ffffff;
}

:deep(.full-image-dialog) .el-dialog__body {
  max-height: unset;
}

.full-image-list-table-top {
  margin-top: 16px;
  margin-bottom: 8px;
  display: flex;
  gap: 16px;
}

.full-image-list-table-title {
  font-size: 14px;
  color: var(--o-text-color-primary);
  font-weight: bolder;
  line-height: 22px;
}

.full-image-list-table-info {
  font-size: 12px;
  line-height: 22px;
}

.full-image-list-table-info-count {
  font-weight: bold;
  color: var(--o-text-color-primary);
  display: inline-block;
  background-color: var(--o-border-color-light);
  border-radius: 10px;
  padding: 0 10px;
  margin-left: 8px;
  margin-right: 8px;
}

.full-image-table-container {
  padding: 16px;
  background-color: var(--o-bg-color-light) !important;
  height: 400px;
}

.full-image-table {
  background-color: var(--o-bg-color-light) !important;
}
</style>

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