<script lang='ts' setup>
import type { GenericObject } from "vee-validate";
import type { EmailVerifyClient } from "@/api/types";
import { toastController } from "@ionic/vue";
import { toTypedSchema } from "@vee-validate/yup";
import { Field, Form } from "vee-validate";
import * as yup from "yup";
import { authClient } from "@/auth";

const emit = defineEmits<{
  (e: "submit", value: EmailVerifyClient): void;
}>();

const { t } = useI18n();

const countdown = ref(0);
const isSending = ref(false);
const canResend = computed(() => countdown.value === 0 && !isSending.value);

const email = ref("");
const emailError = ref("");

let timer: number | null = null;

const schema = computed(() => toTypedSchema(yup.object({
  email: yup
    .string()
    .required(t("auth.login.validation.emailRequired"))
    .email(t("auth.login.validation.emailInvalid")),
  otp: yup
    .string()
    .required(t("auth.login.validation.otpRequired"))
    .matches(/^\d{6}$/, t("auth.login.validation.otpInvalid")),
})));

function startCountdown() {
  countdown.value = 60;
  timer = setInterval(() => {
    countdown.value--;
    if (countdown.value <= 0) {
      if (timer) {
        clearInterval(timer);
        timer = null;
      }
    }
  }, 1000);
}

async function sendOtp() {
  const emailValue = email.value.trim();
  if (!emailValue) {
    emailError.value = t("auth.login.validation.emailRequired");
    return;
  }

  // 使用yup进行验证
  try {
    await yup.string().email().validate(emailValue);
  }
  catch {
    emailError.value = t("auth.login.validation.emailInvalid");
    return;
  }

  if (!canResend.value) {
    return;
  }

  try {
    emailError.value = "";
    isSending.value = true;
    await authClient.emailOtp.sendVerificationOtp({
      email: emailValue,
      type: "sign-in",
    });

    const toast = await toastController.create({
      message: t("auth.login.sendCodeSuccess"),
      duration: 2000,
      position: "top",
      color: "success",
    });
    await toast.present();
    startCountdown();
  }
  catch (error: any) {
    const toast = await toastController.create({
      message: error?.message || t("auth.common.failedSendCode"),
      duration: 2000,
      position: "top",
      color: "danger",
    });
    await toast.present();
  }
  finally {
    isSending.value = false;
  }
}

function handleSubmit(values: GenericObject) {
  emit("submit", values as EmailVerifyClient);
}

onUnmounted(() => {
  if (timer) {
    clearInterval(timer);
    timer = null;
  }
});
</script>

<template>
  <Form :validation-schema="schema" class="mt-5" @submit="handleSubmit">
    <Field v-slot="{ field, errorMessage }" name="email" type="email">
      <div class="mb-4">
        <ui-input
          v-bind="field"
          v-model="email"
          :placeholder="t('auth.login.enterEmail')"
          type="email"
        >
          <ion-button
            slot="end"
            fill="clear"
            size="small"
            :disabled="!canResend"
            @click="sendOtp"
          >
            <span v-if="countdown > 0">
              {{ countdown }}s
            </span>
            <span v-else-if="isSending">
              {{ t('auth.login.sending') }}
            </span>
            <span v-else>
              {{ t('auth.login.getCode') }}
            </span>
          </ion-button>
        </ui-input>
        <div v-if="errorMessage || emailError" class="text-xs text-red-500 mt-1">
          {{ errorMessage || emailError }}
        </div>
      </div>
    </Field>

    <Field v-slot="{ field, errorMessage }" name="otp" type="text">
      <div class="mb-4">
        <ui-input
          v-bind="field"
          :placeholder="t('auth.login.enterOtp')"
          :maxlength="6"
          type="text"
        />
        <div v-if="errorMessage" class="text-xs text-red-500 mt-1">
          {{ errorMessage }}
        </div>
      </div>
    </Field>

    <ion-button
      expand="block"
      class="ion-margin-top"
      shape="round"
      type="submit"
    >
      {{ t('auth.login.loginButton') }}
    </ion-button>
  </Form>
</template>

<style lang='css' scoped>
@reference "tailwindcss";
</style>
