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

type Params = { params: Promise<{ id: string }> };

/** Papers (routine) of one exam — course, date, time, room, marks. */
export async function GET(_req: Request, { params }: Params) {
  const session = await requireCampusInstitution();
  if (!session || !session.institutionId) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  const { id } = await params;
  const exam = await prisma.cuExam.findFirst({
    where: { id: Number(id), institutionId: session.institutionId },
    select: { id: true },
  });
  if (!exam) return NextResponse.json({ error: "Not found" }, { status: 404 });

  const schedules = await prisma.cuExamSchedule.findMany({
    where: { examId: exam.id },
    orderBy: [{ examDate: "asc" }, { startTime: "asc" }, { id: "asc" }],
    include: {
      course: {
        select: { id: true, code: true, name: true, nameBn: true, credits: true, courseType: true, fullMarks: true, passMarks: true, term: { select: { name: true, nameBn: true } } },
      },
      _count: { select: { marks: true } },
    },
  });
  return NextResponse.json({ schedules });
}

/** Add a paper: { courseId, examDate?, startTime?, endTime?, room?,
    fullMarks?, passMarks?, note? } — duplicate course and room/time clashes
    are rejected. */
export async function POST(req: Request, { params }: Params) {
  const session = await requireCampusInstitution();
  if (!session || !session.institutionId) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  const { id } = await params;
  const exam = await prisma.cuExam.findFirst({
    where: { id: Number(id), institutionId: session.institutionId },
    select: { id: true, schedulePublished: true, programId: true },
  });
  if (!exam) return NextResponse.json({ error: "Not found" }, { status: 404 });
  if (exam.schedulePublished) {
    return NextResponse.json({ error: "SCHEDULE_PUBLISHED" }, { status: 409 });
  }

  try {
    const body = await req.json();
    const courseId = Number(body.courseId);
    if (!Number.isFinite(courseId) || courseId <= 0) {
      return NextResponse.json({ error: "Missing fields" }, { status: 400 });
    }
    const course = await prisma.cuCourse.findFirst({
      where: { id: courseId, institutionId: session.institutionId, programId: exam.programId },
      select: { id: true, fullMarks: true, passMarks: true },
    });
    if (!course) return NextResponse.json({ error: "COURSE_NOT_IN_PROGRAM" }, { status: 400 });

    const dup = await prisma.cuExamSchedule.findFirst({
      where: { examId: exam.id, courseId },
      select: { id: true },
    });
    if (dup) return NextResponse.json({ error: "COURSE_EXISTS" }, { status: 409 });

    const dateStr = String(body.examDate ?? "").slice(0, 10);
    const examDate = /^\d{4}-\d{2}-\d{2}$/.test(dateStr) ? new Date(`${dateStr}T00:00:00Z`) : null;
    const startTime = /^\d{2}:\d{2}$/.test(String(body.startTime ?? "")) ? String(body.startTime) : null;
    const endTime = /^\d{2}:\d{2}$/.test(String(body.endTime ?? "")) ? String(body.endTime) : null;
    if (startTime && endTime && endTime <= startTime) {
      return NextResponse.json({ error: "END_BEFORE_START" }, { status: 400 });
    }
    const room = String(body.room ?? "").trim() || null;

    // room clash: same room + same date + overlapping time in this institution
    if (examDate && room && startTime && endTime) {
      const sameDay = await prisma.cuExamSchedule.findMany({
        where: { institutionId: session.institutionId, room, examDate },
        select: { startTime: true, endTime: true },
      });
      const clash = sameDay.some((r) => r.startTime && r.endTime && startTime < r.endTime && r.startTime < endTime);
      if (clash) return NextResponse.json({ error: "ROOM_CLASH" }, { status: 409 });
    }

    const full = body.fullMarks === undefined || body.fullMarks === "" ? course.fullMarks : Number(body.fullMarks);
    const pass = body.passMarks === undefined || body.passMarks === "" ? course.passMarks : Number(body.passMarks);
    if (!Number.isFinite(full) || full <= 0 || !Number.isFinite(pass) || pass < 0 || pass > full) {
      return NextResponse.json({ error: "PASS_EXCEEDS_MARKS" }, { status: 400 });
    }

    const schedule = await prisma.cuExamSchedule.create({
      data: {
        institutionId: session.institutionId,
        examId: exam.id,
        courseId,
        examDate,
        startTime,
        endTime,
        room,
        fullMarks: full,
        passMarks: pass,
        note: String(body.note ?? "").trim() || null,
      },
      include: {
        course: { select: { id: true, code: true, name: true, nameBn: true, credits: true, courseType: true, term: { select: { name: true, nameBn: true } } } },
      },
    });
    return NextResponse.json({ schedule });
  } catch {
    return NextResponse.json({ error: "Could not add paper" }, { status: 500 });
  }
}
