<script setup lang="ts">
const dialogVisible = ref(false)

const openDialog = () => {
  dialogVisible.value = true
}

const pwdData = ref({
  oldPassword: '',
  newPassword: '',
  confirmPassword: ''
})
const loginError: any = ref({
  oldPassword: false,
  newPassword: false,
  confirmPassword: false
})
const newPwdErrTips = ref('')

const handleUpdate = () => {
  if (pwdData.value.newPassword !== pwdData.value.confirmPassword) {
    loginError.value.confirmPassword = true
    return
  }
  if (pwdData.value.newPassword.length < 12 || pwdData.value.newPassword.length > 20) {
    loginError.value.newPassword = true
    newPwdErrTips.value = 'Password length between 12 - 20'
    return
  }
  if (!/[A-Z]/.test(pwdData.value.newPassword)) {
    loginError.value.newPassword = true
    newPwdErrTips.value = 'Password must contain uppercase letters'
    return
  }
  if (!/[a-z]/.test(pwdData.value.newPassword)) {
    loginError.value.newPassword = true
    newPwdErrTips.value = 'Password must contain lowercase letters'
    return
  }
  if (!/[0-9]/.test(pwdData.value.newPassword)) {
    loginError.value.newPassword = true
    newPwdErrTips.value = 'Password must contain numbers'
    return
  }
  $api
    .changePwdByLogin({
      opsw: pwdData.value.oldPassword,
      npsw: pwdData.value.newPassword
    })
    .then((res) => {
      if (res.code === 200) {
        ElMessage.success('Password updated successfully')
        dialogVisible.value = false
      } else if (res.code === 400) {
        if (res.msg === 'Old password is incorrect') {
          loginError.value.oldPassword = true
        } else {
          loginError.value.newPassword = true
          newPwdErrTips.value = res.msg
        }
      }
    })
}

const hiddenError = (key: string) => {
  loginError.value[key] = false
}
const confirmPwd = () => {
  if (pwdData.value.confirmPassword !== pwdData.value.newPassword) {
    loginError.value.confirmPassword = true
  } else {
    loginError.value.confirmPassword = false
  }
}

const hasUppercase = ref(false)
const hasLowercase = ref(false)
const hasNumber = ref(false)
const isValidLength = ref(false)
const checkPassword = () => {
  const pwd = pwdData.value.newPassword

  // 检测是否包含大写字母
  hasUppercase.value = /[A-Z]/.test(pwd)

  // 检测是否包含小写字母
  hasLowercase.value = /[a-z]/.test(pwd)

  // 检测是否包含数字
  hasNumber.value = /[0-9]/.test(pwd)

  // 检测长度是否符合要求
  isValidLength.value = pwd.length >= 12 && pwd.length <= 20
}

const clearData = () => {
  pwdData.value = {
    oldPassword: '',
    newPassword: '',
    confirmPassword: ''
  }
  loginError.value = {
    oldPassword: false,
    newPassword: false,
    confirmPassword: false
  }
}
defineExpose({
  openDialog
})
</script>

<template>
  <el-dialog
    v-model="dialogVisible"
    class="change-password-dialog"
    @close="clearData"
    top="20vh"
    :width="400"
    title="Change Password"
  >
    <div>
      <div class="form-item">
        <span class="label">Old Password</span>
        <el-input
          v-model="pwdData.oldPassword"
          type="password"
          show-password
          :class="{ 'is-error': loginError.oldPassword }"
          placeholder="Please input Old Password"
          @focus="hiddenError('oldPassword')"
        >
          <template #prefix>
            <span class="font_family icon-icon_password_b"></span>
          </template>
        </el-input>
        <div class="error" v-if="loginError.oldPassword">Incorrect password. Please try again.</div>
      </div>
      <div class="form-item">
        <span class="label">New Password</span>
        <el-input
          v-model="pwdData.newPassword"
          type="password"
          show-password
          :class="{ 'is-error': loginError.newPassword }"
          placeholder="New password must contain both letter and numeral"
          @focus="hiddenError('newPassword')"
          @input="checkPassword"
        >
          <template #prefix>
            <span class="font_family icon-icon_password_b"></span>
          </template>
        </el-input>
        <div class="error" v-if="loginError.newPassword">{{ newPwdErrTips }}</div>
        <div class="limit-tips">
          <div class="tip-item">
            <span class="font_family icon-icon_confirm_b" :class="{ active: hasUppercase }"></span>
            <span>Password must contain uppercase letters</span>
          </div>
          <div class="tip-item">
            <span class="font_family icon-icon_confirm_b" :class="{ active: hasLowercase }"></span>
            <span>Password must contain lowercase letters</span>
          </div>
          <div class="tip-item">
            <span class="font_family icon-icon_confirm_b" :class="{ active: hasNumber }"></span>
            <span>Password must contain numbers</span>
          </div>
          <div class="tip-item">
            <span class="font_family icon-icon_confirm_b" :class="{ active: isValidLength }"></span>
            <span>Password length between12 - 20 </span>
          </div>
        </div>
      </div>
      <div class="form-item">
        <span class="label">Confirm Password</span>
        <el-input
          v-model="pwdData.confirmPassword"
          type="password"
          show-password
          :class="{ 'is-error': loginError.confirmPassword }"
          placeholder="Please Confirm Password"
          @focus="hiddenError('confirmPassword')"
          @blur="confirmPwd"
        >
          <template #prefix>
            <span class="font_family icon-icon_password_b"></span>
          </template>
        </el-input>
        <div class="error" v-if="loginError.confirmPassword">
          The password does not match. Please try again.
        </div>
      </div>
    </div>
    <template #footer>
      <el-button class="el-button--default" style="height: 40px" @click="dialogVisible = false"
        >Cancel</el-button
      >
      <el-button @click="handleUpdate" class="el-button--dark" style="height: 40px"
        >Update</el-button
      >
    </template>
  </el-dialog>
</template>

<style lang="scss">
.change-password-dialog {
  .el-dialog__body {
    padding: 8px 16px 0px;
  }
  .form-item {
    margin-bottom: 16px;
    .label {
      font-size: 12px;
    }
    .error {
      font-size: 12px;
      color: var(--color-danger);
      line-height: 14px;
    }
    .limit-tips {
      margin-top: 10px;
      .tip-item {
        display: flex;
        align-items: center;
        margin-bottom: 8px;
        font-size: 12px;
        color: var(--color-neutral-2);
        .font_family {
          display: flex;
          justify-content: center;
          align-items: center;
          height: 12px;
          width: 12px;
          padding-top: 1px;
          background-color: #b5b9bf;
          font-size: 10px;
          color: white;
          border-radius: 50%;
          &.active {
            background-color: #00a870;
          }
        }
        span {
          margin-left: 4px;
        }
      }
    }
    .el-input {
      height: 40px;
      &.is-error {
        .el-input__wrapper {
          box-shadow: 0 0 0 1px var(--color-danger) inset;
        }
      }
    }
  }
  .el-button {
    padding: 8px 24px;
  }
}
</style>
