<template>
  <div class="register">
    <div class="title text-font-white mt-5 mb-16 text-2xl">{{ title }}</div>
    <PhoneInput
      :placeholder="phoneConfig.placeholder"
      :maxlength="phoneConfig.maxLen"
      :clearable="true"
      :value="phone"
      :type="phoneConfig.type"
      @change="handlePhoneChange"
      @selectItem="handleSelect"
    >
    </PhoneInput>
    <transition name="fade" mode="out-in">
      <CodeInput
        v-if="loginWay === eLoginWay.CODE"
        :placeholder="codeConfig.placeholder"
        :maxlength="codeConfig.maxLen"
        :value="code"
        :type="codeConfig.type"
        :handleChange="handleCodeChange"
        :phone="phone"
        :sendSmsFunc="sendSmsFunc"
        :sendVoiceFunc="sendVoiceFunc"
        :phoneValid="phoneValid"
      >
      </CodeInput>
      <div v-else-if="loginWay === eLoginWay.PWD" class="relative">
        <Input
          :placeholder="pwdConfig.placeholder"
          :maxlength="pwdConfig.maxLen"
          :value="pwd"
          :type="pwdConfig.type"
          @change="handlePwdChange"
        >
          <template #button> </template>
        </Input>
        <div class="flex items-center justify-between mt-1">
          <div>
            <Check
              :checked="rememberPwdChecked"
              @change="handleRememberPwdChange"
              class="text-font-gray text-sm"
              >记住密码</Check
            >
          </div>
          <div class="text-font-gray text-sm" @click="handleClickForgetPwd">
            忘记密码
          </div>
        </div>
      </div>
    </transition>
    <div class="flex items-center mt-16">
      <div class="flex items-center" @click="handleClickRadio">
        <transition name="fade" mode="out-in" :duration="50">
          <img
            :key="checkStatus"
            class="w-4 mr-1 transition-all"
            :src="checkStatus ? checkedIcon : notCheckedIcon"
          />
        </transition>
        <span class="text-font-white">我已阅读并同意</span>
      </div>
      <div class="underline text-font-blue" @click="handleClickUserAgreement">
        用户协议
      </div>
    </div>
    <transition name="fade" mode="out-in">
      <SlideValidator
        v-if="
          accountType !== undefined &&
          loginWay !== undefined &&
          accountType !== eAccountType.NO_REG
        "
        :key="randomNum"
        @confirm="handleSlideConfirm"
        class="my-3"
      />
    </transition>
    <transition name="fade" mode="out-in">
      <div v-if="accountType !== undefined && loginWay !== undefined">
        <div>
          <div v-if="accountType === eAccountType.NO_REG">
            <LoginButton
              text="注册"
              :disabled="getRegisterDisableStatus"
              :loading="loading"
              @click="handleClickRegister"
            ></LoginButton>
          </div>
          <div v-else>
            <LoginButton
              text="登录"
              :disabled="getLoginBtnDisableStatus"
              :loading="loading"
              @click="handleClickLogin"
            ></LoginButton>
            <div v-if="loginByPwdFunc">
              <div
                v-if="loginWay === eLoginWay.PWD"
                @click="transferLoginWay(eLoginWay.CODE)"
                class="text-center text-font-blue"
              >
                验证码登录
              </div>
              <div
                class="text-center text-font-blue"
                v-if="loginWay === eLoginWay.CODE"
                @click="transferLoginWay(eLoginWay.PWD)"
              >
                密码登录
              </div>
            </div>
          </div>
        </div>
      </div>
    </transition>
    <Overlay v-show="overlayShow" :lock-scroll="false">
      <UserAgreement :setOverlayShow="setOverlayShow" />
    </Overlay>
  </div>
</template>

<script lang='ts'>
import Input from "@/components/common/Input/index.vue";
import CodeInput from "./components/CodeInput/index.vue";
import { RadioGroup, Radio, Overlay, Dialog } from "vant";
import Vue, { PropType } from "vue";
import {
  eAccountType,
  eLoginWay,
  iRememberPhonePwd,
  tAccountStatusCheckFunc,
  tLoginByCodeFunc,
  tLoginByPwdFunc,
  tRegisterFunc,
  tSendSmsFunc,
  tSendVoiceFunc,
} from "./types";
import { phoneConfig, codeConfig, pwdConfig } from "./const";
import LoginButton from "./components/LoginButton/index.vue";
import UserAgreement from "./UserAgreement.vue";
import Check from "@/components/common/Check/index.vue";
import PhoneInput from "./components/PhoneInput/index.vue";
import SlideValidator from "@/components/common/SlideValidator/index.vue";

const notCheckedIcon = require("@/assets/icons/not_checked.png");
const checkedIcon = require("@/assets/icons/checked.png");

import LoginSerivce from "./LoginService";

export default Vue.extend({
  props: {
    title: {
      type: String,
      required: true,
    },
    accountStatusCheckFunc: {
      type: Function as PropType<tAccountStatusCheckFunc>,
      required: true,
    },
    registerFunc: {
      type: Function as PropType<tRegisterFunc>,
      required: true,
    },
    sendSmsFunc: {
      type: Function as PropType<tSendSmsFunc>,
      required: true,
    },
    sendVoiceFunc: {
      type: Function as PropType<tSendVoiceFunc>,
      required: false,
    },
    loginByCodeFunc: {
      type: Function as PropType<tLoginByCodeFunc>,
      required: true,
    },
    loginByPwdFunc: {
      type: Function as PropType<tLoginByPwdFunc | null>,
    },
  },
  components: {
    Input,
    RadioGroup,
    Radio,
    CodeInput,
    LoginButton,
    Overlay,
    UserAgreement,
    Check,
    PhoneInput,
    SlideValidator,
  },
  data() {
    return {
      notCheckedIcon,
      checkedIcon,
      phoneConfig,
      codeConfig,
      pwdConfig,
      eAccountType,
      eLoginWay,
      accountType: <undefined | eAccountType>undefined,
      loginWay: <undefined | eLoginWay>undefined,
      checkStatus: false,
      phone: "",
      code: "",
      pwd: "",
      overlayShow: false,
      rememberPwdChecked: false,
      slideConfirmed: false,
      randomNum: Math.random(),
      loading: false,
    };
  },
  methods: {
    handleSelect(item: iRememberPhonePwd) {
      this.phone = item.phone;
      this.pwd = item.pwd;
    },
    handleClickRadio() {
      this.checkStatus = !this.checkStatus;
    },
    handlePhoneChange(value: string) {
      this.phone = value;
    },
    handleCodeChange(v: string) {
      this.code = v;
    },
    handleClickForgetPwd() {
      this.$router.push({
        name: "PwdFind",
      });
    },
    handleSlideConfirm() {
      this.slideConfirmed = true;
    },
    handlePwdChange(v: string) {
      this.pwd = v;
    },
    async handleClickRegister(e: MouseEvent) {
      if (this.getRegisterDisableStatus) return;
      const { phone, code } = this;
      // 调用注册接口
      this.loading = true;
      try {
        const regResult = await this.registerFunc(phone, code);
      } catch (err) {}
      this.loading = false;
    },
    async handleClickLogin() {
      const { phone, code, pwd } = this;
      this.loading = true;
      try {
        if (this.loginWay === eLoginWay.PWD) {
          // 调用登录接口
          await (this.loginByPwdFunc as tLoginByCodeFunc)(phone, pwd);
          const { rememberPwdChecked } = this;
          if (rememberPwdChecked) {
            LoginSerivce.getIntance().addPhoneWithPwdToStorage(
              this.phone,
              this.pwd
            );
          }
        } else if (this.loginWay == eLoginWay.CODE) {
          // 调用登录接口
          await this.loginByCodeFunc(phone, code);
        }
      } catch (err) {}
      this.loading = false;
      this.randomNum = Math.random();
      this.slideConfirmed = false;
    },
    handleClickUserAgreement() {
      // 展示用户协议
      this.overlayShow = true;
    },
    transferLoginWay(loginType: eLoginWay) {
      if (
        this.accountType === eAccountType.REG_NOPD &&
        loginType === eLoginWay.PWD
      ) {
        Dialog.confirm({
          title: "提示",
          message: "您还没有设置过登录密码，无法使用密码登录。",
          cancelButtonText: "设置密码",
          confirmButtonText: "验证码登录",
        })
          .then(() => {
            this.transferLoginWay(eLoginWay.CODE);
          })
          .catch(() => {
            this.$router.push({
              name: "PwdSetting",
              query: {
                phone: this.phone,
              },
            });
          });
        return;
      }
      this.loginWay = loginType;
    },
    setOverlayShow(v: boolean) {
      this.overlayShow = v;
    },
    handleRememberPwdChange(checked: boolean) {
      return (this.rememberPwdChecked = checked);
    },
    sendSms() {
      return this.sendSmsFunc(this.phone);
    },
    sendVoice() {
      return this.sendVoiceFunc(this.phone);
    },
  },
  computed: {
    codeValid(): boolean {
      return this.code.length === codeConfig.maxLen;
    },
    checkStatusValid(): boolean {
      return this.checkStatus === true;
    },
    phoneValid(): boolean {
      return this.phone.length === phoneConfig.maxLen;
    },
    pwdValid(): boolean {
      return pwdConfig.validate(this.pwd);
    },
    getRegisterDisableStatus(): boolean {
      return !(this.codeValid && this.checkStatusValid && this.phoneValid);
    },
    getLoginBtnDisableStatus(): boolean {
      if (this.loginWay === eLoginWay.CODE) {
        return (
          !(this.codeValid && this.phoneValid && this.checkStatusValid) ||
          !this.slideConfirmed
        );
      } else if (this.loginWay === eLoginWay.PWD) {
        return (
          !(this.pwdValid && this.phoneValid && this.checkStatusValid) ||
          !this.slideConfirmed
        );
      }
      return true;
    },
  },
  watch: {
    phone(newV: string, oldV: string) {
      if (newV.length === phoneConfig.maxLen) {
        // 调用方法，获取该手机号的账户信息
        this.accountStatusCheckFunc(newV).then((result) => {
          this.accountType = result;
          this.loginWay = eLoginWay.CODE;
        });
      } else {
        this.loginWay = undefined;
      }
    },
  },
});
</script>
