<script lang="ts" setup>
import { IUploadConfig } from '@/model/base-interface';
import { setStoreData, showFailedMessage, showSuccessMessage } from '@/utils/composition';
import { getErrorTranslate, traduction } from '@/utils/language';
import { nextTick, onMounted, reactive, ref } from 'vue';
import Dialog from '@/components/Dialog/Dialog.vue';
import { escapeHeader } from '@/utils/utils';
import { UploadFile } from 'element-plus/es/components/upload/src/upload';
import CaCertificateService from '@/services/caCertificate.service';

const dialogConfig = reactive({
  title: traduction('CERT_CUSTOM_TITLE'),
  content: '',
  modalClass: 'custom-cert-dialog',
  okButton: { id: 'sslUpload' },
  cancelButton: { id: 'sslCancel' },
});
const certDialogRef = ref();
const emit = defineEmits(['close']);
const password = ref('');
const passwordFail = ref(false);
const uploadMsg = ref('');
let certUpload: any = null;
let certFile: UploadFile;
let certList: UploadFile[] = [];
const fileItemHasError = ref(false);
let isNeedRefresh = false;

const loct = localStorage.getItem('loct');
const uploadConfig = reactive({
  id: 'certUpload',
  action: '',
  headers: {
    From: 'WebUI',
    'X-CSRF-Token': escapeHeader(loct ? JSON.parse(loct).to : ''),
  },
  method: 'POST',
  name: 'Content',
  data: { CertificateType: '' },
  isAutoUpload: false,
  accept: '.pfx, .p12',
  isNeedClearError: false,
  onAddItem: (file: UploadFile, list: UploadFile[], msg?: any, upload?: any): boolean => {
    let type = file.name.substring(file.name.lastIndexOf('.') + 1); 
    certUpload = upload;
    passwordFail.value = false;
    uploadMsg.value = '';
    fileItemHasError.value = false;
    certDialogRef.value.disable();
    isNeedRefresh = false;
    if ((type === 'pfx' || type === 'p12') && (file.size as any) > 102400) {
      msg.value = traduction('SERVICE_WBS_FILE_SIZE_VALI_TIP01');
      fileItemHasError.value = true;
      return false;
    } else if ((type === 'pfx' || type === 'p12') && (file.size as any) <= 102400) {
      certDialogRef.value.enable();
      certFile = file;
      return true;
    } else {
      msg.value = traduction('SERVICE_UPLOADIN_CORRECT');
      fileItemHasError.value = true;
      return false;
    }
  },
  onError: (error: any, file: UploadFile, list: UploadFile[]): void => {
    uploadMsg.value = '';
    certDialogRef.value.disable();
    uploadConfig.isNeedClearError = false;
    const errorCode = JSON.parse(error.message).error[0]?.code;
    if (errorCode === 'EncryptedCertImportFailed') {
      certList = list;
      passwordFail.value = true;
      password.value = '';
      uploadMsg.value = traduction('PASSWORD_OR_CERTIFICATE_ERROR');
    } else {
      if (errorCode === 'NoValidSession') {
        setStoreData(
          'event',
          'error401',
          `${traduction('SessionTimeout.errorMessage')}${Date.now()}`,
        );
      }
      showFailedMessage(getErrorTranslate(errorCode));
      dialogClose(false);
    }
  },
  onSuccess: (response: any, file: UploadFile, list: UploadFile[]): void => {
    showSuccessMessage();
    isNeedRefresh = true;
    dialogClose(false);
  },
  onBeforeUpload: (file: UploadFile): any => {
    // 上传前动态添加额外参数
    uploadConfig.data.CertificateType = 'Custom';
    uploadConfig.data.Password = password.value;
    if (file) {
      updateServerCertificate(file);
    }
    return true;
  },
} as IUploadConfig);

function updateServerCertificate(file: any) {
  const clientFormData = new FormData();
  clientFormData.append('imgfile', file, file.name);
  CaCertificateService.uploadCerFile(clientFormData).then(() => {
    CaCertificateService.importDiyCerCtrl(file.name, password.value)
      .then(() => {
        showSuccessMessage();
        isNeedRefresh = true;
        dialogClose(false);
      })
      .catch(error => {
        uploadMsg.value = '';
        certDialogRef.value.disable();
        uploadConfig.isNeedClearError = false;
        let errorCode = '';
        if (error?.data?.error[0]?.code) {
          errorCode = error.data.error[0].code;
        }
        if (errorCode === 'NoValidSession') {
          setStoreData(
            'event',
            'error401',
            `${traduction('SessionTimeout.errorMessage')}${Date.now()}`,
          );
        }
        showFailedMessage(getErrorTranslate(errorCode));
        dialogClose(false);
      });
  }).catch(error => {
    uploadMsg.value = '';
    let errorCode = '';
    certDialogRef.value.disable();
    uploadConfig.isNeedClearError = false;
    if (error?.data?.code) {
      errorCode = error.data.code;
    }
    showFailedMessage(getErrorTranslate(errorCode));
    dialogClose(false);
  });
}
// 关闭导入证书弹窗
function dialogClose(reason: boolean) {
  if (reason) {
      certUpload.submit();
  } else {
    certDialogRef.value.hide();
    emit('close', isNeedRefresh);
  }
}

function passwordChange() {
  if (passwordFail.value) {
    certFile.status = 'ready';
    certList.push(certFile);
    certDialogRef.value.enable();
    uploadConfig.isNeedClearError = true;
    passwordFail.value = false;
  }
}

onMounted(() => {
  certDialogRef.value.show();
  certDialogRef.value.disable();
});
</script>

<template>
  <Dialog ref="certDialogRef" :config="dialogConfig" @close="dialogClose">
    <template #other>
      <el-form>
        <el-form-item
          :label="$t('ALARM_REPORT_SYSLOG_CER_FILE')"
          :class="{ 'error-item': fileItemHasError }"
        >
          <FileUpload :data="uploadConfig"></FileUpload>
          <span class="format-text">{{ traduction('CERT_CUSTOM_FORMAT') }}</span>
        </el-form-item>
        <el-form-item
          :label="$t('SERVICE_WBS_DLOG_CRE_PWD')"
          :class="{
            'min-margin': passwordFail,
            'is-error': passwordFail
          }"
        >
          <el-input
            v-model="password"
            v-addId.input="'certPassword'"
            v-clearable
            clearable
            :placeholder="$t('LOGIN_PASSWORD_TIP')"
            :class="passwordFail ? 'error-input' : 'no-error'"
            type="password"
            autocomplete="new-password"
            @input="passwordChange"
          >
            <template #suffix>
              <ErrorIcon />
              <ClearableIcon />
            </template>
          </el-input>
          <span v-if="passwordFail" class="error-text">{{ uploadMsg }}</span>
        </el-form-item>
      </el-form>
    </template>
  </Dialog>
</template>

<style lang="scss" scoped>
.el-form {
  width: 100%;
}
.min-margin {
  margin-bottom: 0;
}

.el-form-item {
  &:last-child {
    margin-bottom: 0px;
  }
}

.error-text {
  color: var(--o-color-danger);
  line-height: 16px;
  margin: 4px 0;
}

.format-text {
  line-height: 16px;
  margin-top: 4px;
  color: var(--o-text-color-tertiary);
}

:deep(.el-input__inner) {
  padding-left: 16px !important;
}

.error-item {
  margin-bottom: 0 !important;
  .format-text {
    margin-bottom: 4px;
  }
  .file-upload {
    display: grid;
  }
}

.no-error {
  margin-bottom: 24px;
}

:deep(.el-dialog__body) {
  padding-bottom: 4px;
}
</style>
