<script lang="ts" setup>
import { IUploadConfig } from '@/model/base-interface';
import { setStoreData, showFailedMessage, showSuccessMessage, showWarningMessage } 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 gmSigPassword = ref('');
const passwordFail = ref(false);
const passwordFail2 = ref(false);
const uploadMsg = ref('');
const uploadMsg2 = ref('');
let certUpload: any[] = [];

let certFile: UploadFile;
let certList: UploadFile[] = [];
const fileItemHasError = ref(false);
const fileItemHasError2 = ref(false);
let isNeedRefresh = false;

const props = defineProps({
  isGm: {
    type: Boolean,
    required: true,
  },
});

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.push(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, password.value);
    }
    return true;
  },
} as IUploadConfig);

const uploadConfig2 = reactive({
  id: 'certUpload2',
  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.push(upload);
    passwordFail2.value = false;
    uploadMsg2.value = '';
    fileItemHasError2.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');
      fileItemHasError2.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');
      fileItemHasError2.value = true;
      return false;
    }
  },
  onError: (error: any, file: UploadFile, list: UploadFile[]): void => {
    uploadMsg2.value = '';
    certDialogRef.value.disable();
    uploadConfig2.isNeedClearError = false;
    const errorCode = JSON.parse(error.message).error[0]?.code;
    if (errorCode === 'EncryptedCertImportFailed') {
      certList = list;
      passwordFail2.value = true;
      gmSigPassword.value = '';
      uploadMsg2.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 => {
    // 上传前动态添加额外参数
    uploadConfig2.data.CertificateType = 'Custom';
    uploadConfig2.data.Password = gmSigPassword.value;
    if (file) {
      updateServerCertificate(file, gmSigPassword.value);
    }
    return true;
  },
} as IUploadConfig);

function updateServerCertificate(file: any, pass: string) {
  const clientFormData = new FormData();
  clientFormData.append('imgfile', file, file.name);
  CaCertificateService.uploadCerFile(clientFormData).then(() => {
    CaCertificateService.importDiyCerCtrl(file.name, pass)
      .then((res) => {
        if (res?.data?.ValidateResult !== 0) {
          showWarningMessage(traduction('CERT_IMPORT_WARNING'));
        } else {
          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.forEach(item => item?.submit());
    certUpload = [];
  } 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;
  }
}

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

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

<template>
  <Dialog ref="certDialogRef" :config="dialogConfig" @close="dialogClose">
    <template #other>
      <el-form>
        <template v-if="isGm">
          <el-form-item
            label-width="100px"
            :label="$t('CERT_GM_ENC')"
            :class="{ 'error-item': fileItemHasError }"
          >
            <FileUpload :data="uploadConfig"></FileUpload>
            <span class="format-text">{{ traduction('CERT_CUSTOM_FORMAT') }}</span>
          </el-form-item>
          <el-form-item
            label-width="100px"
            :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-item
            label-width="100px"
            :label="$t('CERT_GM_SIG')"
            :class="{ 'error-item': fileItemHasError2 }"
          >
            <FileUpload :data="uploadConfig2"></FileUpload>
            <span class="format-text">{{ traduction('CERT_CUSTOM_FORMAT') }}</span>
          </el-form-item>
          <el-form-item
            label-width="100px"
            :label="$t('SERVICE_WBS_DLOG_CRE_PWD')"
            :class="{
              'min-margin': passwordFail2,
              'is-error': passwordFail2,
            }"
          >
            <el-input
              v-model="gmSigPassword"
              v-addId.input="'certPassword2'"
              v-clearable
              clearable
              :placeholder="$t('LOGIN_PASSWORD_TIP')"
              :class="passwordFail2 ? 'error-input' : 'no-error'"
              type="password"
              autocomplete="new-password"
              @input="passwordChange2"
            >
              <template #suffix>
                <ErrorIcon />
                <ClearableIcon />
              </template>
            </el-input>
            <span v-if="passwordFail2" class="error-text">{{ uploadMsg2 }}</span>
          </el-form-item>
        </template>
        <template v-else>
          <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>
        </template>
      </el-form>
    </template>
  </Dialog>
</template>

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

.el-form-item {
  &:nth-child(odd) {
    margin-bottom: 8px;
  }
  &:nth-child(even) {
    margin-bottom: 0;
  }
}

.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>
