<template>
  <nav-bar :bangsBlock="true" />
  <div class="register pt-5">
    <IconVue
      name="icon-a-shanchu1"
      color="black"
      size="20"
      class="mb-7"
      @click="handleClickClose"
    />
    <div class="flex justify-between items-center text-base">
      <img src="@/assets/icons/app-icon.png" class="h-12" />
    </div>
    <div class="title mt-10 mb-14 title-text text-app-txt">注册/登录</div>
    <PhoneInput
      :placeholder="phoneConfig.placeholder"
      :maxlength="phoneConfig.maxLen"
      :clearable="true"
      :value="phone"
      :type="phoneConfig.type"
      @change="handlePhoneChange"
      @selectItem="handleSelect"
      @clear="handleClear"
    ></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.toString()"
            class="w-4 mr-1 transition-all"
            :src="checkStatus ? checkedIcon : notCheckedIcon"
          />
        </transition>
        <span class="text-white" style="color: #474747 !important"
          >我已阅读并同意</span
        >
      </div>
      <div
        class="underline text-app-blue"
        @click="$router.push({ name: 'UserAgreement' })"
      >
        用户协议
      </div>
    </div>
    <transition name="fade" mode="out-in">
      <div
        v-if="accountType !== eAccountType.NULL && loginWay !== eLoginWay.NULL"
      >
        <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-app-blue"
              >
                验证码登录
              </div>
              <div
                class="text-center text-app-blue"
                v-if="loginWay === eLoginWay.CODE"
                @click="transferLoginWay(eLoginWay.PWD)"
              >
                密码登录
              </div>
            </div>
          </div>
        </div>
      </div>
    </transition>
  </div>
</template>

<script lang="ts">
import Input from "@/components/common/Input/index.vue";
import CodeInput from "./components/CodeInput/index.vue";
import { Dialog, Toast } from "vant";
import { PropType, defineComponent } 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 Check from "@/components/common/Check/index.vue";
import PhoneInput from "./components/PhoneInput/index.vue";
import SlideValidator from "@/components/common/SlideValidator/index.vue";
import IconVue from "@/components/common/Icon.vue";

import notCheckedIcon from "@/assets/icons/not_checked.png";
import checkedIcon from "@/assets/icons/checked.png";

import LoginSerivce from "./LoginService";
import NavBar from "@/components/NavBar/index.vue";

const accountType = eAccountType.NULL;
const loginWay = eLoginWay.NULL;

export default defineComponent({
  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>,
    },
  },
  components: {
    NavBar,
    Input,
    CodeInput,
    LoginButton,
    Check,
    PhoneInput,
    SlideValidator,
    IconVue,
  },
  data() {
    return {
      ignorePhoneCheck: false,
      notCheckedIcon,
      checkedIcon,
      phoneConfig,
      codeConfig,
      pwdConfig,
      eAccountType,
      eLoginWay,
      accountType: accountType,
      loginWay: loginWay,
      checkStatus: false,
      phone: "",
      code: "",
      pwd: "",
      rememberPwdChecked: false,
      randomNum: Math.random(),
      loading: false,
    };
  },
  methods: {
    handleClickClose() {
      this.$router.go(-1);
    },
    handleClear(phone: string) {
      this.pwd = "";
    },
    handleSelect(item: iRememberPhonePwd) {
      this.ignorePhoneCheck = true;
      this.phone = item.phone;
      this.pwd = item.pwd;
      this.rememberPwdChecked = true;
      this.loginWay = eLoginWay.PWD;
      this.accountType = eAccountType.REG_PDSET;
      this.$nextTick(() => {
        this.ignorePhoneCheck = true;
      });
    },
    handleClickRadio() {
      this.checkStatus = !this.checkStatus;
    },
    handlePhoneChange(e: string) {
      this.phone = e;
    },
    handleCodeChange(v: string) {
      this.code = v;
    },
    handleClickForgetPwd() {
      this.$router.push({
        name: "PwdFind",
      });
    },
    handlePwdChange(v: string) {
      this.pwd = v;
    },
    async handleClickRegister() {
      if (this.getRegisterDisableStatus) return;
      const { phone, code } = this;
      // 调用注册接口
      this.loading = true;
      try {
        await this.registerFunc(phone, code);
      } catch (err: any) {
        Toast.fail(err.message);
      }
      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) {
        console.log(err);
      }
      this.loading = false;
      this.randomNum = Math.random();
    },
    transferLoginWay(loginType: eLoginWay) {
      if (
        this.accountType === eAccountType.REG_NOPD &&
        loginType === eLoginWay.PWD
      ) {
        Dialog.confirm({
          title: "提示",
          message: "您还没有设置过登录密码，无法使用密码登录。",
          cancelButtonText: "设置密码",
          confirmButtonText: "验证码登录",
          className: "dialog-style-1",
        })
          .then(() => {
            this.transferLoginWay(eLoginWay.CODE);
          })
          .catch(() => {
            this.$router.push({
              name: "PwdSetting",
              query: {
                phone: this.phone,
              },
            });
          });
        return;
      }
      this.loginWay = loginType;
    },
    handleRememberPwdChange(checked: boolean) {
      return (this.rememberPwdChecked = checked);
    },
    sendSms() {
      return this.sendSmsFunc(this.phone);
    },
    sendVoice() {
      return this.sendVoiceFunc && 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);
      } else if (this.loginWay === eLoginWay.PWD) {
        return !(this.pwdValid && this.phoneValid && this.checkStatusValid);
      }
      return true;
    },
  },
  watch: {
    phone(newV: string) {
      if (this.ignorePhoneCheck) return;
      if (newV.length === phoneConfig.maxLen) {
        // 调用方法，获取该手机号的账户信息
        this.accountStatusCheckFunc(newV).then((result) => {
          this.accountType = result;
          this.loginWay = eLoginWay.CODE;
        });
      } else {
        this.loginWay = eLoginWay.NULL;
      }
    },
  },
});
</script>
<style scoped>
.header-text {
  font-size: 16px;
  font-family: PingFangSC-Semibold, PingFang SC;
  font-weight: 600;
}
.title-text {
  font-size: 30px;
  font-family: PingFangSC-Medium, PingFang SC;
  font-weight: 500;
}
</style>
