<script setup lang="ts">
import { traduction, getErrorTranslate } from '@/utils/language';
import { computed, onMounted, onUnmounted, reactive, ref, watch } from 'vue';
import { useRouter } from 'vue-router';
import { UI_REST_FIRMWAREINVENTORY } from '@/api/api';
import { UploadFile } from 'element-plus/es/components/upload/src/upload';
import useStore from '@/stores';
import { SecondAuthorityFail } from '@/pages/User/models/model';
import { configExport, getGenericInfo, getTask } from '@/services/export-config-service';
import { downloadFileWithResponse, generalDownLoadFile } from '@/utils/common-service';
import { notificationIcons } from '@/model/base-constant';
import { importConfig, queryProgress } from '@/services/config-update.service';
import { IResponse } from '@/model/base-interface';
import { ElNotification as elNotification } from 'element-plus';
import { getBytes, escapeHeader, showElMessage, getMessageId } from '@/utils/utils';
import { getStoreData, setStoreData } from '@/utils/composition';
import Dialog from '@/components/Dialog/Dialog.vue';
import RefreshIcon from '@/components/RefreshIcon/RefreshIcon.vue';
import SecondPassword from '@/components/SecondPassword/SecondPassword.vue';
import FileUpload from '@/components/FileUpload/FileUpload.vue';
import CustAlert from '@/components/CustAlert/CustAlert.vue';
import UploadingIcon from '@/components/UploadingIcon/UploadingIcon.vue';

const isNoPwd = getStoreData('loct', 'nopwd');
const sn = getStoreData('loct', 'sn');
const isSystemLocked = computed(() => {
  return getStoreData('glob', 'systemLocked');
});
const multihost = getStoreData('loct', 'multihost');
let isIrm = false;
let fileItem: any = null;
let noticeInstance: any = null;
const secondRef = ref();
const store = useStore();
const router = useRouter();
const exportState = ref(false);
const dialogRef = ref();
const importState = ref(true);
const importCtrlRef = ref();
const curOperator = ref('');
const secondPwd = ref('');
const isInit = ref(true);
let fileName = '';

// Dialog弹出框配置
const dialogConfig = reactive({
  title: traduction('COMMON_INFORMATION'),
  content: traduction('CONFIG_UPGRADE_CONFIRM_TIP'),
  id: 'exportConfigModal',
  okButton: { label: traduction('COMMON_OK') },
  cancelButton: { label: traduction('COMMON_CANCEL') },
});

// 导入进度条
const importProgress = reactive({
  show: false,
  value: 0,
  errorMsg: '',
});

// 导出进度条
const exportProgress = reactive({
  show: false,
  value: 0,
  errorMsg: '',
});

// 文件上传组件配置
const data = reactive({
  width: 320,
  action: UI_REST_FIRMWAREINVENTORY,
  headers: {
    'X-CSRF-Token': escapeHeader(store.state.loct.to),
  },
  method: 'POST',
  name: 'imgfile',
  data: { Type: 'URI' } as any,
  isAutoUpload: false,
  accept: '.json',
  disabled: isSystemLocked.value,
  onAddItem: (file: UploadFile, list: UploadFile[], msg?: any, upload?: any): boolean => {
    importProgress.errorMsg = '';
    importProgress.show = false;
    importProgress.value = 0;
    const subfix = file.name.split('.').reverse()[0];
    const size = file.size as any;
    fileItem = upload;
    fileName = file.name;
    // 文件格式错误
    if (data.accept.indexOf(subfix) < 0) {
      importState.value = true;
      msg.value = traduction('CONFIG_UPGRADE_FILETYPE_ERROR');
      return false;
    }
    // 文件大小超出限制
    if (1024 * 1024 < size) {
      importState.value = true;
      msg.value = traduction('CONFIG_UPGRADE_FILESIZE_1M');
      return false;
    }

    // 文件名超出限制长度（linux限制长度为255-/temp/web/的固定长度，前端限制为246）
    if (getBytes(file.name) > 246) {
      msg.value = traduction('CONFIG_UPGRADE_FILE_NAME');
      return false;
    }

    importState.value = false;
    exportState.value = true;
    return true;
  },
  onError: (error: any, file: UploadFile, list: UploadFile[]): void => {
    const errorCode = JSON.parse(error.message).error[0].code;
    if (
      errorCode === SecondAuthorityFail.REAUTHFAILED ||
      errorCode === SecondAuthorityFail.AUTHORIZATIONFAILED
    ) {
      secondRef.value.setErrorId();
      secondRef.value.clearPassword();
      file.status = 'ready';
      list.push(file);
    } else {
      secondRef.value.hide();
      // 文件上传失败报错
      importCtrlRef.value.setError(traduction('CONFIG_UPGRADE_IMPORT_FAIL'));
      store.state.event.setEventState({
        type: 'alertMessage',
        value: { type: 'error', message: traduction('SERVICE_WBS_IMPORT_FAILED') },
      });
    }
  },
  onSuccess: (response: any, file: UploadFile, list: UploadFile[]): void => {
    startImportLogic();
    fileItem.clearFiles();
    fileItem.handleStart(list[0].raw);
    setButtonsState(true);
  },
});

// 导入时二次认证弹框显示
function confirm() {
  if (isSystemLocked.value) {
    return;
  }
  curOperator.value = 'import';
  if (!isNoPwd) {
    secondRef.value.show();
  } else {
    importFile({ reason: true, password: '' });
  }
}

// 点击导入按钮的二次认证结果为true时执行导入操作
async function importFile(param: { reason: boolean; password: string }) {
  secondPwd.value = param.password;
  if (param.reason) {
    if (!isNoPwd) {
      data.data.ReauthKey = window.btoa(param.password);
    }
    await fileItem.submit();
    // 禁用按钮
    setButtonsState(true);
  } else {
    secondRef.value.hide();
    setButtonsState(false);
    importState.value = false;
  }
}

function startImportLogic() {
  importConfig(`/tmp/web/${fileName}`, secondPwd.value)
    .then(res => {
      getImportTask(res.data.url);
      secondRef.value.hide();
      // 打开右下角“导入中”弹窗
      openNotification({
        title: traduction('COMMON_IMPORTING'),
        message: traduction('CONFIG_IMPORTING'),
        icon: UploadingIcon as any,
      });
    })
    .catch(error => {
      closeNotification();
      const errorId = getMessageId(error.data);
      if (errorId instanceof Array && errorId.length > 0) {
        const errorMsg = getErrorTranslate(errorId[0].code as string);
        if (errorId[0].code === 'ReauthFailed' || errorId[0].code === 'AuthorizationFailed') {
          secondRef.value.setErrorId(errorId[0].code);
        } else {
          showElMessage('error', errorMsg);
          secondRef.value.hide();
        }
      } else {
        showElMessage('error', traduction('COMMON_FAILED'));
        secondRef.value.hide();
      }
    });
}

// 查询导入进度
function getImportTask(url: string) {
  queryProgress(url).then((rsp: IResponse) => {
    const d = rsp.data;
    const curPercent = d.prepare_progress;
    importProgress.show = true;
    if (curPercent === 100 && d.state === 'Completed') {
      importProgress.value = 100;
      importCtrlRef.value.clear();
      // 恢复按钮初始状态
      setButtonsState(false);

      // 弹出导入成功提示
      dialogConfig.title = traduction('COMMON_CONFIRM');
      dialogConfig.content = traduction('CONFIG_UPGRADE_EFFECTRESTART');
      dialogConfig.okButton.label = traduction('CONFIG_UPGRADE_RESET_NOW');
      dialogConfig.cancelButton.label = traduction('CONFIG_UPGRADE_RESET_LATER');
      dialogRef.value.show();
      // 关闭消息提示框
      elNotification.closeAll();
      openNotification({
        type: 'success',
        title: traduction('COMMON_IMPORT_COMPLETE'),
        message: traduction('CONFIG_IMPORT_SUCCESS'),
      });
    } else if (d.state === 'Running' || d.state === 'Starting') {
      if (curPercent !== null) {
        importProgress.value = parseInt(curPercent);
        importState.value = true;
      }
      setTimeout(() => getImportTask(url), 3000);
    } else {
      // 恢复按钮初始状态
      closeNotification();
      setButtonsState(false);
      const msg = d.message_args && d.message_args[0] ? ` ${d.message_args[0]}` : '';
      importProgress.show = false;
      importProgress.errorMsg = traduction('CONFIG_UPGRADE_IMPORT_FAIL') + msg;
      importCtrlRef.value.setError();
      setStoreData('event', 'alertMessage', {
        type: 'error',
        message: traduction('SERVICE_WBS_IMPORT_FAILED'),
      });
    }
  });
}

// 导出前是否显示弹窗信息
function exportConfig() {
  isInit.value = false;
  curOperator.value = 'export';
  if (isIrm) {
    exportData();
    return;
  }
  getGenericInfo().then((res: any) => {
    if (res && (res.StorageConfigReady === 1 || res.StorageConfigReady === 4)) {
      exportData();
    } else {
      const msg = raidCardStateTips(res.StorageConfigReady);
      dialogConfig.title = traduction('COMMON_INFORMATION');
      dialogConfig.content = traduction(msg);
      dialogConfig.okButton.label = traduction('COMMON_OK');
      dialogConfig.cancelButton.label = traduction('COMMON_CANCEL');
      dialogRef.value.show();
    }
  });
}

// 导出前查询Raid卡状态提示信息
function raidCardStateTips(state: number) {
  let msgContent = '';
  switch (state) {
    case 0:
      msgContent = 'CONFIG_UPGRADE_NOREADY_TIP';
      break;
    case 2:
      msgContent = 'CONFIG_UPGRADE_NOTSURPPORT_TIP';
      break;
    case 3:
      msgContent = 'CONFIG_UPGRADE_ABNORMOL_TIP';
      break;
    default:
      msgContent = 'CONFIG_UPGRADE_CONFIRM_TIP';
  }
  return msgContent;
}

// 导出
function exportData() {
  // 禁用按钮
  setButtonsState(true);
  exportProgress.show = true;
  exportProgress.value = 0;
  configExport().then((res: any) => {
    const response = res.data;
    exportProgress.errorMsg = '';
    sessionStorage.setItem('configExportUrl', response.url);
    preProgress(response.url);
    openNotification({
      title: traduction('COMMON_EXPORTING'),
      message: traduction('CONFIG_EXPORTING'),
      icon: UploadingIcon as any,
    });
  });
}

// 下载配置文件
function downloadConfig(url: string) {
  // 恢复按钮初始状态
  setButtonsState(false);
  generalDownLoadFile(url).then(res => {
    const fName = res.headers['content-disposition'].split('=')[1];
    downloadFileWithResponse(res.data, fName);
    elNotification.closeAll();
    openNotification({
      title: traduction('COMMON_EXPORT_COMPLETE'),
      message: traduction('CONFIG_EXPORT_SUCCESS'),
      icon: notificationIcons.success as any,
    });
  }).catch(error => {
    if (!isInit.value) {
      throw error;
    }
  });
}

// 查询导出进度
function preProgress(url: string) {
  getTask(url).then(
    (response: any) => {
      const res = response.data;
      if (res.prepare_progress === 100 && res.state === 'Completed') {
        exportProgress.value = 100;
        sessionStorage.removeItem('configExportUrl');
        downloadConfig('/tmp/web/config.json');
      } else if (res.state === 'Running' || res.state === 'Starting') {
        if (isInit.value) {
          isInit.value = false;
          setButtonsState(true);
          exportProgress.show = true;
          exportProgress.value = 0;
          openNotification({
            title: traduction('COMMON_EXPORTING'),
            message: traduction('CONFIG_EXPORTING'),
            icon: UploadingIcon as any,
          });
        }
        // 重复查询的条件1.进度没有达到100%， 当前状态是running，starting
        exportProgress.value = res.prepare_progress;
        setTimeout(() => {
          preProgress(url);
        }, 3000);
      } else {
        executeExportFailed();
      }
    },
    error => {
      executeExportFailed();
    },
  );
  importState.value = true;
}

// 导出错误时提示信息
function executeExportFailed() {
  setButtonsState(false);
  exportProgress.errorMsg = traduction('CONFIG_EXPORT_FAILED');
  openNotification({
    title: traduction('COMMON_EXPORT_FAILED'),
    message: traduction('CONFIG_EXPORT_FAILED'),
    icon: notificationIcons.error as any,
  });
}

// 禁用上传，导入，导出按钮组
function setButtonsState(state: boolean) {
  data.disabled = isSystemLocked.value || state;
  exportState.value = state;
  importState.value = true;
}

// 关闭 Dialog
function closeDialog(reason: boolean) {
  if (reason && curOperator.value === 'export') {
    exportData();
  }

  if (reason && curOperator.value === 'import') {
    if (multihost) {
      router.push('/navigate/system/power/multi-control');
    } else {
      router.push('/navigate/system/power/control');
    }
  }

  dialogRef.value.hide();
}

// 显示右下角弹出信息
function openNotification(param: any) {
  closeNotification();
  const configurable: any = {
    title: param.title,
    message: param.message,
    position: 'bottom-right',
    appendTo: '#configUpdateBox',
    duration: 0,
    offset: 10,
  };
  if (param.type) {
    configurable.type = param.type;
  }
  if (param.icon) {
    configurable.icon = param.icon;
  }
  noticeInstance = elNotification(configurable);
}

// 关闭右下角弹出信息
function closeNotification() {
  if (noticeInstance) {
    noticeInstance.close();
  }
}

const unWatchLock = watch(isSystemLocked, (newVal: any) => {
  data.disabled = newVal;
});

onMounted(() => {
  const url = sessionStorage.getItem('configExportUrl');
  if (url) {
    preProgress(url);
  }
});

onUnmounted(() => {
  unWatchLock();
});
</script>

<template>
  <div id="configUpdateBox" class="root-container">
    <CustAlert :content="traduction('CONFIG_UPGRADE_TIP', { softwareName: sn })" />
    <div class="config">
      <div class="config-item">
        <h3>{{ traduction('CONFIG_UPGRADE_IMPORT') }}</h3>
        <div class="add-file">
          <FileUpload ref="importCtrlRef" :data="data" />
          <div v-if="importProgress.show" class="import-progress">
            <el-progress :percentage="importProgress.value" show-text="true" />
          </div>
          <div v-if="importProgress.errorMsg !== ''" id="importErrorMsg" class="state-error">
            {{ importProgress.errorMsg }}
          </div>
        </div>
        <div :class="[importProgress.errorMsg !== '' ? 'show-error' : 'import']">
          <el-button
            :id="'importBtn'"
            :disabled="isSystemLocked || importState"
            type="primary"
            @click="confirm()"
          >
            {{ traduction('CONFIG_UPGRADE_IMPORT_SHORT') }}
          </el-button>
        </div>
      </div>
      <div class="config-item">
        <h3>{{ traduction('CONFIG_UPGRADE_EXPORT') }}</h3>
        <div class="export">
          <el-button
            :id="'exportBtn'"
            :disabled="exportState"
            :class="{ 'default-disabled-btn': exportState }"
            @click="exportConfig"
          >
            {{ traduction('CONFIG_UPGRADE_EXPORT_SHORT') }}
          </el-button>
        </div>
        <el-progress
          v-if="exportProgress.show"
          class="export-progress"
          stroke-width="4"
          :percentage="exportProgress.value"
        />
        <div v-if="exportProgress.errorMsg !== ''" id="exportErrorMsg" class="export-errors">
          {{ $t('CONFIG_UPGRADE_EXPORT_FAIL') }}
        </div>
      </div>
    </div>
  </div>
  <SecondPassword ref="secondRef" @close="importFile" />
  <Dialog ref="dialogRef" :config="dialogConfig" @close="closeDialog"></Dialog>
</template>

<style lang="scss" scoped>
.root-container {
  margin-right: 24px;
}
.config {
  border-radius: 4px;
  margin-top: 16px;
  h3 {
    font-size: 16px;
    margin-bottom: 16px;
  }
  .import {
    margin: 24px 0 0 0;
  }
  .show-error {
    margin-top: 38px;
  }
  .export-progress {
    margin-top: 8px;
  }
  .state-error {
    position: absolute;
    color: #e32020;
    margin-top: 4px;
  }
  .config-item {
    padding: 24px;
    background: var(--o-bg-color-base);
    border-radius: 4px;
    &:last-child {
      margin-top: 16px;
    }

    .default-disabled-btn {
      background-color: #ebedf3;
    }
  }
  .export-errors {
    color: var(--o-color-danger);
    margin-top: 4px;
  }
}

.import-progress {
  margin-top: 4px;
}

:deep(.file-upload) {
  .error-text {
    position: absolute;
  }
}

:deep(.el-progress__text) {
  color: rgba(0, 0, 0, 0.9) !important;
}

:deep(.el-progress) {
  width: 346px;
}

:deep(.el-notification) {
  padding-bottom: 32px;
}

:deep(.el-notification) {
  .refresh-icon {
    width: 24px;
    height: 24px;
  }
}
</style>
