import { googleCalendarAuth } from './auth'; import { startOfMonth, endOfMonth, format } from 'date-fns'; const CALENDAR_API_BASE = 'https://www.googleapis.com/calendar/v3'; export interface CalendarEvent { id: string; summary: string; description?: string; location?: string; start: { dateTime?: string; date?: string; timeZone?: string; }; end: { dateTime?: string; date?: string; timeZone?: string; }; status: string; colorId?: string; } export interface Calendar { id: string; summary: string; description?: string; primary?: boolean; backgroundColor?: string; foregroundColor?: string; } export interface CalendarListResponse { items: Calendar[]; } export interface EventsListResponse { items: CalendarEvent[]; nextPageToken?: string; } async function fetchWithAuth(url: string): Promise { const token = await googleCalendarAuth.getAccessToken(); if (!token) { throw new Error('Not authenticated with Google Calendar'); } const response = await fetch(url, { headers: { Authorization: `Bearer ${token}`, }, }); if (response.status === 401) { // Token might be invalid, clear and throw googleCalendarAuth.clearTokens(); throw new Error('Authentication expired, please re-authenticate'); } if (!response.ok) { throw new Error(`Calendar API error: ${response.status}`); } return response; } export async function getCalendarList(): Promise { const response = await fetchWithAuth(`${CALENDAR_API_BASE}/users/me/calendarList`); const data: CalendarListResponse = await response.json(); return data.items; } export async function getEventsForMonth( calendarId: string = 'primary', date: Date = new Date() ): Promise { const timeMin = startOfMonth(date).toISOString(); const timeMax = endOfMonth(date).toISOString(); const params = new URLSearchParams({ timeMin, timeMax, singleEvents: 'true', orderBy: 'startTime', maxResults: '100', }); const url = `${CALENDAR_API_BASE}/calendars/${encodeURIComponent(calendarId)}/events?${params}`; const response = await fetchWithAuth(url); const data: EventsListResponse = await response.json(); return data.items; } export async function getEventsForDay( calendarId: string = 'primary', date: Date = new Date() ): Promise { const dayStart = new Date(date); dayStart.setHours(0, 0, 0, 0); const dayEnd = new Date(date); dayEnd.setHours(23, 59, 59, 999); const params = new URLSearchParams({ timeMin: dayStart.toISOString(), timeMax: dayEnd.toISOString(), singleEvents: 'true', orderBy: 'startTime', }); const url = `${CALENDAR_API_BASE}/calendars/${encodeURIComponent(calendarId)}/events?${params}`; const response = await fetchWithAuth(url); const data: EventsListResponse = await response.json(); return data.items; } export function getEventTime(event: CalendarEvent): { start: Date; end: Date; allDay: boolean } { const allDay = !!event.start.date; let start: Date; let end: Date; if (allDay) { start = new Date(event.start.date!); end = new Date(event.end.date!); } else { start = new Date(event.start.dateTime!); end = new Date(event.end.dateTime!); } return { start, end, allDay }; } export function formatEventTime(event: CalendarEvent): string { const { start, allDay } = getEventTime(event); if (allDay) { return 'All day'; } return format(start, 'h:mm a'); }