import { useMutation, useQueryClient } from "react-query";
import { fetchGoogleCalendarEvents } from "@/calendar-integration/google-calendar-utils";
import { useAuthContext } from "@/contexts/AuthContext";
import { useCreateEventsFromProvider } from "@/hooks/firebase/useCreateEvent";
import { useClearTokens } from "@/hooks/firebase/useClearTokens";
import { useUpdateUserData } from "@/hooks/firebase/useUpdateUserData";

export const useFetchAndSaveGoogleEvents = () => {
    const queryClient = useQueryClient();
    const { profileData } = useAuthContext();
    const { mutateAsync: createEventsFromProvider } = useCreateEventsFromProvider();
    const { mutateAsync: clearToken } = useClearTokens();
    const { mutateAsync: updateUserData } = useUpdateUserData();

    return useMutation({
        mutationKey: ["fetchAndSaveGoogleEvents", "sync"],
        mutationFn: async ({ token, email, date, refreshToken }: { token?: string; refreshToken?: string; email?: string; date?: Date }) => {
            const baseDate = date || new Date();
            const timeMin = new Date(baseDate.setMonth(baseDate.getMonth() - 1)).toISOString().slice(0, -5) + "Z";
            const timeMax = new Date(baseDate.setMonth(baseDate.getMonth() + 2)).toISOString().slice(0, -5) + "Z";

            console.log("Token: ", token);

            const tryFetchEvents = async (isRetry = false) => {
                try {
                    const response = await fetchGoogleCalendarEvents(
                        token,
                        email,
                        profileData?.familyId,
                        timeMin,
                        timeMax
                    );

                    if (!response.success) {
                        await clearToken({ email: email!, provider: "google" });
                        return; // Stop refetching if clearing the token
                    }

                    console.log("Google Calendar events fetched:", response);

                    const items = response?.googleEvents?.map((item) => {
                        if (item.allDay) {
                            item.startDate = new Date(item.startDate.setHours(0, 0, 0, 0));
                            item.endDate = item.startDate;
                        }
                        return item;
                    }) || [];

                    await createEventsFromProvider(items);
                } catch (error) {
                    console.error("Error fetching Google Calendar events:", error);

                    if (!isRetry) {
                        const refreshedToken = await handleRefreshToken(email, refreshToken);
                        if (refreshedToken) {
                            await updateUserData({
                                newUserData: {
                                    googleAccounts: {
                                        ...profileData.googleAccounts,
                                        [email!]: { ...profileData.googleAccounts[email!], accessToken: refreshedToken },
                                    },
                                },
                            });
                            return tryFetchEvents(true); // Retry once after refreshing
                        } else {
                            await clearToken({ email: email!, provider: "google" });
                            console.error(`Token refresh failed; token cleared for ${email}`);
                            throw error;
                        }
                    } else {
                        console.error(`Retry failed after refreshing token for user ${profileData?.email}:`, error.message);
                        throw error;
                    }
                }
            };

            return tryFetchEvents();
        },
        onSuccess: () => {
            queryClient.invalidateQueries(["events"]);
        },
    });
};

async function handleRefreshToken(email: string, refreshToken: string) {
    if (!refreshToken) return null;

    try {
        const response = await fetch('https://oauth2.googleapis.com/token', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({
                grant_type: 'refresh_token',
                refresh_token: refreshToken,
                client_id: "406146460310-2u67ab2nbhu23trp8auho1fq4om29fc0.apps.googleusercontent.com",
            }),
        });

        const data = await response.json();
        return data.access_token;
    } catch (error) {
        console.error("Error refreshing Google token:", error);
        return null;
    }
}