<!--
 * @Author: xiejiang
 * @Date: 2024-11-05 10:14:56
 * @LastEditors: zengzhe
 * @LastEditTime: 2024-12-30 14:27:25
 * @Description: 登录
 * Copyright（c）2024 by 好老师教育科技有限公司 All right Reserved.
-->
<template>
  <div class="login">
    <div class="left"></div>
    <div class="right">
      <div class="px-[168px] mt-[-40px]">
        <div class="text-center flex flex-col items-center">
          <!-- <img :src="logo" class="" width="46" alt="" /> -->
          <img :src="welcome" class="mb-[28px]" height="46" alt="" />
          <img :src="welcomeInfo" height="23" alt="" />
        </div>
        <div class="right-form">
          <t-form ref="formRef" label-align="top" class="login-form" :rules="rules" :data="formData" @submit="onSubmit">
            <t-form-item name="mobile" :required-mark="false">
              <t-input
                v-model="formData.mobile"
                maxlength="11"
                clearable
                @input="
                  (v: any) => {
                    formData.mobile = v.target.value.replace(/[^0-9]/g, '')
                  }
                "
                placeholder="请输入手机号"
              >
                <template #prefix-icon>
                  <MobileIcon />
                </template>
              </t-input>
            </t-form-item>
            <t-form-item name="code" :required-mark="false">
              <t-input
                v-model="formData.code"
                maxlength="4"
                @input="
                  (v: any) => {
                    formData.code = v.target.value.replace(/[^0-9]/g, '')
                  }
                "
                placeholder="请输入验证码"
              >
                <template #prefix-icon>
                  <ShieldErrorIcon />
                </template>
              </t-input>
              <span
                :class="codeBtnDisabled || !isPhoneNumber(formData.mobile) ? 'code-btn isabled' : 'code-btn'"
                @click="getCode"
              >
                <span v-html="codeBtnTxt"></span>
              </span>
            </t-form-item>
            <t-form-item>
              <t-button
                class="!mt-[60px] !w-full !text-[16px]"
                :disabled="isLoginButtonDisable"
                type="submit"
                size="large"
                >登 录</t-button
              >
            </t-form-item>
          </t-form>
        </div>
      </div>
    </div>
    <Dialog
      :dialog-visible="isShowPuzzleVcode"
      title="请拖动滑块完成拼图"
      width="388px"
      :close-on-overlay-click="false"
      @close="isShowPuzzleVcode = false"
    >
      <template #body><SlideVerify ref="sliderVerify" @success="onSuccess" @fail="onFail" @again="onAgain" /></template>
    </Dialog>
  </div>
</template>

<script setup lang="ts">
import router from '@/routers'
import { FormInstanceFunctions, FormProps, MessagePlugin, CustomValidator } from 'tdesign-vue-next'
import { useUserStore } from '@/stores/modules/user'
import { useAuthStore } from '@/stores/modules/auth'
import { isPhoneNumber } from '@/utils'
import { LoginBySmsCode, getUserInfo, getCheckSliderCode, getSmsCode } from '@/api/modules/login'
import { HOME_URL } from '@/config'
// import logo from '@/assets/images/logo.png'
import welcome from '@/assets/images/welcome.png'
import welcomeInfo from '@/assets/images/welcome-info.png'
onMounted(() => {})

const validateTelePhone: CustomValidator = async val => {
  if (!isPhoneNumber(val)) {
    return {
      result: false,
      message: '请输入正确的手机号码！',
      type: 'error'
    }
  } else {
    await new Promise(resolve => {
      const timer = setTimeout(() => {
        resolve(val)
        clearTimeout(timer)
        return {
          result: false,
          message: '该用户不存在！',
          type: 'error'
        }
      })
    })

    return {
      result: true,
      message: '',
      type: 'success'
    }
  }
}

const userStore = useUserStore()
const formRef = useTemplateRef<FormInstanceFunctions>('formRef')
const formData = ref<{
  mobile: string
  code: string // 短信验证码
}>({
  mobile: '',
  code: ''
})
const rules: FormProps['rules'] = {
  mobile: [
    {
      validator: validateTelePhone
    }
  ],
  code: [
    {
      required: true,
      message: '请输入短信验证码',
      trigger: 'blur'
    }
  ]
}
const codeBtnDisabled = ref<boolean>(false) // 是否禁用获取验证码按钮
const codeBtnTxt = ref<string>('获取验证码') // 获取验证码按钮文字
// 获取短信验证码
let timmer: ReturnType<typeof setTimeout>
const isShowPuzzleVcode = ref(false)
const sliderVerify = ref()
// 发送短信验证码
const getCode = function () {
  if (!isPhoneNumber(formData.value.mobile) || codeBtnDisabled.value) {
    return
  }
  isShowPuzzleVcode.value = true
}

// 拼图验证
interface OnSuccess {
  nonceStr?: string
  value?: number
  blockY?: number
}

//拼图验证成功
const onSuccess = (val: OnSuccess) => {
  getCheckSliderCode(val)
    .then(() => {
      isShowPuzzleVcode.value = false
      onPuzzleVcodeClose()
    })
    .catch(() => {
      sliderVerify.value.refresh()
    })
}
//关闭拼图验证码
const onPuzzleVcodeClose = () => {
  getSmsCode({
    telephone: formData.value.mobile
  })
    .then(() => {
      MessagePlugin.success('验证成功!')
      // 重置密码的验证码
      codeBtnTxt.value = '<span class="text-primary">60s</span>后重新获取'
      codeBtnDisabled.value = true
      let i = 60
      timmer = setInterval(() => {
        i--
        codeBtnTxt.value = `<span class="text-primary">${i}s</span>后重新获取`
        if (i == 0) {
          codeBtnTxt.value = '重新获取验证码'
          codeBtnDisabled.value = false
          window.clearInterval(timmer)
          sliderVerify.value.refresh()
        }
      }, 1000)
    })
    .catch(() => {
      sliderVerify.value.refresh()
    })
}
const onFail = (msg: string) => {
  MessagePlugin.error(msg || '验证失败!')
}
/* 滑动验证异常*/
const onAgain = () => {
  MessagePlugin.error('滑动操作异常，请重试')
}

// 是否禁用登录按钮
const isLoginButtonDisable = computed(() => {
  return !(formData.value.mobile && isPhoneNumber(formData.value.mobile) && formData.value.code)
})

// 登录
const onSubmit: FormProps['onSubmit'] = ({ validateResult }) => {
  if (validateResult === true) {
    const payloadMsg = {
      mobile: formData.value.mobile,
      code: formData.value.code
    }
    try {
      LoginBySmsCode(payloadMsg).then(({ data }) => {
        userStore.setToken(data.token)
        getUserInfo().then(result => {
          userStore.setUserInfo(result.data)
          // 设置可访问的菜单
          useAuthStore().setAuthMenuList(result.data.menuTree)
          // 设置可访问的按钮
          useAuthStore().setAuthButtonList(result.data.menuButtonSigns)
          // 设置用户菜单权限的name集合
          useAuthStore().setRouteNameMap(useAuthStore().authMenuListGet)
          router.push({ path: HOME_URL })
        })
      })
    } catch {
      MessagePlugin.error('登录失败!')
    }
  }
}
</script>

<style scoped lang="less">
.login {
  display: flex;
  min-width: 1280px;
  height: 100%;
  overflow: hidden;

  .left {
    flex: 1;
    background: url('@/assets/images/illustration.png') no-repeat;
    background-size: cover;
  }

  .right {
    position: relative;
    box-sizing: border-box;
    width: 734px;
    background-color: var(--td-white);
    display: flex;
    align-items: center;
    justify-content: center;

    &-form {
      margin-top: 56px;

      :deep(.t-input__wrap) {
        flex: 1;
        border-bottom: 1px solid var(--td-gray-color-3);
        border-radius: 0;
        box-shadow: none;

        .t-input {
          height: 48px;
          border: none;
        }

        .t-input--focused {
          box-shadow: none;
        }
      }

      :deep(.t-form__label) {
        color: var(--font-gray-0);
      }

      .code-btn {
        display: inline-block;
        width: 112px;
        height: 48px;
        line-height: 48px;
        text-align: center;
        margin-left: 20px;
        border-radius: 4px;
        color: var(--td-brand-color);
        font-size: 14px;
        padding: 0;
        position: absolute;
        right: 0;
        bottom: 0;
        cursor: pointer;
        z-index: 1;
      }

      .isabled {
        color: var(--td-font-gray-3);
        cursor: not-allowed;
      }
    }
  }
}
</style>
