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

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

/** Update a course (same fields as create, all optional). */
export async function PATCH(req: Request, { params }: Params) {
  const session = await requireCampusInstitution();
  if (!session || !session.institutionId) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

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

  try {
    const body = await req.json();
    const data: Record<string, unknown> = {};
    if (body.code !== undefined) {
      const code = String(body.code).trim();
      if (!code) return NextResponse.json({ error: "Missing fields" }, { status: 400 });
      if (code !== course.code) {
        const dup = await prisma.cuCourse.findFirst({
          where: { institutionId: session.institutionId, code, id: { not: course.id } },
          select: { id: true },
        });
        if (dup) return NextResponse.json({ error: "CODE_EXISTS" }, { status: 409 });
      }
      data.code = code;
    }
    if (body.programId !== undefined) {
      const programId = Number(body.programId);
      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 });
      data.programId = program.id;
    }
    if (body.termId !== undefined) {
      const termId = Number(body.termId);
      if (Number.isFinite(termId) && termId > 0) {
        const term = await prisma.cuTerm.findFirst({
          where: { id: termId, programId: (data.programId as number) ?? course.programId },
          select: { id: true },
        });
        if (!term) return NextResponse.json({ error: "Invalid term" }, { status: 400 });
        data.termId = term.id;
      } else {
        data.termId = null;
      }
    }
    if (body.name !== undefined) data.name = String(body.name).trim();
    if (body.nameBn !== undefined) data.nameBn = String(body.nameBn).trim() || null;
    if (body.courseType !== undefined) data.courseType = String(body.courseType);
    if (body.note !== undefined) data.note = String(body.note).trim() || null;
    if (body.isActive !== undefined) data.isActive = !!body.isActive;
    for (const key of ["credits", "fullMarks", "passMarks"] as const) {
      if (body[key] !== undefined) {
        const n = Number(body[key]);
        if (Number.isFinite(n) && n >= 0) data[key] = n;
      }
    }
    if (data.fullMarks !== undefined && data.passMarks !== undefined && (data.passMarks as number) > (data.fullMarks as number)) {
      return NextResponse.json({ error: "PASS_EXCEEDS_MARKS" }, { status: 400 });
    }

    const updated = await prisma.cuCourse.update({
      where: { id: course.id },
      data,
      include: {
        program: { select: { id: true, name: true, nameBn: true, gradeScale: true } },
        term: { select: { id: true, name: true, nameBn: true } },
      },
    });
    return NextResponse.json({ course: updated });
  } catch {
    return NextResponse.json({ error: "Could not update course" }, { status: 500 });
  }
}

/** Delete a course — blocked while it has exam schedules or offerings. */
export async function DELETE(_req: Request, { params }: Params) {
  const session = await requireCampusInstitution();
  if (!session || !session.institutionId) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  const { id } = await params;
  const course = await prisma.cuCourse.findFirst({
    where: { id: Number(id), institutionId: session.institutionId },
    select: { id: true, _count: { select: { offerings: true, schedules: true } } },
  });
  if (!course) return NextResponse.json({ error: "Not found" }, { status: 404 });
  if (course._count.offerings > 0 || course._count.schedules > 0) {
    return NextResponse.json({ error: "COURSE_IN_USE" }, { status: 409 });
  }

  try {
    await prisma.cuCourse.delete({ where: { id: course.id } });
    return NextResponse.json({ ok: true });
  } catch {
    return NextResponse.json({ error: "Could not delete course" }, { status: 500 });
  }
}
