<script setup lang="ts">
import { reactive, ref } from "vue";
import type {
  ICommonResponse,
  IUserRegisterData,
  IUserRegisterRequest
} from "#shared/types";
import { useUserStore } from "~/stores";

type FormRef = {
  validate: () => Promise<boolean>;
  resetFields: () => void;
};

type RegisterForm = Required<
  Pick<IUserRegisterRequest, "username" | "password" | "email">
> &
  Pick<IUserRegisterRequest, "verification_code" | "aff_code"> & {
    confirmPassword: string;
  };

const emit = defineEmits<{
  success: [response: ICommonResponse<IUserRegisterData>];
}>();

const route = useRoute();
const router = useRouter();
const userStore = useUserStore();
const { isOnline, getUserInfoLoading } = storeToRefs(userStore);
const formRef = ref<FormRef>();

const form = reactive<RegisterForm>({
  username: "",
  password: "",
  confirmPassword: "",
  email: "",
  verification_code: "",
  aff_code: ""
});

const validateConfirmPassword = (
  _rule: unknown,
  value: string,
  callback: (error?: Error) => void
) => {
  if (!value) {
    callback(new Error("请再次输入密码"));
    return;
  }

  if (value !== form.password) {
    callback(new Error("两次输入的密码不一致"));
    return;
  }

  callback();
};

const rules = {
  username: [{ required: true, message: "请输入用户名", trigger: "blur" }],
  email: [
    { required: true, message: "请输入邮箱", trigger: "blur" },
    { type: "email", message: "邮箱格式不正确", trigger: ["blur", "change"] }
  ],
  password: [
    { required: true, message: "请输入密码", trigger: "blur" },
    { min: 6, message: "密码至少 6 位", trigger: "blur" }
  ],
  confirmPassword: [{ validator: validateConfirmPassword, trigger: "blur" }]
};

const submit = async () => {
  const valid = await formRef.value?.validate().catch(() => false);
  if (!valid) return;

  const payload: IUserRegisterRequest = {
    username: form.username.trim(),
    password: form.password,
    email: form.email.trim()
  };

  if (form.verification_code?.trim()) {
    payload.verification_code = form.verification_code.trim();
  }

  if (form.aff_code?.trim()) {
    payload.aff_code = form.aff_code.trim();
  }

  const response = await userStore.register(payload);

  if (response?.code === 0) {
    emit("success", response);
  }
};

const resetForm = () => {
  formRef.value?.resetFields();
};

const goToLogin = () => {
  const { _loginAction, ...query } = route.query;
  router.replace({ query });
};

defineExpose({
  resetForm
});
</script>

<template>
  <div class="w-full max-w-sm">
    <el-form
      ref="formRef"
      :model="form"
      :rules="rules"
      label-position="top"
      @submit.prevent="submit"
    >
      <el-form-item label="用户名" prop="username">
        <el-input
          v-model="form.username"
          autocomplete="username"
          placeholder="请输入用户名"
          size="large"
        />
      </el-form-item>

      <el-form-item label="邮箱" prop="email">
        <el-input
          v-model="form.email"
          autocomplete="email"
          placeholder="请输入邮箱"
          size="large"
        />
      </el-form-item>

      <el-form-item label="密码" prop="password">
        <el-input
          v-model="form.password"
          autocomplete="new-password"
          placeholder="请输入密码"
          show-password
          size="large"
          type="password"
        />
      </el-form-item>

      <el-form-item label="确认密码" prop="confirmPassword">
        <el-input
          v-model="form.confirmPassword"
          autocomplete="new-password"
          placeholder="请再次输入密码"
          show-password
          size="large"
          type="password"
          @keyup.enter="submit"
        />
      </el-form-item>

      <el-form-item label="邮箱验证码" prop="verification_code">
        <el-input
          v-model="form.verification_code"
          placeholder="如需验证请填写"
          size="large"
        />
      </el-form-item>

      <el-form-item label="邀请码" prop="aff_code">
        <el-input v-model="form.aff_code" placeholder="选填" size="large" />
      </el-form-item>

      <el-button
        class="w-full"
        native-type="submit"
        size="large"
        type="primary"
        :loading="userStore.registerLoading"
        :disabled="getUserInfoLoading || isOnline"
      >
        注册
      </el-button>
    </el-form>

    <div class="mt-4 text-center text-sm">
      已有账户？
      <span class="cursor-pointer text-blue-600" @click="goToLogin">登录</span>
    </div>
  </div>
</template>
