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

/** Campus exams — mid-term / semester final / preliminary etc. */
export async function GET(req: Request) {
  const session = await requireCampusInstitution();
  if (!session || !session.institutionId) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  const programId = Number(new URL(req.url).searchParams.get("programId"));
  const exams = await prisma.cuExam.findMany({
    where: {
      institutionId: session.institutionId,
      ...(Number.isFinite(programId) && programId > 0 ? { programId } : {}),
    },
    orderBy: [{ startDate: "desc" }, { id: "desc" }],
    include: {
      program: { select: { id: true, name: true, nameBn: true, gradeScale: true } },
      term: { select: { id: true, name: true, nameBn: true } },
      _count: { select: { schedules: true } },
    },
  });
  return NextResponse.json({
    exams: exams.map((e) => ({ ...e, paperCount: e._count.schedules })),
  });
}

/** Create an exam: { programId, termId?, name, nameBn?, examType?, sessionYear?,
    startDate?, endDate?, note? }. */
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 programId = Number(body.programId);
    const name = String(body.name ?? "").trim();
    if (!Number.isFinite(programId) || programId <= 0 || !name) {
      return NextResponse.json({ error: "Missing fields" }, { status: 400 });
    }
    const program = await prisma.cuProgram.findFirst({
      where: { id: programId, institutionId: session.institutionId },
      select: { id: true },
    });
    if (!program) return NextResponse.json({ error: "Invalid program" }, { status: 400 });

    const termId = Number(body.termId);
    let termOk: number | null = null;
    if (Number.isFinite(termId) && termId > 0) {
      const term = await prisma.cuTerm.findFirst({
        where: { id: termId, programId },
        select: { id: true },
      });
      if (!term) return NextResponse.json({ error: "Invalid term" }, { status: 400 });
      termOk = term.id;
    }

    const date = (v: unknown) => {
      const s = String(v ?? "").slice(0, 10);
      return /^\d{4}-\d{2}-\d{2}$/.test(s) ? new Date(`${s}T00:00:00Z`) : null;
    };
    const startStr = String(body.startDate ?? "").slice(0, 10);
    const endStr = String(body.endDate ?? "").slice(0, 10);
    if (endStr && startStr && endStr < startStr) {
      return NextResponse.json({ error: "END_BEFORE_START" }, { status: 400 });
    }

    const exam = await prisma.cuExam.create({
      data: {
        institutionId: session.institutionId,
        programId,
        termId: termOk,
        name,
        nameBn: String(body.nameBn ?? "").trim() || null,
        examType: String(body.examType ?? "SEMESTER_FINAL"),
        sessionYear: String(body.sessionYear ?? "").trim() || null,
        startDate: date(body.startDate),
        endDate: date(body.endDate),
        note: String(body.note ?? "").trim() || null,
      },
      include: {
        program: { select: { id: true, name: true, nameBn: true, gradeScale: true } },
        term: { select: { id: true, name: true, nameBn: true } },
      },
    });
    return NextResponse.json({ exam });
  } catch {
    return NextResponse.json({ error: "Could not create exam" }, { status: 500 });
  }
}
