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

import useGetChat from "~/composables/api/chat/useGetChat";
import ChatInput from "~/components/product/ChatBox/ChatInput.vue";
import { useIsMutating } from "@tanstack/vue-query";
import { MUTATION_KEYS } from "~/constants";
import CloseButton from "~/components/product/ChatBox/CloseButton.vue";
import { useAuth } from "~/composables/api/auth/useAuth";
import { useScroll } from "@vueuse/core";

// provide-inject

const { isOpen, closeChat } = inject("isOpen") as any;

// state

const { isLoggedIn } = useAuth();

const route = useRoute();
const id = route.params.id as string | number;

const isMobile = useMediaQuery("(max-width: 480px)");

const scrollToBottomTimer = ref<NodeJS.Timeout | null>(null);

const chatContainerEl = ref<HTMLElement | null>(null);

const lastMessageBeforeUpdate = ref(0);

const {
    data: chat,
    isPending: isChatPending,
    isFetchingNextPage: isNextChatPagePending,
    hasNextPage: hasMoreChat,
    fetchNextPage: loadMoreChat,
} = useGetChat(id, isOpen);
const isCreateMessagePending = useIsMutating({
    mutationKey: [MUTATION_KEYS.create_chat],
});

const canLoadMoreChat = ref(false);

const isChatScrollLocked = useScrollLock(chatContainerEl);
const { y: chatContainerScrollY } = useScroll(chatContainerEl, {
    behavior: "smooth",
});

useInfiniteScroll(
    chatContainerEl,
    async () => {
        if (hasMoreChat.value && !isChatPending.value) {
            lastMessageBeforeUpdate.value = chatMessages.value ? chatMessages.value[0].id : 0;
            await loadMoreChat();
        }
    },
    {
        distance: 10,
        direction: "top",
        throttle: 1000,
        canLoadMore: () => canLoadMoreChat.value,
    }
);

// methods

const scrollToBottom = () => {
    if (scrollToBottomTimer.value) clearTimeout(scrollToBottomTimer.value);
    scrollToBottomTimer.value = setTimeout(() => {
        chatContainerScrollY.value = chatContainerEl.value?.scrollHeight ?? 0;
    }, 50);
};

// computed

const chatMessages = computed(() => {
    return chat.value?.pages
        .flatMap((page) => {
            return page.results;
        })
        .reverse();
});

// watch

watch(
    () => isCreateMessagePending.value,
    (newValue) => {
        requestAnimationFrame(() => {
            scrollToBottom();
            isChatScrollLocked.value = !!newValue;
        });
    }
);

watch(
    () => chat.value,
    () => {
        if (canLoadMoreChat.value) {
            const scrollTopOld = chatContainerEl.value!.scrollTop - 100;
            requestAnimationFrame(() => {
                const lastChatMessageEl = document.querySelector(
                    `#message-container-${lastMessageBeforeUpdate.value}`
                ) as HTMLElement;
                lastChatMessageEl?.scrollIntoView();
                chatContainerEl.value!.scrollTop = chatContainerEl.value!.scrollTop + scrollTopOld;
            });
        }
    }
);

whenever(
    () => !!chatContainerEl.value,
    () => {
        requestAnimationFrame(() => {
            scrollToBottom();
        });
        setTimeout(() => {
            canLoadMoreChat.value = true;
        }, 2000);
    },
    {
        once: true,
    }
);
</script>

<template>
    <Transition :name="isMobile ? 'fade-down' : 'fade-right-to-left'">
        <div
            v-if="isOpen"
            class="fixed z-9999 max-xs:inset-0 xs:right-8 xs:bottom-8 w-full xs:w-[450px] transition-all duration-500 overflow-hidden h-svh xs:h-[700px] xs:rounded-250 shadow-2xl shadow-black/30 pt-[40px] bg-white"
        >
            <CloseButton :disabled="!!isCreateMessagePending" />

            <template v-if="isLoggedIn">
                <Transition
                    name="zoom"
                    mode="out-in"
                >
                    <div
                        v-if="!isChatPending"
                        class="p-4.5 h-full flex flex-col justify-between gap-4"
                    >
                        <div
                            :style="{
                                maskImage: 'linear-gradient(to top, transparent, black 5%, black, black)',
                            }"
                            class="hide-scrollbar flex flex-col py-7 gap-6 h-full overflow-y-auto"
                            ref="chatContainerEl"
                        >
                            <div
                                v-if="hasMoreChat"
                                class="py-2 flex items-center justify-center"
                            >
                                <Icon
                                    name="ci:svg-spinners-3-dots-fade"
                                    size="24"
                                />
                            </div>
                            <ChatMessage
                                v-for="(message, index) in chatMessages"
                                :key="message.id"
                                :id="message.id"
                                :reverse="message.sender === 'ai'"
                                :content="message.content"
                                :isLast="chatMessages?.length === index + 1"
                                @textUpdate="scrollToBottom"
                            />
                            <ChatMessage
                                v-if="!!isCreateMessagePending"
                                :id="Date.now() + 1"
                                reverse
                                content=""
                                isLast
                                @textUpdate="scrollToBottom"
                                :loadingContent="!!isCreateMessagePending"
                            />
                        </div>

                        <ChatInput />
                    </div>

                    <div
                        v-else
                        class="w-full h-full flex items-center justify-center absolute inset-0"
                    >
                        <NuxtImg
                            class="size-[225px] sm:size-[250px] drop-shadow-2xl"
                            src="/img/heymlz/heymlz-small-idle.gif"
                            loading="lazy"
                            fetch-priority="low"
                            alt=""
                        />
                    </div>
                </Transition>
            </template>
            <div
                class="text-black p-6 size-full flex justify-center items-center flex-col"
                v-else
            >
                <NuxtImg
                    class="size-[225px] sm:size-[250px] drop-shadow-2xl"
                    src="/img/heymlz/heymlz-small-idle.gif"
                    loading="lazy"
                    fetch-priority="low"
                    alt=""
                />
                <div class="flex flex-col gap-4 items-center">
                    <span class="text-center typo-p-xl font-bold">سلام دوست عزیز!</span>
                    <p class="text-center typo-p-md">
                        من میتونم هر سوالی رو درمورد این محصول جواب بدم اگه میخوای شروع کنیم وارد وبسایت شو
                    </p>
                </div>
                <div class="flex-center gap-4">
                    <Button
                        @click="closeChat"
                        class="mt-8 rounded-full px-10"
                    >
                        بستن
                    </Button>
                    <NuxtLink to="/signin">
                        <Button
                            variant="outlined"
                            class="mt-8 rounded-full px-10"
                        >
                            ورود به فروشگاه
                        </Button>
                    </NuxtLink>
                </div>
            </div>
        </div>
    </Transition>
</template>
