export const dynamic = 'force-dynamic' import { NextResponse } from 'next/server' import { google } from 'googleapis' import * as fs from 'fs' import * as path from 'path' function getAuth() { // Service account JSON (inline or from file) const saJson = process.env.GOOGLE_SA_JSON if (saJson) { const sa = JSON.parse(saJson) return new google.auth.GoogleAuth({ credentials: sa, scopes: ['https://www.googleapis.com/auth/calendar.readonly'], }) } // Fallback: file const saPath = path.join(process.cwd(), 'google-sa.json') if (fs.existsSync(saPath)) { return new google.auth.GoogleAuth({ keyFile: saPath, scopes: ['https://www.googleapis.com/auth/calendar.readonly'], }) } return null } export async function GET(req: Request) { const { searchParams } = new URL(req.url) const range = searchParams.get('range') || 'today' const auth = getAuth() if (!auth) { return NextResponse.json({ events: [], error: 'not_configured' }) } const daniilCalendarId = process.env.DANIIL_CALENDAR_ID || 'daniilklimov25@gmail.com' const svetaCalendarId = process.env.SVETA_CALENDAR_ID || '' const now = new Date() let timeMin: string let timeMax: string if (range === 'today') { timeMin = new Date(now.getFullYear(), now.getMonth(), now.getDate()).toISOString() timeMax = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1).toISOString() } else if (range === 'week') { timeMin = new Date(now.getFullYear(), now.getMonth(), now.getDate()).toISOString() timeMax = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 7).toISOString() } else { timeMin = new Date(now.getFullYear(), now.getMonth(), 1).toISOString() timeMax = new Date(now.getFullYear(), now.getMonth() + 1, 0, 23, 59).toISOString() } const calendarClient = google.calendar({ version: 'v3', auth: auth as any }) const calendars = [ { id: daniilCalendarId, owner: 'daniil', color: '#6366f1', name: 'Даниил' }, ...(svetaCalendarId ? [{ id: svetaCalendarId, owner: 'sveta', color: '#ec4899', name: 'Света' }] : []) ] const results = await Promise.allSettled( calendars.map(cal => calendarClient.events.list({ calendarId: cal.id, timeMin, timeMax, singleEvents: true, orderBy: 'startTime', maxResults: 100, }).then(r => ({ ...cal, events: r.data.items || [] })) ) ) const allEvents = results .filter(r => r.status === 'fulfilled') .flatMap(r => { const val = (r as PromiseFulfilledResult).value return val.events.map((e: any) => ({ id: e.id, title: e.summary || '(без названия)', start: e.start?.dateTime || e.start?.date, end: e.end?.dateTime || e.end?.date, allDay: !e.start?.dateTime, description: e.description || null, location: e.location || null, owner: val.owner, ownerName: val.name, color: val.color, })) }) .sort((a, b) => new Date(a.start).getTime() - new Date(b.start).getTime()) const errors = results .filter(r => r.status === 'rejected') .map(r => (r as PromiseRejectedResult).reason?.message || 'unknown') return NextResponse.json({ events: allEvents, errors: errors.length ? errors : undefined, fetchedAt: new Date().toISOString() }) }