import { NextRequest, NextResponse } from 'next/server';
import { getServerSession } from 'next-auth';
import { authOptions } from "@/lib/auth";
import { prisma } from '@/lib/prisma';
import { getTokens, getUserCalendars } from '@/lib/outlook-calendar';

export const dynamic = 'force-dynamic';

export async function GET(request: NextRequest) {
    const baseUrl = process.env.NEXTAUTH_URL || request.url;

    try {
        const session = await getServerSession(authOptions);

        if (!session?.user?.email) {
            return NextResponse.redirect(new URL('/auth/login', baseUrl));
        }

        const { searchParams } = new URL(request.url);
        const code = searchParams.get('code');
        const error = searchParams.get('error');

        if (error) {
            console.error('Outlook OAuth error:', error);
            return NextResponse.redirect(new URL('/?error=outlook_auth_failed', baseUrl));
        }

        if (!code) {
            return NextResponse.redirect(new URL('/?error=no_code', baseUrl));
        }

        // Exchange code for tokens
        const tokenData = await getTokens(code);
        const accessToken = tokenData.access_token;
        const refreshToken = tokenData.refresh_token;
        const expiresIn = tokenData.expires_in;

        // Fetch user's calendars to store initial list
        const calendars = await getUserCalendars(accessToken);

        const userId = (session.user as any).id;
        const user = userId
            ? await prisma.user.findUnique({ where: { id: userId } })
            : await prisma.user.findUnique({ where: { email: session.user.email } });

        if (!user) {
            return NextResponse.redirect(new URL('/auth/login', baseUrl));
        }

        // Calculate expiry date
        const expiresAt = new Date();
        expiresAt.setSeconds(expiresAt.getSeconds() + expiresIn);

        // Check for existing connection
        const existingConnection = await prisma.calendarConnection.findFirst({
            where: {
                userId: user.id,
                provider: 'outlook'
            }
        });

        const calendarData = calendars.map(cal => ({
            id: cal.id,
            title: cal.name,
            isPrimary: cal.isDefaultCalendar,
            selected: true,
            editable: cal.canEdit
        }));

        if (existingConnection) {
            await prisma.calendarConnection.update({
                where: { id: existingConnection.id },
                data: {
                    accessToken,
                    refreshToken,
                    expiresAt,
                    calendars: calendarData,
                    updatedAt: new Date()
                }
            });
        } else {
            // Create new connection
            await prisma.calendarConnection.create({
                data: {
                    userId: user.id,
                    provider: 'outlook',
                    accessToken,
                    refreshToken,
                    expiresAt,
                    calendars: calendarData,
                }
            });
        }

        // Redirect to a client-side page that re-establishes the session
        // Direct redirects from Microsoft OAuth may lose the session cookie (SameSite policy)
        const redirectUrl = new URL('/auth/oauth-complete', baseUrl);
        redirectUrl.searchParams.set('provider', 'outlook');
        redirectUrl.searchParams.set('status', 'connected');
        return NextResponse.redirect(redirectUrl);
    } catch (error) {
        console.error('Error in Outlook callback:', error);
        const redirectUrl = new URL('/auth/oauth-complete', baseUrl);
        redirectUrl.searchParams.set('provider', 'outlook');
        redirectUrl.searchParams.set('status', 'error');
        redirectUrl.searchParams.set('message', 'outlook_callback_failed');
        return NextResponse.redirect(redirectUrl);
    }
}
