import { NextResponse } from "next/server";
import { Prisma } from "@prisma/client";
import { prisma } from "@/lib/prisma";
import { requireRole } from "@/lib/auth";
import { parseScope } from "@/lib/identity";

/* Maintainer assignments for the Student Identity page — admin only. */

export async function GET() {
  const session = await requireRole("INSTITUTION_ADMIN");
  if (!session || !session.institutionId) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  const managers = await prisma.identityManager.findMany({
    where: { institutionId: session.institutionId },
    orderBy: { createdAt: "desc" },
    include: { staff: { select: { id: true, name: true, employeeCode: true, designation: true } } },
  });

  return NextResponse.json({
    managers: managers.map((m) => ({
      staffId: m.staffId,
      staffName: m.staff.name,
      employeeCode: m.staff.employeeCode,
      designation: m.staff.designation,
      scope: parseScope(m.scopeClassItemIds),
      createdAt: m.createdAt,
    })),
  });
}

/** Assign (or re-scope) a staff member. classIds: [] or omitted = all classes. */
export async function POST(req: Request) {
  const session = await requireRole("INSTITUTION_ADMIN");
  if (!session || !session.institutionId) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  try {
    const body = await req.json();
    const staffId = Number(body.staffId);
    if (!staffId) return NextResponse.json({ error: "STAFF_REQUIRED" }, { status: 400 });

    const staff = await prisma.staff.findFirst({
      where: { id: staffId, institutionId: session.institutionId },
      select: { id: true },
    });
    if (!staff) return NextResponse.json({ error: "STAFF_NOT_FOUND" }, { status: 404 });

    // scope must reference CLASS items this institution actually selected
    let scopeIds: number[] | null = null;
    if (Array.isArray(body.classIds)) {
      const wanted = [...new Set((body.classIds as unknown[]).map((v) => Number(v)).filter(Boolean))];
      if (wanted.length) {
        const selected = await prisma.academicSelection.findMany({
          where: {
            institutionId: session.institutionId,
            academicItemId: { in: wanted },
            academicItem: { category: "CLASS" },
          },
          select: { academicItemId: true },
        });
        const allowed = new Set(selected.map((s) => s.academicItemId));
        const valid = wanted.filter((id) => allowed.has(id));
        if (!valid.length) return NextResponse.json({ error: "INVALID_SCOPE" }, { status: 400 });
        scopeIds = valid;
      }
    }

    const manager = await prisma.identityManager.upsert({
      where: { institutionId_staffId: { institutionId: session.institutionId, staffId } },
      create: {
        institutionId: session.institutionId,
        staffId,
        scopeClassItemIds: scopeIds ?? Prisma.JsonNull,
        grantedById: session.userId,
      },
      update: { scopeClassItemIds: scopeIds ?? Prisma.JsonNull, grantedById: session.userId },
    });
    const staffRec = await prisma.staff.findUniqueOrThrow({
      where: { id: staffId },
      select: { name: true, employeeCode: true, designation: true },
    });

    return NextResponse.json({
      manager: {
        staffId: manager.staffId,
        staffName: staffRec.name,
        employeeCode: staffRec.employeeCode,
        designation: staffRec.designation,
        scope: parseScope(manager.scopeClassItemIds),
        createdAt: manager.createdAt,
      },
    });
  } catch {
    return NextResponse.json({ error: "Could not save assignment" }, { status: 500 });
  }
}
