import { NextRequest, NextResponse } from 'next/server';
import { getServerSession } from 'next-auth';
import { authOptions } from "@/lib/auth";
import { prisma } from '@/lib/prisma';
import { refreshConnectionCache, RefreshableConnection } from '@/lib/calendar-cache';
import { getUserCalendars as getSynologyCalendars } from '@/lib/synology-calendar';

// Get user's calendar connections
export async function GET(request: NextRequest) {
    try {
        const session = await getServerSession(authOptions);

        if (!session?.user?.email) {
            return NextResponse.json(
                { error: 'Unauthorized' },
                { status: 401 }
            );
        }

        // Find user by email
        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 }
            );
        }

        // Return calendar connections (without sensitive tokens)
        // Prune deleted calendars from providers that support live listing
        const connections = await Promise.all(user.calendarConnections.map(async (conn) => {
            let calendars = conn.calendars as any[] | null;

            // For Apple connections, filter out VTODO/Reminders collections
            if (conn.provider === 'apple' && Array.isArray(calendars)) {
                calendars = calendars.filter((cal: any) =>
                    !cal.id?.includes('/reminders/')
                );
            }

            // For Synology connections, prune calendars deleted on the server
            if (conn.provider === 'synology' && Array.isArray(calendars) && calendars.length > 0) {
                try {
                    const [username, password] = conn.accessToken.split(':');
                    const serverUrl = conn.refreshToken;
                    if (username && password && serverUrl) {
                        const freshCalendars = await getSynologyCalendars(serverUrl, username, password);
                        const freshIds = new Set(freshCalendars.map(c => c.id));
                        const storedIds = calendars.map((c: any) => c.id);
                        const staleIds = storedIds.filter((id: string) => !freshIds.has(id));
                        if (staleIds.length > 0) {
                            console.log('[CONNECTIONS] Synology stale calendars to prune:', staleIds);
                        }
                        const pruned = calendars.filter((c: any) => freshIds.has(c.id));
                        if (pruned.length < calendars.length) {
                            calendars = pruned;
                            await prisma.calendarConnection.update({
                                where: { id: conn.id },
                                data: { calendars: pruned },
                            });
                        }
                    }
                } catch (err) {
                    console.error('[CONNECTIONS] Synology calendar pruning failed:', err);
                }
            }

            return {
                id: conn.id,
                provider: conn.provider,
                calendars,
                createdAt: conn.createdAt,
                expiresAt: conn.expiresAt,
            };
        }));

        return NextResponse.json({ connections });
    } catch (error) {
        console.error('Error fetching calendar connections:', error);
        return NextResponse.json(
            { error: 'Failed to fetch calendar connections' },
            { status: 500 }
        );
    }
}

// Update a calendar connection (e.g. selection)
export async function PATCH(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 { id, calendars } = body;

        if (!id || !calendars) {
            return NextResponse.json({ error: 'ID and calendars required' }, { status: 400 });
        }

        // Find user
        const user = await prisma.user.findUnique({
            where: { email: session.user.email }
        });

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

        // Update connection
        const updated = await prisma.calendarConnection.update({
            where: {
                id,
                userId: user.id
            },
            data: {
                calendars: calendars // Update the JSON field
            }
        });

        // Fire-and-forget cache refresh for this connection (covers ±1 week)
        const now = new Date();
        const tMin = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);
        const tMax = new Date(now.getTime() + 14 * 24 * 60 * 60 * 1000);
        const rc: RefreshableConnection = {
            dbId: updated.id,
            userId: user.id,
            id: updated.id,
            provider: updated.provider as 'google' | 'apple' | 'outlook',
            accessToken: updated.accessToken,
            refreshToken: updated.refreshToken ?? undefined,
            expiresAt: updated.expiresAt ?? undefined,
            calendars: calendars,
        };
        refreshConnectionCache(rc, tMin, tMax)
            .catch(e => console.error('[CACHE] Post-selection refresh failed:', e));

        return NextResponse.json({ success: true, connection: updated });
    } catch (error) {
        console.error('Error updating calendar connection:', error);
        return NextResponse.json(
            { error: 'Failed to update calendar connection' },
            { status: 500 }
        );
    }
}

// Delete a calendar connection
export async function DELETE(request: NextRequest) {
    try {
        const session = await getServerSession(authOptions);

        if (!session?.user?.email) {
            return NextResponse.json(
                { error: 'Unauthorized' },
                { status: 401 }
            );
        }

        const { searchParams } = new URL(request.url);
        const connectionId = searchParams.get('id');

        if (!connectionId) {
            return NextResponse.json(
                { error: 'Connection ID required' },
                { status: 400 }
            );
        }

        // Find user and verify ownership
        const user = await prisma.user.findUnique({
            where: { email: session.user.email }
        });

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

        // Get connection before deleting to clean up provider-specific state
        const connection = await prisma.calendarConnection.findFirst({
            where: { id: connectionId, userId: user.id }
        });

        // Delete the connection
        await prisma.calendarConnection.delete({
            where: {
                id: connectionId,
                userId: user.id
            }
        });

        return NextResponse.json({ success: true });
    } catch (error) {
        console.error('Error deleting calendar connection:', error);
        return NextResponse.json(
            { error: 'Failed to delete calendar connection' },
            { status: 500 }
        );
    }
}
