<template>
  <n-form ref="formRef" :model="model" :rules="rules" size="large" :show-label="false">
    <n-form-item path="userName">
      <n-input v-model:value="model.username" placeholder="请输入用户名" />
    </n-form-item>
    <n-form-item path="password">
      <n-input v-model:value="model.passwd" type="password" show-password-on="click" placeholder="请输入密码" />
    </n-form-item>
    <n-space :vertical="true" :size="24">
      <n-button
        type="primary"
        size="large"
        :block="true"
        :round="true"
        :loading="auth.loginLoading"
        @click="handleSubmit"
      >
        确定
      </n-button>
      <other-account @change="handleLoginOtherAccount" />
    </n-space>
  </n-form>
  <div v-show="mode === 'pop'" class="mask">
    <div class="verifybox" :style="{ 'max-width': '340px' }">
      <div class="verifybox-top">
        请完成安全验证
        <span class="verifybox-close" @click="closeBox">
          <i class="iconfont icon-close"></i>
        </span>
      </div>
      <div class="verifybox-bottom" :style="{ padding: mode === 'pop' ? '15px' : '0' }">
        <!-- 验证码容器 -->
        <verify-slide @success="verifySlideClose" />
      </div>
    </div>
  </div>
</template>
<script setup lang="ts">
import { reactive, ref } from 'vue';
import type { FormInst, FormRules } from 'naive-ui';
import type { AdminLoginParams } from '@/service';
import { useAuthStore } from '@/store';
import { formRules } from '@/utils';
import { encryption } from '@/utils/crypto/index';
import { OtherAccount } from './components';
import VerifySlide from './components/validate/Verify/VerifySlide.vue';

const mode = ref('push');
const closeBox = () => {
  mode.value = 'push';
};

const loginType = ref<string>('admin');

const model = reactive<AdminLoginParams>({
  username: 'wangyan',
  passwd: '123456',
  captchaVerification: ''
});

function verifySlideClose(result: any) {
  model.captchaVerification = result.captchaVerification;
  mode.value = 'push';
  handleSubmit();
}

const auth = useAuthStore();
const { login, studentLogin } = useAuthStore();
interface loginByType {
  [index: string]: (params: AdminLoginParams) => Promise<boolean>;
}
const userLoginType: loginByType = {
  admin: (params: AdminLoginParams) => {
    return login(params);
  },
  student: (params: AdminLoginParams) => {
    return studentLogin(params);
  }
};

const formRef = ref<HTMLElement & FormInst>();

const rules: FormRules = {
  password: formRules.pwd
};
async function handleSubmit() {
  mode.value = 'pop';
  await formRef.value?.validate();
  const { username, passwd, captchaVerification } = model;
  if (captchaVerification !== '') {
    const result = await userLoginType[loginType.value]({
      username,
      passwd: encryption(passwd),
      captchaVerification
    });
    if (result === false) {
      mode.value = 'push';
      if (model.captchaVerification !== '') {
        model.captchaVerification = '';
      }
    }
  } else {
    mode.value = 'pop';
  }
}

function handleLoginOtherAccount(param: { type: string }) {
  const { type } = param;
  loginType.value = type;
}
</script>

<style>
.mask {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 1001;
  width: 100%;
  height: 100vh;
  background: rgba(0, 0, 0, 0.3);
  transition: all 0.5s;
}

.verifybox {
  position: relative;
  box-sizing: border-box;
  border-radius: 2px;
  border: 1px solid #e4e7eb;
  background-color: #fff;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}

.verifybox-top {
  padding: 0 15px;
  height: 50px;
  line-height: 50px;
  text-align: left;
  font-size: 16px;
  color: #45494c;
  border-bottom: 1px solid #e4e7eb;
  box-sizing: border-box;
}

.verifybox-bottom {
  padding: 15px;
  box-sizing: border-box;
}

.verifybox-close {
  position: absolute;
  top: 13px;
  right: 9px;
  width: 24px;
  height: 24px;
  text-align: center;
  cursor: pointer;
}

.iconfont {
  font-family: 'iconfont' !important;
  font-size: 16px;
  font-style: normal;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.icon-close:before {
  content: ' ';
  display: block;
  width: 16px;
  height: 16px;
  position: absolute;
  margin: auto;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  z-index: 9999;
  background-image: url('data:image/png;base64,[encoded data, 5600 characters]');
  background-size: contain;
}
</style>
