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

const prisma = new PrismaClient();

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

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

        const userId = (session.user as any).id;

        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) {
            return NextResponse.json(
                { error: 'Unauthorized' },
                { status: 401 }
            );
        }

        const userId = (session.user as any).id;
        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) {
            return NextResponse.json(
                { error: 'Unauthorized' },
                { status: 401 }
            );
        }

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

        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 !== (session.user as any).id) {
            return NextResponse.json(
                { error: 'List not found or unauthorized' },
                { status: 404 }
            );
        }

        // Delete list (tasks cascade delete is not set in schema for tasks->list, check schema)
        // In schema: tasks defined as `tasks Task[]`. 
        // We updated schema: `user User ... onDelete: Cascade`. `tasks` are separate.
        // We need to verify if deleting list deletes tasks or unlinks them.
        // Schema: `somedayList SomedayList? @relation...`
        // If we want cascade delete tasks in the list, we should check relations.
        // Prisma default is usually not cascade for optional relations unless specified.
        // Let's assume we want to keep tasks or delete them? Usually delete list = delete tasks in it.
        // Let's explicitly delete tasks first or rely on schema if configured.
        // Schema update I did: `tasks Task[]`. `Task` has `somedayListId`.
        // I didn't add `onDelete: Cascade` to the `somedayList` relation in `Task`.
        // So I should clean up tasks manually or update schema.
        // For now, let's delete tasks in the list.

        // 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 }
        });

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

        notifyUser((session.user as any).id, "list-changed", { action: "deleted" });
        return NextResponse.json({ success: true });
    } 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) {
            return NextResponse.json(
                { error: 'Unauthorized' },
                { status: 401 }
            );
        }

        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 }) => {
                // Verify ownership for each or just assume if one matches? 
                // Better to be safe, but for performance in batch, we might trust ID if valid.
                // Let's verify ownership implicitly by where clause.
                return prisma.somedayList.updateMany({
                    where: {
                        id: item.id,
                        userId: (session.user as any).id
                    },
                    data: { order: item.order }
                });
            });

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

        // Handle Single Update (Title and/or Tab)
        const { id, title, tab } = 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 !== (session.user as any).id) {
            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;

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

        notifyUser((session.user as any).id, "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 }
        );
    }
}
