// imports

import { QueryClient, useMutation } from "@tanstack/vue-query";
import type { InfiniteData } from "@tanstack/vue-query";
import { API_ENDPOINTS, MUTATION_KEYS, QUERY_KEYS } from "~/constants";

// types

export type CreateChatMessageRequest = {
    productId: string | number;
    new_message: string;
};

export type CreateChatMessageResponse = Chat[];

const useCreateChatMessage = (queryClient: QueryClient) => {
    // state

    const { $axios: axios } = useNuxtApp();

    // methods

    const handleCreateChatMessage = async (
        variables: CreateChatMessageRequest
    ) => {
        const { data } = await axios.post<CreateChatMessageResponse>(
            `${API_ENDPOINTS.chat.new_message}/${variables.productId}`,
            variables
        );
        return data;
    };

    return useMutation({
        mutationKey: [MUTATION_KEYS.create_chat],
        mutationFn: (variables: CreateChatMessageRequest) =>
            handleCreateChatMessage(variables),
        onMutate: (newMessage) => {
            const prevData = queryClient.getQueriesData({
                queryKey: [QUERY_KEYS.chat],
            });

            queryClient.setQueryData<InfiniteData<ApiPaginated<Chat>>>(
                [QUERY_KEYS.chat],
                (oldData) => {
                    const lastPage = oldData!.pages[oldData!.pages.length - 1];

                    return {
                        pages: [
                            {
                                count: lastPage.count,
                                next: lastPage.next,
                                previous: lastPage.previous,
                                results: [
                                    {
                                        id: Date.now(),
                                        content: newMessage.new_message,
                                        sender: "user",
                                    },
                                ],
                            },
                            ...oldData!.pages,
                        ],
                        pageParams: [
                            ...oldData!.pageParams,
                            {
                                limit: 10,
                                offset: 0,
                            },
                        ],
                    };
                }
            );

            return { prevData: prevData ? prevData[0][1] : undefined };
        },
        onSuccess: (response) => {
            queryClient.setQueryData<InfiniteData<ApiPaginated<Chat>>>(
                [QUERY_KEYS.chat],
                (oldData : any) => {
                    if (oldData) {
                        const lastPage = oldData!.pages[oldData!.pages.length - 1];

                        return {
                            pages: [
                                {
                                    count: lastPage.count,
                                    next: lastPage.next,
                                    previous: lastPage.previous,
                                    results: {
                                        ...response[0],
                                        id: Date.now(),
                                    },
                                },
                                ...oldData!.pages,
                            ],
                            pageParams: [
                                ...oldData!.pageParams,
                                {
                                    limit: 10,
                                    offset: 0,
                                },
                            ],
                        };
                    }

                    return oldData;
                }
            );
        },
        onError: (err, newMessage, context) => {
            if (context) {
                queryClient.setQueryData([QUERY_KEYS.chat], context.prevData);
            }
        },
        onSettled: (newMessage) => {
            queryClient.invalidateQueries({ queryKey: [QUERY_KEYS.chat] });
        },
    });
};

export default useCreateChatMessage;
