<template>
  <div id="auth-card-body">
    <h2 id="auth-card-title">{{ cardTitle }} </h2>
    <el-form id="auth-card-form" ref="cardFormRef"  :model="cardForm" :rules="cardFormRule" @keyup.enter="onSubmit">

      <el-form-item v-if="cardType==='login'" class="auth-card-form-item" prop="phone">
        <el-input v-model="cardForm.phone" autofocus clearable placeholder="请输入手机号">
          <template #prefix>
            <el-icon class="el-input__icon">
              <phone/>
            </el-icon>
          </template>
        </el-input>
      </el-form-item>

      <el-form-item v-if="cardType==='register'" class="auth-card-form-item" prop="name">
        <el-input v-model="cardForm.name" autofocus clearable placeholder="请输入昵称，长度为1-20个字符">
          <template #prefix>
            <el-icon class="el-input__icon">
              <cherry/>
            </el-icon>
          </template>
        </el-input>
      </el-form-item>

      <el-form-item v-if="cardType==='register'" class="auth-card-form-item" prop="username">
        <el-input v-model="cardForm.username" clearable placeholder="请输入用户名，只允许英文和数字，长度为1-20个字符">
          <template #prefix>
            <el-icon class="el-input__icon">
              <avatar/>
            </el-icon>
          </template>
        </el-input>
      </el-form-item>

      <el-form-item v-if="cardType==='register'" class="auth-card-form-item" prop="email">
        <el-input v-model="cardForm.email" clearable placeholder="请输入邮箱">
          <template #prefix>
            <el-icon class="el-input__icon">
              <message/>
            </el-icon>
          </template>
        </el-input>
      </el-form-item>

      <el-form-item class="auth-card-form-item" prop="password">
        <el-input v-model="cardForm.password" :placeholder="passwordPlaceHolder" clearable type="password" autocomplete="new-password">
          <template #prefix>
            <el-icon class="el-input__icon">
              <lock/>
            </el-icon>
          </template>
        </el-input>
      </el-form-item>

      <el-form-item v-if="cardType==='reset'||cardType==='register'" class="auth-card-form-item" prop="passwordConfirm">
        <el-input v-model="cardForm.passwordConfirm" clearable placeholder="请再次输入密码" type="password">
          <template #prefix>
            <el-icon class="el-input__icon">
              <lock/>
            </el-icon>
          </template>
        </el-input>
      </el-form-item>

      <el-form-item v-if="cardType==='reset'||cardType==='register'" class="auth-card-form-item" prop="phone">
        <el-input v-model="cardForm.phone" autofocus clearable placeholder="请输入手机号">
          <template #prefix>
            <el-icon class="el-input__icon">
              <phone/>
            </el-icon>
          </template>
        </el-input>
      </el-form-item>

      <div v-if="cardType==='reset'||cardType==='register'" id="auth-card-code-verifier">
        <el-form-item prop="identifyCode">
          <el-input v-model="cardForm.identifyCode" placeholder="请输入验证码">
            <template #prefix>
              <el-icon class="el-input__icon">
                <key/>
              </el-icon>
            </template>
          </el-input>
        </el-form-item>
        <el-button id="auth-card-code-verifier-button" :disabled="cardButtonDisabled" @click="handleSendMessage">{{ cardButtonText }}</el-button>
      </div>

      <div v-if="cardType==='login'" id="auth-card-login-password-options">
        <el-checkbox v-model="rememberMe">记住我</el-checkbox>
        <span id="auth-card-login-password-option-reset" @click="toResetType">重置密码</span>
      </div>

      <el-form-item v-if="cardType==='login'" class="auth-card-form-item">
        <SlideVerifier id="auth-card-slide-verifier" ref="verifier" is-lock @change="handleSlideVerifier"/>
      </el-form-item>

      <el-form-item class="auth-card-form-item">
        <el-button id="auth-card-submit-button" type="primary" @click="onSubmit">{{ cardTitle }}</el-button>
      </el-form-item>

      <div id="auth-card-form-link">
        <div @click="toOtherType">{{ cardLink }}</div>
      </div>

    </el-form>
  </div>
</template>

<script>
import { Avatar, Cherry, Key, Lock, Message, Phone } from "@element-plus/icons-vue";
import SlideVerifier from "@/views/AuthPage/components/SlideVerifier";

export default {
  name: "AuthCard",
  components: { Message, Cherry, Avatar, SlideVerifier, Lock, Phone, Key },
  data() {
    const inputNumberValidator = (rule, value, callback) => {
      if (!(/(^[1-9]\d*$)/.test(value))) {
        callback(new Error("请勿输入非数字"));
      } else {
        callback();
      }
    };
    const passwordConfirmValidator = (rule, value, callback) => {
      if (value !== this.cardForm.password) {
        callback(new Error("请输入相同的密码"));
      } else {
        callback();
      }
    };
    const phoneValidator = (rule, value, callback) => {
      if (/^(13\d|14\d|15\d|166|18\d|19[6,9]|17\d)\d{8}$/i.test(value) === false) {
        callback(new Error("请输入正确格式的手机号"));
      } else {
        callback();
      }
    };
    const emailValidator = (rule, value, callback) => {
      if (/^([a-zA-Z\d]+[_|.]?)*[a-zA-Z\d]+@([a-zA-Z\d]+[_|.]?)*[a-zA-Z\d]+\.[a-zA-Z]{2,3}$/.test(value) === false) {
        callback(new Error("请输入正确格式的邮箱"));
      } else {
        callback();
      }
    };
    const identifyCodeValidator = (rule, value, callback) => {
      if (value.length !== 6) {
        this.shakeElem("auth-card-code-verifier");
        callback(new Error("请正确输入短信验证码"));
      } else {
        this.cardVerified = true;
        callback();
      }
    };
    return {
      cardType: "login",
      cardButtonDisabled: false,
      cardButtonText: "获取验证码",
      cardVerified: false,
      rememberMe: false,
      cardForm: {
        phone: "",
        name: "",
        username: "",
        email: "",
        password: "",
        passwordConfirm: "",
        identifyCode: "",
      },
      cardFormRule: {
        phone: [
          { required: true, message: "请输入手机号", trigger: "blur" },
          {
            validator: phoneValidator,
            trigger: "blur"
          },
          {
            validator: inputNumberValidator,
            trigger: "change"
          }
        ],
        name: [
          {
            required: true,
            min: 1,
            max: 20,
            message: "请输入正确格式的昵称",
            trigger: "blur",
          }
        ],
        username: [
          {
            required: true,
            min: 1,
            max: 20,
            message: "请输入正确格式的用户名",
            trigger: "blur",
          }
        ],
        email: [
          { required: true, message: "请输入邮箱", trigger: "blur" },
          {
            validator: emailValidator,
            trigger: "blur"
          }
        ],
        password: [
          {
            required: true,
            message: "请输入密码",
            trigger: "blur",
          },
          {
            min: 8,
            max: 20,
            message: "密码长度应为8-20个字符",
            trigger: "blur",
          }
        ],
        passwordConfirm: [
          { required: true, message: "请再次输入密码", trigger: "blur" },
          {
            validator: passwordConfirmValidator,
            trigger: "blur"
          }
        ],
        identifyCode: [
          {
            validator: identifyCodeValidator,
            trigger: "blur",
          },
          {
            validator: inputNumberValidator,
            trigger: "change",
          }
        ]
      },
      slideVerifierVisible: true,
    };
  },

  computed: {
    cardTitle() {
      if (this.cardType === "login") {
        return "登录";
      } else if (this.cardType === "register") {
        return "注册";
      } else {
        return "重置密码";
      }
    },
    cardLink() {
      if (this.cardType === "login") {
        return "立即注册";
      } else if (this.cardType === "register") {
        return "已有账号? 前往登录";
      } else {
        return "记得密码? 前往登录";
      }
    },
    passwordPlaceHolder() {
      if (this.cardType === "login") {
        return "请输入密码";
      } else {
        return "请输入密码，需要包含英文和数字，长度为8-20个字符";
      }
    }
  },

  created() {
    if (localStorage.rememberMe) {
      this.cardForm.phone = localStorage.phone;
      this.cardForm.password = localStorage.password;
      this.rememberMe = true;
    }
    this.cardVerified = false;
  },

  methods: {
    onSubmit() {
      if (this.cardType === "login") {
        this.handleLogin();
      } else if (this.cardType === "register") {
        this.handleRegister();
      } else if (this.cardType === "reset") {
        this.handleReset();
      }
    },

    toResetType() {
      this.$refs.cardFormRef.resetFields();
      this.cardVerified = false;
      this.cardType = "reset";
    },
    toOtherType() {
      this.$refs.cardFormRef.resetFields();
      this.cardVerified = false;
      if (this.cardType === "login") {
        this.cardType = "register";
      } else if (this.cardType === "register") {
        this.cardType = "login";
        if (localStorage.rememberMe) {
          this.cardForm.phone = localStorage.phone;
          this.cardForm.password = localStorage.password;
          this.rememberMe = true;
        }
        this.cardVerified = false;
      } else if (this.cardType === "reset") {
        this.cardType = "login";
        if (localStorage.rememberMe) {
          this.cardForm.phone = localStorage.phone;
          this.cardForm.password = localStorage.password;
          this.rememberMe = true;
        }
        this.cardVerified = false;
      }
    },

    handleLogin() {
      const thatForm = this.$refs.cardFormRef;
      thatForm.validateField("phone", v1 => {
        thatForm.validateField("password", v2 => {
          if (!v1 && !v2) {
            if (this.cardVerified) {
              const params = {
                phone: this.cardForm.phone,
                password: this.cardForm.password
              };
              this.$apis.loginAPI(params)
                .then((res) => {
                  if (res.data.code === 0) {
                    if (this.rememberMe) {
                      localStorage.phone = this.cardForm.phone;
                      localStorage.password = this.cardForm.password;
                      localStorage.rememberMe = this.rememberMe;
                    } else {
                      localStorage.removeItem("rememberMe");
                      localStorage.removeItem("phone");
                      localStorage.removeItem("password");
                    }
                    this.$store.commit("state_set_user", res.data.data);
                    this.$message({
                      showClose: true,
                      message: "登录成功",
                      type: "success",
                      duration: 1000,
                    });
                    setTimeout(() => {
                      if (this.$route.params.login_to) {
                        this.$router.push(String(this.$route.params.login_to));
                      } else {
                        this.$router.push("/portal");
                      }
                    }, 500);
                  } else {
                    this.$message({
                      showClose: true,
                      message: res.data.message,
                      type: "error"
                    });
                    Object.assign(this.$data, this.$options.data());
                    this.$refs.verifier.init();
                  }
                })
                .catch((e) => {
                  this.$message({
                    showClose: true,
                    message: e,
                    type: "error"
                  });
                });
            } else {
              this.shakeElem("auth-card-slide-verifier");
            }
          }
        });
      });
    },
    handleRegister() {
      //虽然很傻，但是似乎没有直接简化的写法
      const thatForm = this.$refs.cardFormRef;
      thatForm.validateField("name", v1 => {
        thatForm.validateField("username", v2 => {
          thatForm.validateField("email", v3 => {
            thatForm.validateField("password", v4 => {
              thatForm.validateField("passwordConfirm", v5 => {
                thatForm.validateField("phone", v6 => {
                  thatForm.validateField("identifyCode", v7 => {
                    if (!v1 && !v2 && !v3 && !v4 && !v5 && !v6 && !v7) {
                      if (this.cardVerified) {
                        const params = {
                          name: this.cardForm.name,
                          username: this.cardForm.username,
                          email: this.cardForm.email,
                          password: this.cardForm.password,
                          identifyCode: this.cardForm.identifyCode,
                          phone: this.cardForm.phone,
                        };
                        this.$apis.registerAPI(params)
                          .then((res) => {
                            if (res.data.code === 0) {
                              this.$message({
                                showClose: true,
                                message: "注册成功",
                                type: "success"
                              });
                              setTimeout(() => {
                                this.cardType = "login";
                              }, 1000);
                            } else {
                              this.$message({
                                showClose: true,
                                message: res.data.message,
                                type: "warning"
                              });
                            }
                          })
                          .catch((e) => {
                            this.$message({
                              showClose: true,
                              message: e,
                              type: "error"
                            });
                          });
                      } else {
                        this.shakeElem("auth-card-code-verifier");
                      }
                    }
                  });
                });
              });
            });
          });
        });
      });
    },
    handleReset() {
      const thatForm = this.$refs.cardFormRef;
      thatForm.validateField("password", v1 => {
        thatForm.validateField("passwordConfirm", v2 => {
          thatForm.validateField("phone", v3 => {
            thatForm.validateField("identifyCode", v4 => {
              if (!v1 && !v2 && !v3 && !v4) {
                if (this.cardVerified) {
                  const params = {
                    password: this.cardForm.password,
                    identifyCode: this.cardForm.identifyCode,
                    phone: this.cardForm.phone,
                  };
                  this.$apis.resetAPI(params)
                    .then((res) => {
                      if (res.data.code === 0) {
                        this.$message({
                          showClose: true,
                          message: "重置成功",
                          type: "success"
                        });
                        setTimeout(() => {
                          this.cardType = "login";
                        }, 1000);
                      } else {
                        this.$message({
                          showClose: true,
                          message: res.data.message,
                          type: "warning"
                        });
                      }
                    })
                    .catch((e) => {
                      this.$message({
                        showClose: true,
                        message: e,
                        type: "error"
                      });
                    });
                } else {
                  this.shakeElem("auth-card-code-verifier");
                }
              }
            });
          });
        });
      });
    },
    handleSlideVerifier(verifyStatus) {
      this.cardVerified = verifyStatus;
      if (this.cardVerified && verifyStatus && this.rememberMe && localStorage.getItem("rememberMe")) {
        if (localStorage.phone === this.cardForm.phone && localStorage.password === this.cardForm.password) {
          this.handleLogin();
        }
      }
    },
    shakeElem(elemId) {
      let elem = document.getElementById(elemId);
      elem.classList.add("shake");
      setTimeout(() => {
        elem.classList.remove("shake");
      }, 800);
    },
    handleSendMessage() {
      const thatForm = this.$refs.cardFormRef;
      thatForm.validateField("phone", v1 => {
        if (!v1) {
          this.cardButtonDisabled = true;
          let time = 60;
          const myScroll = setInterval(() => {
            time--;
            if (time >= 0) {
              this.cardButtonText = time + "s后可重发";
            } else {
              this.cardButtonText = "获取验证码";
              this.cardButtonDisabled = false;
              clearTimeout(myScroll);
              time = 60;
            }
          }, 1000);
          const params = {
            phone: this.cardForm.phone
          };
          this.$apis.sendMessageAPI(params)
            .then((res) => {
              if (res.data.code === 0) {
                this.$message({
                  showClose: true,
                  message: "发送成功，请注意查收验证码",
                  type: "success"
                });
              } else {
                this.$message({
                  showClose: true,
                  message: res.data.message,
                  type: "warning"
                });
              }
            })
            .catch((e) => {
              this.$message({
                showClose: true,
                message: e,
                type: "error"
              });
            });
        }
      });
    },

  }
};
</script>

<style scoped src="./AuthCard.css"/>
