<script setup lang="ts">
import { useRouter, useRoute } from 'vue-router'
import ErrorTips from './components/ErrorTips.vue'
import { useUserStore } from '@/stores/modules/user'
import ScoringSystem from '@/views/Dashboard/src/components/ScoringSystem.vue'
import CryptoJS from 'crypto-js'
import dayjs from 'dayjs'

const router = useRouter()
const route = useRoute()

// 手动获取url中的参数，直接获取route.query的参数时如果有+号会被转义成空格
const getQueryParams = (url: string) => {
  const params = url.split('?')[1]
  const query = {}
  if (params) {
    params.split('&').forEach((param) => {
      const [key, value] = param.split('=')
      query[key] = value
    })
  }
  return query
}
const handleTokenRedirect = () => {
  if (route.query.token && route.query.uname) {
    const obj: any = getQueryParams(route.fullPath)
    $api
      .login({
        uname: obj.uname,
        token: obj.token
      })
      .then((res: any) => {
        if (res.code === 200) {
          const { data } = res
          if (data.msg === 'today' || data.msg === 'last') {
            const expiredDays = data.msg === 'today' ? 'today' : `in ${data.data} days`
            ElMessageBox.confirm(
              `Your password will expire ${expiredDays}, please reset your password`,
              'Prompt',
              {
                confirmButtonText: 'OK',
                cancelButtonText: 'Change Password',
                type: 'warning',
                confirmButtonClass: 'el-button--dark',
                cancelButtonClass: 'el-button--main',
                distinguishCancelAndClose: true
              }
            ).catch((action: any) => {
              if (action === 'cancel') {
                router.push({
                  name: 'Reset Password'
                })
              }
            })
          }
          userStore.setUsername(res.data.uname || '')
          router.push('/')
        } else if (res.code === 400) {
          const { data } = res
          if (data.msg === 'Invalid token') {
            ElMessageBox.alert('Invalid token', 'Prompt', {
              confirmButtonText: 'OK',
              type: 'warning',
              confirmButtonClass: 'el-button--dark'
            })
          } else if (data.msg === 'passwordExpires') {
            ElMessageBox.alert('Password expired, please change your password', 'Prompt', {
              confirmButtonText: 'OK',
              type: 'warning',
              confirmButtonClass: 'el-button--dark'
            })
            userStore.setUsername(res.data.uname || '')
            router.push({
              name: 'Reset Password'
            })
          }
        }
      })
  }
}
handleTokenRedirect()

const loginForm = ref({
  username: '',
  password: '',
  email: ''
})

const isRememerPwd = ref(false)
const secretKey = 'fT5!R1k$7Mv@4Q9X'
// AES 加密函数
const encryptPassword = (password) => {
  return CryptoJS.AES.encrypt(password, secretKey).toString()
}

// AES 解密函数
const decryptPassword = (encryptedPassword) => {
  const bytes = CryptoJS.AES.decrypt(encryptedPassword, secretKey)
  return bytes.toString(CryptoJS.enc.Utf8)
}

// 存储账号和加密后的密码
const saveCredentials = () => {
  clearCredentials()
  const encryptedPassword = encryptPassword(loginForm.value.password) // 加密密码
  localStorage.setItem('account', loginForm.value.username)
  localStorage.setItem('password', encryptedPassword)
}

// 验证当前用户是否存在
const handleCheckUser = () => {
  if (!loginForm.value.username) {
    return
  }
  // 这里是验证用户是否存在的逻辑
  $api.isUserNameExit({ uname: loginForm.value.username }).then((res: any) => {
    if (res.code === 200) {
      if (res.data.msg !== 'no_exist') {
        isUserNameExit.value = true
      } else {
        loginError.value.username = true
        isUserNameExit.value = false
      }
    } else {
      isUserNameExit.value = false
    }
  })
}

// 读取存储的账号和解密后的密码
const getCredentials = () => {
  const username = localStorage.getItem('account')
  const encryptedPassword = localStorage.getItem('password')
  if (username && encryptedPassword) {
    const password = decryptPassword(encryptedPassword) // 解密密码
    loginForm.value.username = username
    loginForm.value.password = password
    isRememerPwd.value = true
    // 验证用户名是否存在
    handleCheckUser()
  }
}

// 删除存储的账号和密码
const clearCredentials = () => {
  localStorage.removeItem('account')
  localStorage.removeItem('password')
}
getCredentials()
const status = ref(route.query.status || 'login')
watch(status, () => {
  loginForm.value = {
    username: '',
    password: '',
    email: ''
  }
  loginError.value = {
    username: false,
    password: false,
    email: false
  }
  isRememerPwd.value = false
  isUserNameExit.value = false
})

const loginError: any = ref({
  username: false,
  password: false,
  email: false
})

const userStore = useUserStore()

const sliderVerificationRef = ref()
const sliderVerificationFn = () => {
  isShowSliderVerification.value = true
  nextTick(() => {
    sliderVerificationRef.value.openDialog()
  })
}
const isShowSliderVerification = ref(false)

const confirmVerifyStatus = ref('')
const secretVerificationKey = 'fT5!R1k$7Mv@4Q9X'
const fixedIv = '1234567890123456' // 固定的初始化向量，长度为16字符
// 判断用户是否完成验证，完成后生成一个密文传给后端
// AES 加密函数
const encryptVerificationPwd = (password) => {
  const key = CryptoJS.enc.Utf8.parse(secretVerificationKey) // 解析密钥
  const iv = CryptoJS.enc.Utf8.parse(fixedIv) // 解析IV
  const encrypted = CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse(password), key, { iv: iv })
  return encrypted.toString()
}

// 点击登录按钮
const handleVerification = () => {
  if (!isUserNameExit.value || !loginForm.value.username) {
    return
  }
  sliderVerificationFn()
  // 这里是登录逻辑
  // handleLoginAfterVerify()
}
// 验证结束后通过status值判断调登录还是忘记密码接口
const confirmVerification = () => {
  // 生成验证成功的密文
  const pwd = dayjs().unix()
  confirmVerifyStatus.value = encryptVerificationPwd(pwd)
  isShowSliderVerification.value = false

  if (status.value === 'login') {
    handleLoginAfterVerify()
  } else {
    handleSendPassword()
  }
}

// 验证结束后调用登录接口
const handleLoginAfterVerify = () => {
  $api
    .login({
      uname: loginForm.value.username,
      psw: loginForm.value.password,
      verifcation_code: confirmVerifyStatus.value
    })
    .then((res: any) => {
      if (res.code === 200) {
        const { data } = res
        if (isRememerPwd.value) {
          saveCredentials()
        } else {
          clearCredentials()
        }
        if (data.msg === 'today' || data.msg === 'last') {
          const expiredDays = data.msg === 'today' ? 'today' : `in ${data.data} days`
          ElMessageBox.confirm(
            `Your password will expire ${expiredDays}, please reset your password`,
            'Prompt',
            {
              confirmButtonText: 'OK',
              cancelButtonText: 'Change Password',
              type: 'warning',
              confirmButtonClass: 'el-button--dark',
              cancelButtonClass: 'el-button--main',
              distinguishCancelAndClose: true
            }
          ).catch((action: any) => {
            if (action === 'cancel') {
              router.push({
                name: 'Reset Password'
              })
            }
          })
        }
        userStore.setUsername(res.data.uname || '')
        router.push('/')
      } else if (res.code === 400) {
        const { data } = res
        if (data.msg === 'password_error') {
          loginError.value.password = true
        } else if (data.msg === 'error_times') {
          errorTipsRef.value.openDialog()
        } else if (data.msg === 'passwordExpires') {
          ElMessageBox.alert('Password expired, please change your password', 'Prompt', {
            confirmButtonText: 'OK',
            type: 'warning',
            confirmButtonClass: 'el-button--dark'
          })
          userStore.setUsername(res.data.uname || '')
          router.push({
            name: 'Reset Password'
          })
        }
      }
    })
}

// 从忘记密码返回登录
const backLogin = (emailTips: boolean) => {
  status.value = 'login'
  isEmailTips.value = emailTips
  emailTipsContent.value = emailTips ? 'Your password sent to registered email.' : ''
  // 如果是成功忘记密码，清空保存的账号密码
  // 如果是直接返回登录，获取保存的账号密码
  setTimeout(() => {
    if (emailTips) {
      clearCredentials()
    } else {
      getCredentials()
    }
  }, 0)
}

const isUserNameExit = ref(false)

const handleForgot = () => {
  status.value = 'reset'
  handleDeleteEmailTips()
}
const handleSendPassword = () => {
  if (!isUserNameExit.value || !loginForm.value.username) {
    return
  }
  // 这里是发送密码逻辑
  $api
    .forgotPassword({
      login: loginForm.value.username,
      email: loginForm.value.email,
      verifcation_code: confirmVerifyStatus.value
    })
    .then((res: any) => {
      if (res.code === 200) {
        backLogin(true)
      }
    })
}

const isEmailTips = ref(false)
const emailTipsContent = ref()
// 判断当前路由中是否有 isChange 参数，如果有则提示修改密码成功
const initEmailTips = () => {
  if (route.query.isChange === 'true') {
    isEmailTips.value = true
    emailTipsContent.value = 'Changed successfully. Please log in.'
  } else {
    isEmailTips.value = false
    emailTipsContent.value = 'Your password sent to registered email.'
  }
}
initEmailTips()

const handleDeleteEmailTips = (type?: any) => {
  isEmailTips.value = false
  if (type) {
    loginError.value[type] = false
  }
}

const errorTipsRef = ref()
</script>

<template>
  <div class="login">
    <ScoringSystem class="scoring-system"></ScoringSystem>
    <el-card class="login-card" v-if="status === 'login'">
      <div class="card-title">
        <span class="welcome">Welcome to KLN Portal</span>
        <span class="tips">Login to your account</span>
      </div>
      <div class="send-email-tips" :style="{ display: isEmailTips ? 'flex' : 'none' }">
        <div>
          <span class="font_family icon-icon_confirm_b success-icon"></span>
          <span class="text-content">{{ emailTipsContent }}</span>
        </div>

        <span
          @click="handleDeleteEmailTips"
          class="font_family icon-icon_reject_b delete-icon"
        ></span>
      </div>
      <div class="login-form">
        <div class="label">
          <span>User Name</span>
        </div>
        <el-input
          ref="userNameRef"
          :class="{ 'is-error': loginError.username }"
          v-model="loginForm.username"
          class="user-name"
          placeholder="Please input user name"
          @focus="handleDeleteEmailTips('username')"
          @blur="handleCheckUser"
        >
          <template #prefix>
            <span class="font_family icon-icon_username_b"></span>
          </template>
          <template #suffix>
            <span v-if="isUserNameExit" class="font_family icon-icon_confirm_b confirm-icon"></span>
          </template>
        </el-input>
        <div class="error" v-if="loginError.username">This account does not exist.</div>
        <div class="label">
          <span>Password</span>
          <span class="forgot-password" @click="handleForgot">Forgot Password?</span>
        </div>
        <el-input
          ref="passWordRef"
          :class="{ 'is-error': loginError.password }"
          v-model="loginForm.password"
          type="password"
          placeholder="Please input password"
          show-password
          @focus="handleDeleteEmailTips('password')"
          ><template #prefix>
            <span class="font_family icon-icon_password_b"></span>
          </template>
        </el-input>
        <div class="error" v-if="loginError.password">Incorrect password. Please try again.</div>

        <el-checkbox
          class="remember-password"
          v-model="isRememerPwd"
          label="Remember Password"
          size="large"
        />
        <el-button @click="handleVerification" class="el-button--dark login-btn">Login</el-button>
      </div>
      <template #footer>
        <div class="license">
          <span>Copyright © <span class="company">2024 KLN.</span> All rights reserved.</span>
        </div>
      </template>
    </el-card>
    <el-card class="login-card" v-else-if="status === 'reset'">
      <div class="card-title">
        <span class="welcome">Password Retrieval</span>
        <span class="tips">We'll send your password to your email address.</span>
      </div>
      <div class="login-form">
        <div class="label">
          <span>User Name</span>
        </div>
        <el-input
          ref="userNameRef"
          :class="{ 'is-error': loginError.username }"
          v-model="loginForm.username"
          class="user-name"
          placeholder="Please input user name"
          @focus="handleDeleteEmailTips('username')"
          @blur="handleCheckUser"
        >
          <template #prefix>
            <span class="font_family icon-icon_username_b"></span>
          </template>
          <template #suffix>
            <span v-if="isUserNameExit" class="font_family icon-icon_confirm_b confirm-icon"></span>
          </template>
        </el-input>
        <div class="error" v-if="loginError.username">This account does not exist</div>
        <div class="label">
          <span>Email Address</span>
        </div>
        <el-input
          ref="passWordRef"
          :class="{ 'is-error': loginError.email }"
          v-model="loginForm.email"
          placeholder="Please input your email address"
          @focus="handleDeleteEmailTips('email')"
          ><template #prefix>
            <span class="font_family icon-icon_email_b"></span>
          </template>
        </el-input>
        <div class="error" v-if="loginError.email">Incorrect email. Please try again.</div>

        <el-button @click="handleVerification" class="el-button--dark login-btn"
          >Send Password</el-button
        >
        <div @click="backLogin(false)" class="back-text">
          <span class="font_family icon-icon_back_b"></span>
          <span class="text"> Back to login</span>
        </div>
      </div>
      <template #footer>
        <div class="license">
          <span>Copyright © <span class="company">2024 KLN.</span> All rights reserved.</span>
        </div>
      </template>
    </el-card>
    <VSliderVerification
      v-if="isShowSliderVerification"
      @close="confirmVerification"
      ref="sliderVerificationRef"
    ></VSliderVerification>
    <ErrorTips ref="errorTipsRef" @forget-password="status = 'reset'"></ErrorTips>
  </div>
</template>

<style lang="scss" scoped>
.login {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
  width: 100%;
  background: url(../src/image/bg.png) no-repeat center center;
  background-size: cover;
  .scoring-system {
    position: absolute;
    top: 0;
    width: 100%;
    background: linear-gradient(251deg, #fff4eb 22.66%, #f0f3ff 44.57%, #e0f7f9 70.46%);
  }
}

.login-card {
  width: 400px;

  .card-title {
    display: flex;
    flex-direction: column;
    align-items: center;
    height: 94px;
    padding-top: 32px;
    background: url(../src/image/bg-login-card.png) no-repeat center center;
    background-position: top left; /* 从左上角开始显示 */
    background-size: 400px 100px; /* 保持背景图像的原始尺寸 */

    .welcome {
      margin-bottom: 16px;
      font-size: 24px;
      font-weight: 700;
    }
  }

  .send-email-tips {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: 40px;
    margin: 24px 40px 0;
    padding: 12px;
    padding-left: 14px;
    background-color: #e5f6f1;
    border-radius: 6px;

    .success-icon {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      height: 16px;
      width: 16px;
      padding-left: 1px;
      margin-right: 4px;
      font-size: 14px;
      color: #fff;
      background-color: var(--color-success);
      border-radius: 50%;
    }
    .text-content {
      color: var(--color-success);
    }

    .delete-icon {
      // align-self: ri;
      margin-left: 8px;
      color: var(--color-success);
      cursor: pointer;
    }
  }

  :deep(.el-card__body) {
    padding: 0px;
    padding-bottom: 16px;
  }

  .login-btn {
    width: 100%;
    height: 40px;
    margin-top: 16px;
  }
}

.login-form {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  padding: 0 40px;

  .el-input {
    height: 40px;
    .confirm-icon {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      height: 16px;
      width: 16px;
      margin-right: 4px;
      font-size: 14px;
      color: #fff;
      background-color: var(--color-success);
      border-radius: 50%;
    }

    &.is-error {
      :deep(.el-input__wrapper) {
        box-shadow: 0 0 0 1px var(--color-danger) inset;
      }
    }

    :deep(.el-input__prefix) {
      margin: 0 4px;
      background-color: transparent;
    }
  }
  .verification-code {
    margin-top: 16px;
    .verification-code-img {
      display: block;
      width: 130px;
      height: 38px;
      object-fit: cover;
    }
    :deep(.el-input-group__append) {
      padding: 0;
      padding-right: 1px;
    }
  }
  .el-input.user-name {
    :deep(.el-input__wrapper) {
      padding-right: 6px;
    }
  }

  .label {
    display: flex;
    justify-content: space-between;
    width: 100%;
    margin-top: 16px;
    font-size: 12px;
    line-height: 18px;

    span {
      color: var(--color-neutral-2);
    }

    .forgot-password {
      color: var(--color-theme);
      cursor: pointer;
    }
  }

  .error {
    font-size: 12px;
    color: var(--color-danger);
    line-height: 14px;
  }
  .remember-password {
    height: 24px;
    margin-top: 16px;
  }

  .back-text {
    width: 100%;
    height: 20px;
    margin-top: 24px;
    margin-bottom: 8px;
    text-align: center;
    cursor: pointer;

    span {
      color: var(--color-theme);
    }

    .text {
      display: inline-block;
      transform: translateY(-2px);
      font-size: 12px;
    }
  }
}

.license {
  display: flex;
  flex-direction: column;
  align-items: center;
  font-size: 12px;

  .company {
    color: var(--color-theme);
  }

  span {
    color: var(--color-neutral-2);
  }
}
</style>
