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; } }