import { NextRequest, NextResponse } from 'next/server';
import { getServerSession } from 'next-auth';
import { authOptions } from "@/lib/auth";
import { prisma } from '@/lib/prisma';
import { notifyUser } from '@/lib/sse';

async function resolveUserId(email: string): Promise<string | null> {
    const user = await prisma.user.findUnique({
        where: { email },
        select: { id: true }
    });
    return user?.id ?? null;
}

export async function GET(request: NextRequest) {
    try {
        const session = await getServerSession(authOptions);

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

        const userId = await resolveUserId(session.user.email);
        if (!userId) {
            return NextResponse.json({ error: 'User not found' }, { status: 404 });
        }

        const lists = await prisma.somedayList.findMany({
            where: { userId },
            orderBy: { order: 'asc' },
            include: {
                tasks: {
                    where: { deletedAt: null },
                    orderBy: { order: 'asc' }
                }
            }
        });

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

export async function POST(request: NextRequest) {
    try {
        const session = await getServerSession(authOptions);

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

        const userId = await resolveUserId(session.user.email);
        if (!userId) {
            return NextResponse.json({ error: 'User not found' }, { status: 404 });
        }

        const { title } = await request.json();

        if (!title) {
            return NextResponse.json(
                { error: 'Title is required' },
                { status: 400 }
            );
        }

        // Get max order
        const maxOrderList = await prisma.somedayList.findFirst({
            where: { userId },
            orderBy: { order: 'desc' }
        });
        const order = (maxOrderList?.order ?? -1) + 1;

        const list = await prisma.somedayList.create({
            data: {
                userId,
                title,
                order
            },
            include: { tasks: true } // Return with empty tasks array for frontend consistency
        });

        notifyUser(userId, "list-changed", { action: "created" });
        return NextResponse.json({ list });
    } catch (error) {
        console.error('Error creating someday list:', error);
        return NextResponse.json(
            { error: 'Failed to create someday list' },
            { status: 500 }
        );
    }
}

export async function DELETE(request: NextRequest) {
    try {
        const session = await getServerSession(authOptions);

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

        const userId = await resolveUserId(session.user.email);
        if (!userId) {
            return NextResponse.json({ error: 'User not found' }, { status: 404 });
        }

        const { searchParams } = new URL(request.url);
        const id = searchParams.get('id');
        // tasksOnly=true: soft-disconnect (keep list record with tab, just remove tasks + external link)
        const tasksOnly = searchParams.get('tasksOnly') === 'true';
        // deleteExternal=true: also remove the list from the connected provider (Outlook/Google)
        const deleteExternal = searchParams.get('deleteExternal') === 'true';

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

        // Verify ownership
        const list = await prisma.somedayList.findUnique({
            where: { id }
        });

        if (!list || list.userId !== userId) {
            return NextResponse.json(
                { error: 'List not found or unauthorized' },
                { status: 404 }
            );
        }

        // If asked to remove the list from the external provider too, do so first
        // (so a Graph/API failure doesn't orphan the local state).
        let externalDeleteFailed = false;
        if (deleteExternal && list.externalId && list.externalProvider) {
            try {
                if (list.externalProvider === 'outlook') {
                    const { getOutlookAccessToken } = await import('@/lib/outlook-token');
                    const { deleteMsTodoList } = await import('@/lib/microsoft-todo');
                    const token = await getOutlookAccessToken(userId);
                    if (token) await deleteMsTodoList(token, list.externalId);
                } else if (list.externalProvider === 'google') {
                    const { createGoogleClient, deleteGoogleTaskList } = await import('@/lib/google-tasks');
                    const account = await prisma.account.findFirst({
                        where: { userId, provider: { in: ['google-calendar', 'google'] } }
                    });
                    if (account?.access_token) {
                        const client = createGoogleClient(account.access_token, account.refresh_token || undefined);
                        await deleteGoogleTaskList(client, list.externalId);
                    }
                }
                // Note: Synology task list deletion not yet implemented at the provider level.
            } catch (extErr) {
                console.error('Failed to delete external list, proceeding with local cleanup:', extErr);
                externalDeleteFailed = true;
            }
        }

        // Soft-delete tasks in this list (they can be recovered from trash)
        await prisma.task.updateMany({
            where: { somedayListId: id },
            data: { deletedAt: new Date(), somedayListId: null }
        });

        if (tasksOnly) {
            // Soft-disconnect: keep list record (preserves tab assignment) but clear external link
            await prisma.somedayList.update({
                where: { id },
                data: { externalId: null, externalProvider: null, lastSyncedAt: null }
            });
            notifyUser(userId, "list-changed", { action: "disconnected" });
            return NextResponse.json({ success: true, kept: true });
        }

        await prisma.somedayList.delete({
            where: { id }
        });

        notifyUser(userId, "list-changed", { action: "deleted" });
        return NextResponse.json({ success: true, externalDeleteFailed });
    } catch (error) {
        console.error('Error deleting someday list:', error);
        return NextResponse.json(
            { error: 'Failed to delete someday list' },
            { status: 500 }
        );
    }
}

export async function PATCH(request: NextRequest) {
    try {
        const session = await getServerSession(authOptions);

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

        const userId = await resolveUserId(session.user.email);
        if (!userId) {
            return NextResponse.json({ error: 'User not found' }, { status: 404 });
        }

        const body = await request.json();

        // Handle Reordering (Array of { id, order })
        if (Array.isArray(body)) {
            const updates = body.map(async (item: { id: string; order: number }) => {
                return prisma.somedayList.updateMany({
                    where: {
                        id: item.id,
                        userId
                    },
                    data: { order: item.order }
                });
            });

            await Promise.all(updates);
            notifyUser(userId, "list-changed", { action: "reordered" });
            return NextResponse.json({ success: true });
        }

        // Handle Single Update (Title, Tab, Color, Icon)
        const { id, title, tab, color, icon } = body;

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

        // Verify ownership
        const existingList = await prisma.somedayList.findUnique({
            where: { id }
        });

        if (!existingList || existingList.userId !== userId) {
            return NextResponse.json(
                { error: 'List not found or unauthorized' },
                { status: 404 }
            );
        }

        const data: Record<string, any> = {};
        if (title !== undefined) data.title = title;
        if (tab !== undefined) data.tab = tab;
        if (color !== undefined) data.color = color || null;
        if (icon !== undefined) data.icon = icon || null;

        const list = await prisma.somedayList.update({
            where: { id },
            data
        });

        notifyUser(userId, "list-changed", { action: "updated" });
        return NextResponse.json({ list });
    } catch (error) {
        console.error('Error updating someday list:', error);
        return NextResponse.json(
            { error: 'Failed to update someday list' },
            { status: 500 }
        );
    }
}
