import { NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
import { requireCampusInstitution } from "@/lib/auth";

/** Enrollments — one student's course list (?studentId=) or one offering's
    student list (?offeringId=). */
export async function GET(req: Request) {
  const session = await requireCampusInstitution();
  if (!session || !session.institutionId) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  const sp = new URL(req.url).searchParams;
  const studentId = Number(sp.get("studentId"));
  const offeringId = Number(sp.get("offeringId"));
  if (!(Number.isFinite(studentId) && studentId > 0) && !(Number.isFinite(offeringId) && offeringId > 0)) {
    return NextResponse.json({ error: "Missing filter" }, { status: 400 });
  }

  const enrollments = await prisma.cuEnrollment.findMany({
    where: {
      institutionId: session.institutionId,
      ...(Number.isFinite(studentId) && studentId > 0 ? { studentId } : {}),
      ...(Number.isFinite(offeringId) && offeringId > 0 ? { offeringId } : {}),
    },
    orderBy: [{ id: "desc" }],
    include: {
      student: { select: { id: true, studentIdNo: true, name: true, nameBn: true, sessionYear: true, status: true, program: { select: { name: true, nameBn: true } } } },
      offering: {
        select: {
          id: true, sessionYear: true, section: true,
          course: { select: { id: true, code: true, name: true, nameBn: true, credits: true, courseType: true, term: { select: { name: true, nameBn: true } } } },
          staff: { select: { name: true, nameBn: true } },
        },
      },
    },
  });
  return NextResponse.json({ enrollments });
}

/** Enroll: { studentId, offeringId } or bulk { studentId, offeringIds: [] } —
    existing pairs are skipped. */
export async function POST(req: Request) {
  const session = await requireCampusInstitution();
  if (!session || !session.institutionId) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  try {
    const body = await req.json();
    const studentId = Number(body.studentId);
    if (!Number.isFinite(studentId) || studentId <= 0) {
      return NextResponse.json({ error: "Missing fields" }, { status: 400 });
    }
    const student = await prisma.cuStudent.findFirst({
      where: { id: studentId, institutionId: session.institutionId },
      select: { id: true },
    });
    if (!student) return NextResponse.json({ error: "Invalid student" }, { status: 400 });

    const ids: number[] = Array.isArray(body.offeringIds)
      ? body.offeringIds.map(Number).filter((n: number) => Number.isFinite(n) && n > 0)
      : Number.isFinite(Number(body.offeringId)) && Number(body.offeringId) > 0
        ? [Number(body.offeringId)]
        : [];
    if (ids.length === 0) return NextResponse.json({ error: "Missing offerings" }, { status: 400 });

    // only own offerings; verify before insert
    const offerings = await prisma.cuOffering.findMany({
      where: { id: { in: ids }, institutionId: session.institutionId },
      select: { id: true },
    });
    const valid = new Set(offerings.map((o) => o.id));

    const existing = await prisma.cuEnrollment.findMany({
      where: { studentId, offeringId: { in: [...valid] } },
      select: { offeringId: true },
    });
    const have = new Set(existing.map((e) => e.offeringId));

    const created = await prisma.$transaction(
      [...valid].filter((oid) => !have.has(oid)).map((oid) =>
        prisma.cuEnrollment.create({
          data: { institutionId: session.institutionId!, studentId, offeringId: oid },
        })
      )
    );
    return NextResponse.json({ created: created.length, skipped: have.size });
  } catch {
    return NextResponse.json({ error: "Could not enroll" }, { status: 500 });
  }
}
