<script setup lang="ts">
import { computed, reactive, defineProps, ref, onMounted, onUnmounted, onUpdated } from 'vue';
import { getStoreData, loading, setStoreData } from '@/utils/composition';
import { ITableStep3 } from '@/model/Manager/upgrade-interface';
import { traduction, getErrorTranslate } from '@/utils/language';
import useStore from '@/stores';
import { showElMessage, getMessageId, escapeHeader } from '@/utils/utils';
import UploadingIcon from '@/components/UploadingIcon/UploadingIcon.vue';
import { checkPrivil } from '@/apps/app-bmc/router/routes';
import { SecondAuthorityFail, SystemModel, UserPrivil } from '@/model/base-enum';
import {
  queryTaskProgress,
  getUpgradeInfo,
  getActiveInfo,
  getFirmwareList
} from '../../upgrade.services';
import { showFailedMessage } from '@/utils/composition';

const store = useStore();
const isSystemLock = computed(() => {
  return store.state.glob.systemLocked;
});
const props = defineProps({});
const emits = defineEmits(['previousStep']);
const enabledType = ref([]);
// 常规配置权限
const isBaseConfig = checkPrivil(UserPrivil.baseConfig);
const hasPowerControlPrivil = checkPrivil(UserPrivil.powerControl);
// 生效前确认弹窗
const dialogConfig = reactive({
  id: 'activeDialog',
  content: traduction('COMMON_ASK_OK'),
  title: traduction('ALARM_OK')
});
const canActive = ref(true);
// 查询升级
const isActive = computed(() => {
  return store.state.glob.isActive;
});
const columns: ITableColumns[] = [
  {
    title: 'EVENT_ORDER',
    width: '10%',
    content: 'id'
  },
  {
    title: 'UPDATE_FIRMWARE_TYPE',
    width: '35%',
    content: 'firmwareType'
  },
  {
    title: 'UPDATE_ACTIVE_STATUS',
    width: '35%',
    content: 'activeStatus'
  },
  {
    title: 'UPDATE_ACTIVE_OPERATION',
    width: '20%',
    content: 'activeAction'
  }
];

let tableData: any = reactive({ data: [] });
let preData: ITableStep3[] = reactive([]);
const radioList = reactive([
  {
    id: '0',
    value: 'ResetBMC',
    label: traduction('IBMC_REST_IBMC', { softwareName: store.state.loct.sn }),
  },
  {
    id: '1',
    value: 'PowerOff',
    label: traduction('UPDATE_POWER_OFF'),
    disabled: !hasPowerControlPrivil,
  },
  {
    id: '2',
    value: 'PowerOn',
    label: traduction('UPDATE_POWER_ON'),
    disabled: !hasPowerControlPrivil,
  },
]);

const productLabel = store.state.loct.sn;
const loct: any = localStorage.getItem('loct');
const dialogRef = ref();
const tipRef = ref();
const alertInfo = traduction('IBMC_FIMWARE_TIP_INFO', { softwareName: productLabel });
let hpmUpload: any = null;
let formData = ref(); // 表单数据
// 表示进度条的显示状态
const onUpgrade = ref(false);
const submitDisabled = ref(true);
const progress = ref(0);
// 升级进度查询
let taskInterval: any = null;
let taskStateErrorAmount = 0;
let taskInfoErrorAmount = 0;
// 记录网络失败次数
let networkErrorAmount = 0;
const upgradeResult = reactive({
  result: '',
  msg: ''
});
let currentPage = ref(1);
const uploadError = ref('');
let pageSizeCount = ref(10);
let total = ref(0);

let fileItem: any = null;

const hasUserConfig = checkPrivil(UserPrivil.userConfig);

// 开始执行升级流程
function startActive() {
  onUpgrade.value = false;
  progress.value = 0;
  getActiveInfo(enabledType.value).then(
    (res: any) => {
      const url = res.data.url;
      onUpgrade.value = false;
      showElMessage('success', traduction('COMMON_SUCCESS'));
      queryTask();
    },
    err => {
      onUpgrade.value = false;
      const errorId = getMessageId(err.data);
      const errorMsg =
        getErrorTranslate(errorId?.[0]?.code as string) || traduction('COMMON_FAILED');
      showElMessage('error', errorMsg);
      uploadError.value = errorMsg;
    }
  );
}

// 升级完成后处理逻辑
function taskCompleted(taskData: any) {
  clearQueryProgress();
  progress.value = 100;
  setTimeout(() => {
    onUpgrade.value = false;
  }, 120000);

  store.state.glob.setGlobState({ type: 'isActive', value: false });
}

function taskOtherCases(taskData: any) {
  taskStateErrorAmount++;
  if (taskStateErrorAmount > 10) {
    const state = taskData?.TaskState || 'TaskState is not valid.';
    executeUpgradeFailed(taskData.ErrorCode);
    store.state.glob.setGlobState({ type: 'isActive', value: false });
    return;
  }
  reQueryProgress();
}

async function queryTask() {
  store.state.glob.setGlobState({ type: 'isActive', value: true });
  onUpgrade.value = true;
  try {
    const [res1, res2] = await Promise.all([getUpgradeInfo(), getFirmwareList()]);
    const taskData = res1.data;
    const tableNewData = res2?.data?.PendingFirmwareList || [];
    getTableInfo(tableNewData);
    getProgress(taskData);
  } catch (error) {
    getTaskError(error);
  }
}

function getTableInfo(res: any) {
  preData.splice(0);
  const tempData = JSON.parse(JSON.stringify(res as any));
  for (let index = 0; index < tempData.length; index++) {
    preData.push({
      id: index + 1,
      firmwareType: tempData[index].FirmwareType,
      activeStatus: tempData[index].ActiveStatus,
      activeAction: tempData[index].ActiveAction
    });
  }
  let arr = tempData.filter((item: any) => item.ActiveStatus === 'Activating');
  if (tempData.length !== 0 && arr.length === 0) {
    canActive.value = true;
  } else {
    canActive.value = false;
  }
  total.value = preData.length;
  handleSizeChange(pageSizeCount.value);
}

function getTaskError(error: any) {
  taskInfoErrorAmount++;
  // 出现状态不对时，重试次数为10次
  if (taskInfoErrorAmount > 10) {
    store.state.glob.setGlobState({ type: 'isActive', value: false });
    setTimeout(() => {
      onUpgrade.value = false;
    }, 120000);
    const code = error?.data?.error?.[0]?.code;
    if (code) {
      let errorMessage = code + '.errorMessage';
      showFailedMessage(traduction(errorMessage));
      return;
    }
    showFailedMessage();
    return;
  }
  reQueryProgress();
}
// 固件升级进度函数拆分
function getProgress(taskData: any): void {
  if (taskData?.ActiveUrl) {
    reQueryProgress();
  } else {
    taskCompleted(taskData);
  }
}

function reQueryProgress() {
  taskInterval = window.setTimeout(() => {
    queryTask();
  }, 2000);
}

// 清除定时任务
function clearQueryProgress() {
  if (taskInterval) {
    clearTimeout(taskInterval);
    taskInterval = null;
  }
}

function executeUpgradeFailed(errorCode: number) {
  onUpgrade.value = false;
  let msg = traduction('COMMON_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 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('COMMON_FAILED');
      break;
  }
  displayUpgradeState('failed', msg);
}

function displayUpgradeState(state: 'success' | 'failed' | 'clear', msg: string) {
  if (state === 'failed') {
    uploadError.value = msg;
    showElMessage('error', msg);
  } else if (state === 'success') {
    showElMessage('success', traduction('IBMC_FIMWARE_UPDATE_FIND'));
  }
}
function init() {
  loading(true);
  getUpgradeInfo().then(resTemp => {
    const upgradeUrl = resTemp.data?.UpgradeUrl;
    const isUpdating = resTemp.data?.UpdatingFlag || false;
    const activeUrl = resTemp.data?.ActiveUrl;
    getFirmwareList()
      .then((res: any) => {
        getTableInfo(res?.data?.PendingFirmwareList || []);
      })
      .catch((err: any) => {
        const errorCode = err?.data?.error?.[0]?.code;
        if (errorCode) {
          showFailedMessage(getErrorTranslate(errorCode));
        }
      })
      .finally(() => {
        if (Boolean(activeUrl) && !Boolean(isUpdating)) {
          store.state.glob.setGlobState({ type: 'isActive', value: true });
          queryTask();
        } else {
          store.state.glob.setGlobState({ type: 'isActive', value: false });
        }
        loading(false);
      });
  });
}

function openSec() {
  dialogRef.value.show();
}

function continueActive(reason: any) {
  dialogRef.value.hide();
  if (reason) {
    startActive();
  }
}

const handleSizeChange = (val: number) => {
  pageSizeCount.value = val;
  currentPage.value = 1;
  pageChange();
};
function pageChange() {
  let start = total.value - ((currentPage.value - 1) * pageSizeCount.value);
  if (start === 0) {
    currentPage.value = 1;
  }
  tableData.data = JSON.parse(JSON.stringify(preData)).slice(
    (currentPage.value - 1) * pageSizeCount.value,
    pageSizeCount.value * currentPage.value
  );
}
const handleCurrentChange = (val: number) => {
  pageChange();
};

onMounted(() => {
  init();
});
onUnmounted(() => {
  clearQueryProgress();
});

function back() {
  emits('previousStep');
}
</script>
<template>
  <div class="step3-enabled-container">
    <el-form>
      <el-form-item :label="$t('UPDATE_ACTIVE_MODE')">
        <div id="configSavedInfo">
          <el-checkbox-group
            v-model="enabledType"
            :disabled="isActive || !canActive || isSystemLock || !isBaseConfig"
          >
            <el-checkbox
              v-for="item in radioList"
              :id="item.id"
              :key="item.id"
              :label="item.label"
              :value="item.value"
              :disabled="item.disabled"
            />
          </el-checkbox-group>
        </div>
      </el-form-item>
    </el-form>
    <div class="step3-button">
      <el-button id="previous" @click="back" :disabled="isActive">
        {{ $t('UPDATE_PREVIOUS') }}
      </el-button>
      <el-button
        id="activateButton"
        type="primary"
        :disabled="
          isActive || !canActive || isSystemLock || !isBaseConfig || enabledType.length === 0
        "
        @click="openSec"
      >
        {{ $t('UPDATE_ACTIVATE') }}
      </el-button>
      <div class="step3-progress">
        <el-progress
          v-if="false"
          id="proUpdate"
          stroke-width="4"
          :percentage="progress"
        />
      </div>
    </div>
    <div class="step3-content-title">
      {{ $t('UPDATE_FIRMWARE_ACTIVE_STATUS') }}
    </div>
    <div id="enabledTableBox">
      <el-table
        v-addId.table="'enableTable'"
        :data="tableData.data"
        :default-sort="sort"
        border
        resizable
        :height="344"
        @sort-change="sortChange"
      >
        <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">
            <div
              v-if="item.content === 'activeStatus'"
              :id="item.content + scope.row.id"
              :class="item.content"
            >
              <el-tag v-if="scope.row[item.content] === 'ToBeActivated'" type="info">
                {{ $t('UPDATE_BE_ACTIVATED') }}
              </el-tag>
              <el-tag v-else-if="scope.row[item.content] === 'Activating'" type="primary">
                {{ $t('UPDATE_ACTIVATING') }}
              </el-tag>
              <el-tag v-else type="success">{{ $t('UPDATE_ACTIVATED') }}</el-tag>
            </div>
            <div
              v-else-if="item.content === 'activeAction'"
              :id="item.content + scope.row.id"
              :class="item.content"
            >
              <span v-if="scope.row[item.content] === 'ResetBMC'">
                {{ traduction('IBMC_REST_IBMC', { softwareName: store.state.loct.sn }) }}
              </span>
              <span v-else-if="scope.row[item.content] === 'PowerOff'">
                {{ $t('UPDATE_POWER_OFF') }}
              </span>
              <span v-else-if="scope.row[item.content] === 'PowerOn'">
                {{ $t('UPDATE_POWER_ON') }}
              </span>
              <span v-else-if="scope.row[item.content] === 'ACCycle'">
                {{ $t('IBMC_AC_CYCLE', { softwareName: store.state.loct.sn }) }}
              </span>
            </div>
            <span v-else :id="item.content + scope.row.id" :class="item.content">
              {{ scope.row[item.content] }}
            </span>
          </template>
        </el-table-column>
        <template #empty>
          <TableNoData />
        </template>
      </el-table>
      <el-pagination
        v-if="tableData.data.length > 0"
        v-model:currentPage="currentPage"
        v-addId.pagination="'eventPagination'"
        :page-sizes="[10, 15, 30, 50]"
        :page-size="pageSizeCount"
        layout="total, prev, pager, next, sizes, jumper"
        :total="total"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>
    <Dialog ref="dialogRef" :config="dialogConfig" @close="continueActive"></Dialog>
  </div>
</template>
<style lang="scss">
.step3-enabled-container {
  margin-top: 16px;
}
.step3-title {
  font-size: 16px;
  color: #000000;
  font-weight: bolder;
  line-height: 24px;
  margin-top: 16px;
}
.step3-content-title {
  font-size: 16px;
  color: #000000;
  font-weight: bolder;
  line-height: 24px;
  margin: 32px 0 16px;
}
.step3-button {
  display: flex;
  align-items: center;
  .step3-progress {
    margin-left: 16px;
    width: 282px;
  }
}
</style>
<style lang="scss" scoped>
.el-form {
  .el-form-item {
    margin-bottom: 8px;
  }
}
</style>
