<script setup lang="ts">
import { ref, reactive, computed, onMounted, nextTick } from 'vue';
import { UI_REST_ACCESSMGNT_ACCOUNTS_USER } from '@/api/api';
import { getStoreData } from '@/utils/composition';
import { getMessageId, urlReplace } from '@/utils/utils';
import { modifyUserInfo } from '../login-service';
import { IconSuccess, IconError } from '@computing/opendesign-icons';
import { getErrorTranslate, traduction } from '@/utils/language';
import { clearCurrentLoginInfo } from '@/utils/common-service';
import ComplexPopoverContentOfList from '@/components/ComplexPopoverContent/ComplexPopoverContentOfList.vue';
import ErrorIcon from '@/components/ErrorIcon/ErrorIcon.vue';
import ClearableIcon from '@/components/ClearableIcon/ClearableIcon.vue';
import { strVerification } from '@/validators/validation-functions';
import { initPasswordRules } from '@/pages/User/Localuser/utils/utils';
import { SecondAuthorityFail } from '@/model/base-enum';

const props = defineProps({
  password: {
    type: String,
    required: true,
    default: '',
  },
  account: {
    type: String,
    required: true,
    default: '',
  },
  pwdChecked: {
    type: Boolean,
    required: true,
    default: true,
  },
  minPwdLength: {
    type: Number,
    required: true,
    default: 8,
  },
  firstLoginPolicy: Boolean,
  passwordExpired: Boolean,
});

const pwdData = reactive({
  userName: props.account,
  userPwd: '',
  userPwd1: '',
  userPwd2: '',
});

const rules = reactive({
  userPwd1: {},
  userPwd2: {
    type: 'password',
    required: false,
    containsEmptyString: true,
    equals: {
      aimObj: pwdData,
      aimObjKey: 'userPwd1',
    },
    validator: strVerification,
    message: traduction('COMMON_PASSWORDS_DIFFERENT'),
    trigger: 'change',
  },
});
const validatorResult = reactive({
  userPwd1: false,
  userPwd2: false,
});
const emits = defineEmits(['back']);
const modifyRef = ref();
const secondErrorMsg = ref('');
const disabled = ref(true);
const saveState = ref(false);
const tipShow = ref(false);
const pwdMaxLen = getStoreData('loct', 'pml');
const minPwdLength = computed(() => {
  if (!props.pwdChecked) {
    return 1;
  }
  return props.minPwdLength;
});

// 密码修改结果 0: 初始 1：成功 2：失败
const result = ref(0);
const saveFailedMessage = ref('');

// 设置校验规则
function setEditFormRule() {
  const errorMessage = [
    ' ',
    traduction('VALIDTOR_FORMAT_ERROR'),
    traduction('VALIDTOR_FORMAT_ERROR'),
    traduction('VALIDTOR_FORMAT_ERROR'),
    traduction('VALIDTOR_FORMAT_ERROR'),
  ];
  rules.userPwd1 = initPasswordRules(
    props.pwdChecked,
    minPwdLength.value,
    pwdData,
    false,
    errorMessage,
    'change',
  );
}

function input(key: string, value: string) {
  if (key === 'userPwd1') {
    modifyRef.value.validateField('userPwd2');
  }
  resetState();
  nextTick(() => {
    computedSaveState();
  });
}

function resetState() {
  // 重置状态
  result.value = 0;
  saveFailedMessage.value = '';
  secondErrorMsg.value = '';
}

function validator(key: string, r: boolean) {
  validatorResult[key] = r;
  nextTick(() => {
    computedSaveState();
  });
}

// 计算保存按钮的状态
function computedSaveState() {
  // 高亮条件：1. 旧密码不为空，2. 校验状态全部通过。3.不存在后端报错信息
  const isOldPwdValid = pwdData.userPwd !== '';
  const isNotAsyncError = secondErrorMsg.value === '' && saveFailedMessage.value === '';
  const isFormState = validatorResult.userPwd1 && validatorResult.userPwd2;
  if (isOldPwdValid && isFormState && isNotAsyncError) {
    disabled.value = false;
  } else {
    disabled.value = true;
  }
}

// 修改密码
function updatePassword() {
  if (disabled.value || saveState.value) {
    return;
  }

  const params = { Password: pwdData.userPwd1, ReauthKey: window.btoa(pwdData.userPwd) };
  const url = urlReplace(UI_REST_ACCESSMGNT_ACCOUNTS_USER, { id: getStoreData('loct', 'uid') });
  saveState.value = true;
  disabled.value = true;
  modifyUserInfo(url, params)
    .then(
      () => {
        result.value = 1;
        clearCurrentLoginInfo();
        setTimeout(() => {
          self.location.reload();
        }, 3000);
      },
      error => {
        const errorId = getMessageId(error.data)[0]?.code;
        if (errorId) {
          result.value = 2;
          pwdData.userPwd = '';
          if (
            errorId === SecondAuthorityFail.AUTHORIZATIONFAILED ||
            errorId === SecondAuthorityFail.REAUTHFAILED
          ) {
            saveFailedMessage.value = traduction('COMMON_SECONDPWD_ERROR');
            secondErrorMsg.value = ' ';
            return;
          }

          const msg = getErrorTranslate(errorId);
          saveFailedMessage.value = msg;
        }
      },
    )
    .finally(() => {
      saveState.value = false;
    });
}

// 返回
function back() {
  emits('back');
}

onMounted(() => {
  setEditFormRule();
});
</script>

<template>
  <div class="root-container">
    <p class="modify-title">{{ $t('LOGIN_MODIFY_PASSWORD') }}</p>
    <!-- 强制修改密码场景下，提示文字信息 -->
    <p v-if="firstLoginPolicy" class="init-pwd-tip">{{ $t('LOGIN_RISK_TIP3') }}</p>
    <p v-if="passwordExpired" class="init-pwd-tip">{{ $t('LOGING_SSO_ERROR_137') }}</p>
    <el-form
      ref="modifyRef"
      class="modify-form"
      :rules="rules"
      :model="pwdData"
      :validate-on-rule-change="false"
      @validate="validator"
    >
      <el-form-item :error="secondErrorMsg">
        <!-- 初始密码 -->
        <div class="login-modify-container">
          <el-input
            v-model="pwdData.userPwd"
            v-addId.input="'oldPwd'"
            type="password"
            autocomplete="new-password"
            :maxlength="pwdMaxLen"
            :placeholder="$t('LOGIN_MODIFY_OLD')"
            @input="input"
          ></el-input>
        </div>
      </el-form-item>
      <el-form-item :label="''" prop="userPwd1">
        <!-- 新密码 -->
        <div class="login-modify-container">
          <el-popover
            v-model:visible="tipShow"
            popper-class="no-wrap-popover modify-tip"
            :teleported="false"
            :placement="'top'"
            trigger="focus"
            trigger-keys
          >
            <!-- 密码提示 -->
            <span v-if="!props.pwdChecked">{{ rules.userPwd1['tipText'] }}</span>
            <ComplexPopoverContentOfList
              v-if="props.pwdChecked"
              :data="rules.userPwd1['verificationList']"
            />

            <template #reference>
              <el-input
                v-model="pwdData.userPwd1"
                v-addId.input="'newPwd'"
                v-clearable
                clearable
                :maxlength="pwdMaxLen"
                type="password"
                autocomplete="new-password"
                :placeholder="$t('LOGIN_MODIFY_NEW')"
                @focus="tipShow = true"
                @blur="tipShow = false"
                @input="input('userPwd1', $event)"
              >
                <template #suffix>
                  <ErrorIcon />
                  <ClearableIcon />
                </template>
              </el-input>
            </template>
          </el-popover>
        </div>
      </el-form-item>
      <el-form-item :label="''" prop="userPwd2">
        <!-- 确认密码 -->
        <div class="login-modify-container">
          <el-input
            v-model="pwdData.userPwd2"
            v-addId.input="'confirmNewPwd'"
            type="password"
            autocomplete="new-password"
            :maxlength="pwdMaxLen"
            :placeholder="$t('COMMON_PASSWORD_CONFIRM')"
            @input="input('userPwd2', $event)"
          ></el-input>
        </div>
      </el-form-item>
    </el-form>

    <!-- 修改密码结果提示 -->
    <div
      v-if="result !== 0"
      class="login-result resultMoify"
      :class="{ success: result === 1, error: result === 2 }"
    >
      <!-- 修改成功提示 -->
      <div v-if="result === 1" id="modifySuccessMessage" class="result-item">
        <el-icon :size="16">
          <IconSuccess />
        </el-icon>
        <span class="tip-msg success">{{ $t('LOGIN_MODIFY_SUCCESS') }}</span>
      </div>
      <!-- 修改失败提示 -->
      <div v-if="result === 2" id="modifyFailedMessage" class="result-item">
        <el-icon :size="16">
          <IconError />
        </el-icon>
        <span class="tip-msg error">{{ saveFailedMessage }}</span>
      </div>
    </div>

    <!-- 保存按钮 -->
    <div class="login-modify-save">
      <el-button
        id="btLoginConfirm"
        class="save"
        type="primary"
        :disabled="disabled"
        @click="updatePassword()"
      >
        {{ $t('COMMON_CONFIRM') }}
      </el-button>
      <el-button
        v-if="!firstLoginPolicy"
        id="btLoginBack"
        class="cancel"
        type="text"
        @click="back()"
      >
        {{ $t('COMMON_BACK') }}
      </el-button>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.root-container {
  p.modify-title {
    font-size: 28px;
    line-height: 24px;
    margin-bottom: 16px;
  }
  p.init-pwd-tip {
    font-size: 16px;
    color: #8d98aa;
    line-height: 24px;
  }
}

.modify-form {
  margin-top: 32px;
}
.login-modify-container {
  width: 100%;
}
.login-modify-save {
  margin-top: 36px;
  text-align: center;
  .save {
    width: 100%;
    height: 48px;
    font-size: 16px;
  }
  .cancel {
    font-size: 16px;
    margin-top: 16px;
  }
}
.login-result {
  margin-top: 5px;
  padding: 0 5px;
  span.tip-msg {
    vertical-align: top;
  }
  span.success {
    color: green;
  }
  span.error {
    color: red;
  }
}

:deep(.el-form-item:last-child) {
  margin-bottom: 0;
}

:deep(.el-button) {
  border-radius: 2px;
}
:deep(.el-input) {
  height: 48px;
  .el-input__inner {
    font-size: 16px;
    height: 48px;
  }
  input::-webkit-input-placeholder,
  textarea::-webkit-input-placeholder {
    color: $FONT-COLOR-PLACEHOLDER !important;
    font-size: 16px !important;
  }

  input::-moz-placeholder,
  textarea::-moz-placeholder {
    color: $FONT-COLOR-PLACEHOLDER !important;
    font-size: 16px !important;
  }

  input::-moz-placeholder,
  textarea::-moz-placeholder {
    color: $FONT-COLOR-PLACEHOLDER !important;
    font-size: 16px !important;
  }
}

:deep(.el-popper.modify-tip) {
  max-width: 360px !important;
}
</style>
