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

/** Courses — filterable by ?programId= and ?termId=. */
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 programId = Number(sp.get("programId"));
  const termId = Number(sp.get("termId"));
  const courses = await prisma.cuCourse.findMany({
    where: {
      institutionId: session.institutionId,
      ...(Number.isFinite(programId) && programId > 0 ? { programId } : {}),
      ...(Number.isFinite(termId) && termId > 0 ? { termId } : {}),
    },
    orderBy: [{ code: "asc" }],
    include: {
      program: { select: { id: true, name: true, nameBn: true, gradeScale: true } },
      term: { select: { id: true, name: true, nameBn: true } },
      _count: { select: { offerings: true, schedules: true } },
    },
  });
  return NextResponse.json({ courses });
}

/** Create a course: { programId, termId?, code, name, nameBn?, credits?,
    courseType?, fullMarks?, passMarks?, 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 code = String(body.code ?? "").trim();
    const name = String(body.name ?? "").trim();
    if (!Number.isFinite(programId) || programId <= 0 || !code || !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 dup = await prisma.cuCourse.findFirst({
      where: { institutionId: session.institutionId, code },
      select: { id: true },
    });
    if (dup) return NextResponse.json({ error: "CODE_EXISTS" }, { status: 409 });

    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 num = (v: unknown, fallback: number, min = 0) => {
      const n = Number(v);
      return Number.isFinite(n) && n >= min ? n : fallback;
    };
    const fullMarks = num(body.fullMarks, 100, 1);
    const passMarks = num(body.passMarks, 40, 0);
    if (passMarks > fullMarks) {
      return NextResponse.json({ error: "PASS_EXCEEDS_MARKS" }, { status: 400 });
    }

    const course = await prisma.cuCourse.create({
      data: {
        institutionId: session.institutionId,
        programId,
        termId: termOk,
        code,
        name,
        nameBn: String(body.nameBn ?? "").trim() || null,
        credits: num(body.credits, 3, 0),
        courseType: String(body.courseType ?? "THEORY"),
        fullMarks,
        passMarks,
        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({ course });
  } catch {
    return NextResponse.json({ error: "Could not create course" }, { status: 500 });
  }
}
