<script lang="ts" setup>
// import

import { helpers, required } from "@vuelidate/validators";
import { useVuelidate } from "@vuelidate/core";
import useOtp from "~/composables/api/auth/useOtp";
import useSignIn from "~/composables/api/auth/useSignIn";
import { definePageMeta } from "#imports";
import useGetAccount from "~/composables/api/account/useGetAccount";
import { useAuth } from "~/composables/api/auth/useAuth";
import { useToast } from "~/composables/global/useToast";
import { useTimer } from "~/composables/global/useTimer";

// types

type LoginInfo = {
    phone: string;
};

// meta

definePageMeta({
    layout: "none",
    middleware: ["check-is-not-logged-in"],
});

// seo

useSeoMeta({
    title: "ورود به فروشگاه",
});

// state

const route = useRoute();

const { addToast } = useToast();

const { updateToken, updateRefreshToken } = useAuth();

const { refetch: refetchAccount } = useGetAccount();

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

const formRules = computed(() => {
    return {
        phone: {
            required: helpers.withMessage("Phone is required", required),
            phoneValidator: helpers.withMessage("شماره تلفن وارد شده معتبر نمی باشد", 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: "کد برای شما ارسال شد",
                options: {
                    status: "success",
                },
            });

            showOtp.value = true;
        } catch (e) {
            addToast({
                message: "مشکلی پیش آمده",
                options: {
                    status: "error",
                },
            });
        }
    }
};

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

        if (!formValidator$.value.$errors.length) {
            await sendOtpHandler();
        }
    } else {
        try {
            const response = await signIn({
                otp: otpCode.value.join(""),
                phone: `0${loginInfo.value.phone}`,
            });

            updateToken(response.access);
            updateRefreshToken(response.refresh);
            await refetchAccount();

            addToast({
                message: "با موفقیت وارد شدید",
                options: {
                    status: "success",
                },
            });

            if (route.query.hasOwnProperty("cb_url")) {
                window.location.href = route.query["cb_url"] as string;
            } else {
                window.location.href = "/";
            }
        } 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="w-full flex h-svh items-center relative container">
        <div class="pattern -z-10 size-full fixed inset-0" />
        <div class="flex items-center justify-center flex-col size-full translate-y-[-100px]">
            <img
                class="aspect-square w-[250px] sm:w-[325px] translate-y-[90px] sm:translate-y-[120px] animate-fade-in"
                src="/img/heymlz/heymlz-signin.gif"
                :style="{
                    filter: 'drop-shadow(0px 4px 20px rgba(0, 0, 0, 0.15))',
                }"
            />

            <div
                class="max-w-[600px] w-full p-6 h-[350px] sm:h-[430px] flex flex-col items-center bg-white border shadow-black/10 justify-center border-slate-300 rounded-3xl"
            >
                <h1 class="typo-h-6 sm:typo-h-5 mt-12">
                    {{ showOtp ? "کد ارسالی را وارد کنید" : "شماره خود را وارد کنید" }}
                </h1>

                <form
                    @submit.prevent
                    class="max-w-[500px] w-full mt-10"
                >
                    <Input
                        v-if="!showOtp"
                        class="w-full tracking-[3px] persian-number"
                        v-model="loginInfo.phone"
                        placeholder="۹۳۸۰۱۲۳۴۵۶"
                        dir="ltr"
                        :error="formValidator$.phone.$error"
                    >
                        <template #startItem>
                            <div class="flex items-center gap-3">
                                <Icon
                                    class="translate-y-[-1px] static-icon"
                                    name="twemoji:flag-iran"
                                    size="24"
                                />
                                <span class="text-slate-500 typo-label-sm"> +۹۸ </span>
                            </div>
                        </template>
                    </Input>

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

                    <div
                        class="flex justify-center gap-2 px-4 text-slate-500/80 rounded-lg mt-4"
                    >
                        <span class="text-xs lg:text-sm"> لطفا حروف را با کیبورد انگلیسی وارد کنید </span>
                        <Icon
                            name="ci:bi-info-circle"
                            class="lg:text-xl"
                        />
                    </div>

                    <Button
                        data-testid="send-otp-code-button"
                        v-if="!showOtp"
                        class="rounded-full w-full mt-6 sm:mt-10 max-sm:h-[45px]"
                        type="submit"
                        @click="handleLogin"
                        :loading="sendOtpIsPending"
                        :disabled="sendOtpIsPending"
                    >
                        ارسال کد
                    </Button>

                    <div
                        v-else
                        class="flex items-center w-full gap-4 mt-2 sm:mt-4"
                    >
                        <Button
                            class="rounded-full w-full mt-4 max-sm:h-[45px]"
                            type="button"
                            variant="secondary"
                            @click="resetForm"
                            :disabled="signInIsPending || sendOtpIsPending"
                        >
                            تغییر شماره
                        </Button>
                        <Button
                            class="rounded-full w-full mt-4 max-sm:h-[45px]"
                            type="submit"
                            @click="resendOtp"
                            :loading="signInIsPending || sendOtpIsPending"
                            :disabled="signInIsPending || isResendOtpBlocked || sendOtpIsPending"
                        >
                            ارسال مجدد کد
                            {{ isResendOtpBlocked ? otpBlockerTimePassed : "" }}
                        </Button>
                    </div>
                    <NuxtLink
                        to="/"
                        class="flex items-center gap-2 justify-center mt-6"
                    >
                        <Icon
                            name="ci:left-rotation"
                            class="lg:text-xl"
                        />
                        <span class="text-xs lg:text-sm"> بازگشت به فروشگاه </span>
                    </NuxtLink>
                </form>
            </div>
        </div>
    </div>
</template>
