import { NextRequest, NextResponse } from 'next/server';
export const dynamic = 'force-dynamic';
import { getServerSession } from 'next-auth';
import { authOptions } from "@/lib/auth";
import { prisma } from '@/lib/prisma';
import { readCachedEvents, isCacheStale, refreshConnectionCache, RefreshableConnection } from '@/lib/calendar-cache';
import { runSyncRules } from '@/lib/calendar-cross-sync';

export async function POST(request: NextRequest) {
    try {
        const session = await getServerSession(authOptions);
        if (!session?.user?.email) {
            return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
        }

        const body = await request.json();
        const { timeMin, timeMax, connectionId, forceRefresh } = body;

        const timeMinDate = new Date(timeMin ?? Date.now());
        const timeMaxDate = new Date(timeMax ?? Date.now() + 7 * 24 * 60 * 60 * 1000);

        // Look up by email — session ID can be stale after DB restore/migration
        const user = await prisma.user.findUnique({
            where: { email: session.user.email },
            include: { calendarConnections: true },
        });

        if (!user) {
            return NextResponse.json({ error: 'User not found' }, { status: 404 });
        }

        let connections = user.calendarConnections;
        if (connectionId) {
            connections = connections.filter(c => c.id === connectionId);
        }

        if (connections.length === 0) {
            return NextResponse.json({ success: true, events: [], fromCache: true });
        }

        // FAST PATH: read from DB cache
        const cachedEvents = await readCachedEvents(user.id, timeMinDate, timeMaxDate);

        // Check which connections are stale
        const staleChecks = await Promise.all(
            connections.map(async conn => ({
                conn,
                stale: forceRefresh || await isCacheStale(conn.id, timeMinDate),
            }))
        );
        const staleConnections = staleChecks.filter(c => c.stale).map(c => c.conn);

        // Refresh stale connections
        if (staleConnections.length > 0) {
            const doRefresh = () => Promise.allSettled(
                staleConnections.map(conn => {
                    const rc: RefreshableConnection = {
                        dbId: conn.id,
                        userId: user.id,
                        id: conn.id,
                        provider: conn.provider as 'google' | 'apple' | 'outlook' | 'synology',
                        accessToken: conn.accessToken,
                        refreshToken: conn.refreshToken ?? undefined,
                        expiresAt: conn.expiresAt ?? undefined,
                        calendars: conn.calendars as any,
                    };
                    return refreshConnectionCache(rc, timeMinDate, timeMaxDate);
                })
            );

            if (forceRefresh) {
                // BLOCKING: wait for fresh data when user explicitly requests refresh
                await doRefresh();
                // Run cross-sync rules after cache refresh (fire-and-forget, don't block response)
                runSyncRules(user.id).catch(e => console.error('[cross-sync] Error running sync rules:', e));
                const freshEvents = await readCachedEvents(user.id, timeMinDate, timeMaxDate);
                return NextResponse.json({
                    success: true,
                    events: freshEvents,
                    count: freshEvents.length,
                    fromCache: false,
                    staleConnectionCount: 0,
                });
            } else {
                // BACKGROUND: try to refresh within a short window; fall back to stale cache
                const refreshWork = doRefresh().catch(e => console.error('[CACHE] Background refresh error:', e));
                const timeout = new Promise<void>(resolve => setTimeout(resolve, 800));
                await Promise.race([refreshWork, timeout]);
                const maybeRefreshed = await readCachedEvents(user.id, timeMinDate, timeMaxDate);
                return NextResponse.json({
                    success: true,
                    events: maybeRefreshed,
                    count: maybeRefreshed.length,
                    fromCache: true,
                    staleConnectionCount: staleConnections.length,
                });
            }
        }

        return NextResponse.json({
            success: true,
            events: cachedEvents,
            count: cachedEvents.length,
            fromCache: true,
            staleConnectionCount: 0,
        });
    } catch (error) {
        console.error('[CALENDAR SYNC] Sync request failed:', error);
        return NextResponse.json({
            error: 'Sync failed',
            details: error instanceof Error ? error.message : 'Unknown error'
        }, { status: 500 });
    }
}
