<script setup lang="ts">
import { traduction } from '@/utils/language';
import { computed, inject, nextTick, onUnmounted, reactive, ref, watch } from 'vue';
import { UploadFile } from 'element-plus/es/components/upload/src/upload';
import { SecondAuthorityFail } from '../../models/model';
import { getStoreData, showSuccessMessage } from '@/utils/composition';
import FileUpload from '@/components/FileUpload/FileUpload.vue';
import ErrorIcon from '@/components/ErrorIcon/ErrorIcon.vue';
import ClearableIcon from '@/components/ClearableIcon/ClearableIcon.vue';
import { escapeHeader } from '@/utils/utils';

const props = defineProps({
  action: {
    type: String,
    default: '',
  },
});
const isSystemLocked = computed(() => {
  return getStoreData('glob', 'systemLocked');
});

const isNoPwd = getStoreData('loct', 'nopwd');
const pwdMaxLen = getStoreData('loct', 'pml');
const crlRef = ref();
const secondErrorMsg = ref('');
const uploadFailedMsg = ref('');
let fileItem: any = null;
let resolveFunc: any = null;
let rejectFunc: any = null;

// 定义组件暴露给外部的事件
defineExpose({
  upload: () => {
    return new Promise((resolve, reject) => {
      resolveFunc = resolve;
      rejectFunc = reject;
      if (fileItem) {
        if (!isNoPwd) {
          crlData.data.ReauthKey = window.btoa(secondPwd.value);
        }
        fileItem.submit();
      }
    });
  },
});

// 定义组件暴露的事件
const emits = defineEmits(['enable', 'disable', 'close', 'reInit']);
const action = inject('action');
const secondPwd = ref('');
const pwdError = ref(false);
const crlData = reactive({
  width: 420,
  action: action as string,
  headers: {
    From: 'WebUI',
    'X-CSRF-Token': escapeHeader(getStoreData('loct', 'to')),
  },
  method: 'POST',
  name: 'Content',
  data: { Type: 'URI' } as any,
  isAutoUpload: false,
  accept: '.crl',
  disabled: false,
  onAddItem: (file: UploadFile, list: UploadFile[], msg?: any, upload?: any): boolean => {
    const subfix = file.name.split('.').reverse()[0];
    const size = file.size as any;
    // 文件格式错误
    if (crlData.accept.indexOf(subfix) < 0) {
      crlRef.value.setError('');
      uploadFailedMsg.value = traduction('COMMON_FILE_SUFFIX_CRL');
      return false;
    }
    // 文件大小超出限制
    if (1024 * 1024 < size) {
      crlRef.value.setError('');
      uploadFailedMsg.value = traduction('CONFIG_UPGRADE_FILESIZE_1M');
      return false;
    }

    fileItem = upload;
    crlRef.value.clearError();
    uploadFailedMsg.value = '';

    // 只能在回调里面去修改URL地址，在其他方法里面修改不成功。
    crlData.action = props.action as string;
    computeSaveState();
    return true;
  },
  onError: (error: any, file: UploadFile, list: UploadFile[]): void => {
    const errorCode = JSON.parse(error.message).error[0].code;
    rejectFunc(errorCode);
    secondPwd.value = '';
    emits('disable');
    crlRef.value.clear();
    crlRef.value.clearError();
    fileItem = null;
    if (
      errorCode === SecondAuthorityFail.REAUTHFAILED ||
      errorCode === SecondAuthorityFail.AUTHORIZATIONFAILED
    ) {
      nextTick(() => {
        secondErrorMsg.value = traduction('COMMON_SECONDPWD_ERROR');
      });
    } else {
      // 文件上传失败报错
      uploadFailedMsg.value = traduction(errorCode + '.errorMessage');
      crlRef.value.setError('');
    }
  },
  onSuccess: (response: any, file: UploadFile, list: UploadFile[]): void => {
    resolveFunc(true);
    showSuccessMessage();
    emits('reInit');
  },
});

// 计算保存按钮的状态
function computeSaveState() {
  let result = false;
  const isPwdValid = isNoPwd || (secondPwd.value.length > 0 && !pwdError.value);
  const iSFileSelected = fileItem !== null;
  result = isPwdValid && iSFileSelected;
  if (result) {
    emits('enable');
  } else {
    emits('disable');
  }
}

function resetControlValue(key: string, value: string) {
  secondErrorMsg.value = '';
  computeSaveState();
}

const unWatchLocked = watch(isSystemLocked, newValue => {
  crlData.disabled = newValue;
});

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

<template>
  <div class="root-container">
    <el-form>
      <el-form-item :label="traduction('ALARM_REPORT_SYSLOG_CER_FILE')" :error="uploadFailedMsg">
        <FileUpload ref="crlRef" :data="crlData" />
      </el-form-item>
      <el-form-item v-if="!isNoPwd" :error="secondErrorMsg">
        <template #label>
          <span class="login-pwd">{{ $t('COMMON_LOGIN_PASSWORD') }}</span>
        </template>
        <el-input
          id="userPwd"
          v-model="secondPwd"
          v-clearable
          type="password"
          autocomplete="new-password"
          clearable
          :maxlength="pwdMaxLen"
          :placeholder="$t('COMMON_PASSWORD_PLACEHOLDER')"
          :disabled="isSystemLocked"
          @input="resetControlValue('secondPwd', $event)"
        >
          <template #suffix>
            <ErrorIcon />
            <ClearableIcon />
          </template>
        </el-input>
      </el-form-item>
    </el-form>
  </div>
</template>

<style scoped lang="scss">
.login-pwd::before {
  content: '*';
  position: absolute;
  font-size: 12px;
  margin-left: -6px;
  color: var(--o-form-require-color);
  margin-right: 0;
}
:deep(.el-form-item:first-child) {
  margin-bottom: 24px;
}
:deep(.el-form-item__label) {
  width: auto !important;
}
:deep(.el-input) {
  width: 100% !important;
}
.el-form {
  .el-form-item:nth-last-child(1) {
    margin-bottom: 0 !important;
  }
}

.root-container {
  width: 100%;

  :deep(.file-upload) {
    width: 100% !important;
  }
}
</style>
