<script lang="ts" setup>

// import

import { helpers, required } from "@vuelidate/validators";
import { useVuelidate } from "@vuelidate/core";
import useOtp from "~/composables/api/auth/useOtp";
import { useTimer } from "~/composables/useTimer";
import useSignIn from "~/composables/api/auth/useSignIn";

// types

type LoginInfo = {
    phone: string;
};

// state

const { addToast } = useToast();

const showOtp = ref(false);
const otpCode = ref([]);

const formRules = computed(() => {
    return {
        phone: {
            required: helpers.withMessage("Phone is required", required),
            phoneValidator: helpers.regex(/^[1-9][0-9]{9}$/)
        }
    };
});

const loginInfo = ref<LoginInfo>({
    phone: ""
});

const formValidator$ = useVuelidate(formRules, loginInfo);

const {
    timer: otpBlockerTimePassed,
    start: startOtpBlocker,
    reset: resetOtpBlocker,
    isPending: isResendOtpBlocked
} = useTimer({
    duration: 5000
});

const { mutateAsync: sendOtp, isPending: sendOtpIsPending } = useOtp();
const { mutateAsync: signIn, isPending: signInIsPending, status: signInStatus } = useSignIn();

// computed

const sendOtpHandler = async () => {
    if (!sendOtpIsPending.value) {
        try {
            await sendOtp({
                phone: `0${loginInfo.value.phone}`
            });

            addToast({ message: "کد برای شما ارسال شد" });

            showOtp.value = true;

        } catch (e) {
            addToast({ message: "مشکلی پیش آمده" });
        }
    }
};

const handleLogin = async () => {
    if (!showOtp.value) {
        await formValidator$.value.$validate();

        if (!formValidator$.value.$errors.length) {
            await sendOtpHandler();
        }
    } else {
        try {
            await signIn({
                otp: otpCode.value.join(""),
                phone: `0${loginInfo.value.phone}`
            });
        } catch (e) {
            otpCode.value = [];
            addToast({ message: "مشکلی پیش آمده" });
        }
    }
};

const resendOtp = async () => {
    try {
        await sendOtpHandler();
        resetOtpBlocker();
        startOtpBlocker();
    } catch (e) {
        resetOtpBlocker();
    }
};

const resetForm = () => {
    loginInfo.value.phone = "";
    formValidator$.value.$reset();
    otpCode.value = [];
    showOtp.value = false;
};

</script>

<template>
    <div class="container min-h-[700px] flex flex-col items-center justify-center">
        <h1 class="typo-hero-2">
            فرم ورود
        </h1>
        <form
            @submit.prevent
            class="max-w-[500px] w-full mt-12"
        >
            <div
                v-if="!showOtp"
                class="flex items-center gap-2 w-full"
            >
                <Input
                    class="w-full"
                    v-model="loginInfo.phone"
                    placeholder="9380123456"
                    dir="ltr"
                    :error="formValidator$.phone.$error"
                >
                    <template #startItem>
                        <span class="text-slate-500">
                            +98
                        </span>
                    </template>
                </Input>
                <div class="flex items-center gap-1">
                    <Icon class="translate-y-[-1px]" name="twemoji:flag-iran" size="24" />
                </div>
            </div>

            <OtpInput
                v-else
                v-model="otpCode"
                :status="signInStatus === 'success' ? 'success' : signInStatus === 'error' ? 'error' : 'idle'"
                :disabled="signInIsPending || sendOtpIsPending"
                :autofocus="true"
                @complete="handleLogin"
            />

            <Button
                v-if="!showOtp"
                class="rounded-full w-full mt-4"
                type="submit"
                @click="handleLogin"
                :loading="sendOtpIsPending"
                :disabled="sendOtpIsPending"
            >
                ارسال کد
            </Button>

            <div
                v-else
                class="flex items-center w-full gap-4 mt-4"
            >
                <Button
                    class="rounded-full w-full mt-4"
                    type="button"
                    variant="secondary"
                    @click="resetForm"
                    :disabled="signInIsPending || sendOtpIsPending"
                >
                    تغییر شماره
                </Button>
                <Button
                    class="rounded-full w-full mt-4"
                    type="submit"
                    @click="resendOtp"
                    :loading="signInIsPending || sendOtpIsPending"
                    :disabled="signInIsPending || isResendOtpBlocked || sendOtpIsPending"
                >
                    ارسال مجدد کد
                    {{ isResendOtpBlocked ? otpBlockerTimePassed : "" }}
                </Button>
            </div>

            <div class="flex items-center gap-2 justify-center mt-6">
                <span>
                    بازگشت به فروشگاه
                </span>
                <Icon
                    name="ci:left-rotation"
                    size="24"
                />
            </div>
        </form>
    </div>
</template>