import { NextRequest, NextResponse } from 'next/server';
import { PrismaClient, Prisma } from '@prisma/client';
import bcrypt from 'bcryptjs';
import { requireAdminAuth } from '@/lib/auth';

const prisma = new PrismaClient();

export async function GET(request: NextRequest) {
    // Only admin may list and manage curators
    const authError = await requireAdminAuth(request);
    if (authError) return authError;

    const curators = await prisma.curator.findMany({
        include: {
            genres: true,
            specials: true,
        },
        orderBy: { username: 'asc' },
    });

    return NextResponse.json(
        curators.map(c => ({
            id: c.id,
            username: c.username,
            isGlobalCurator: c.isGlobalCurator,
            genreIds: c.genres.map(g => g.genreId),
            specialIds: c.specials.map(s => s.specialId),
        }))
    );
}

export async function POST(request: NextRequest) {
    const authError = await requireAdminAuth(request);
    if (authError) return authError;

    const { username, password, isGlobalCurator = false, genreIds = [], specialIds = [] } = await request.json();

    if (!username || !password) {
        return NextResponse.json({ error: 'username and password are required' }, { status: 400 });
    }

    const passwordHash = await bcrypt.hash(password, 10);

    try {
        const curator = await prisma.curator.create({
            data: {
                username,
                passwordHash,
                isGlobalCurator: Boolean(isGlobalCurator),
                genres: {
                    create: (genreIds as number[]).map(id => ({ genreId: id })),
                },
                specials: {
                    create: (specialIds as number[]).map(id => ({ specialId: id })),
                },
            },
            include: {
                genres: true,
                specials: true,
            },
        });

        return NextResponse.json({
            id: curator.id,
            username: curator.username,
            isGlobalCurator: curator.isGlobalCurator,
            genreIds: curator.genres.map(g => g.genreId),
            specialIds: curator.specials.map(s => s.specialId),
        });
    } catch (error) {
        console.error('Error creating curator:', error);

        // Handle unique username constraint violation explicitly
        if (error instanceof Prisma.PrismaClientKnownRequestError && error.code === 'P2002') {
            return NextResponse.json(
                { error: 'A curator with this username already exists.' },
                { status: 409 }
            );
        }

        return NextResponse.json({ error: 'Internal Server Error' }, { status: 500 });
    }
}

export async function PUT(request: NextRequest) {
    const authError = await requireAdminAuth(request);
    if (authError) return authError;

    const { id, username, password, isGlobalCurator, genreIds, specialIds } = await request.json();

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

    const data: any = {};
    if (username !== undefined) data.username = username;
    if (isGlobalCurator !== undefined) data.isGlobalCurator = Boolean(isGlobalCurator);
    if (password) {
        data.passwordHash = await bcrypt.hash(password, 10);
    }

    try {
        const updated = await prisma.$transaction(async (tx) => {
            const curator = await tx.curator.update({
                where: { id: Number(id) },
                data,
                include: {
                    genres: true,
                    specials: true,
                },
            });

            if (Array.isArray(genreIds)) {
                await tx.curatorGenre.deleteMany({
                    where: { curatorId: curator.id },
                });
                if (genreIds.length > 0) {
                    await tx.curatorGenre.createMany({
                        data: (genreIds as number[]).map(gid => ({
                            curatorId: curator.id,
                            genreId: gid,
                        })),
                    });
                }
            }

            if (Array.isArray(specialIds)) {
                await tx.curatorSpecial.deleteMany({
                    where: { curatorId: curator.id },
                });
                if (specialIds.length > 0) {
                    await tx.curatorSpecial.createMany({
                        data: (specialIds as number[]).map(sid => ({
                            curatorId: curator.id,
                            specialId: sid,
                        })),
                    });
                }
            }

            const finalCurator = await tx.curator.findUnique({
                where: { id: curator.id },
                include: {
                    genres: true,
                    specials: true,
                },
            });

            if (!finalCurator) {
                throw new Error('Curator not found after update');
            }

            return finalCurator;
        });

        return NextResponse.json({
            id: updated.id,
            username: updated.username,
            isGlobalCurator: updated.isGlobalCurator,
            genreIds: updated.genres.map(g => g.genreId),
            specialIds: updated.specials.map(s => s.specialId),
        });
    } catch (error) {
        console.error('Error updating curator:', error);

        // Handle unique username constraint violation explicitly for updates
        if (error instanceof Prisma.PrismaClientKnownRequestError && error.code === 'P2002') {
            return NextResponse.json(
                { error: 'A curator with this username already exists.' },
                { status: 409 }
            );
        }

        return NextResponse.json({ error: 'Internal Server Error' }, { status: 500 });
    }
}

export async function DELETE(request: NextRequest) {
    const authError = await requireAdminAuth(request);
    if (authError) return authError;

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

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

    try {
        await prisma.curator.delete({
            where: { id: Number(id) },
        });

        return NextResponse.json({ success: true });
    } catch (error) {
        console.error('Error deleting curator:', error);
        return NextResponse.json({ error: 'Internal Server Error' }, { status: 500 });
    }
}


