import { NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
import { requireRole } from "@/lib/auth";
import { saveMarkRows, validateMarkRows } from "@/lib/marks";

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

/** All saved marks of one exam (every paper × every student that has a row).
    The client slices this grid by subject (subject-wise entry) or by student
    (student-wise entry). */
export async function GET(_req: Request, { params }: Params) {
  const session = await requireRole("INSTITUTION_ADMIN");
  if (!session || !session.institutionId) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

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

  const rows = await prisma.examMark.findMany({
    where: { examSchedule: { examId: exam.id } },
    orderBy: [{ studentId: "asc" }, { examScheduleId: "asc" }],
    select: {
      id: true,
      examScheduleId: true,
      studentId: true,
      cq: true,
      mcq: true,
      applied: true,
      total: true,
      note: true,
    },
  });

  return NextResponse.json({ rows });
}

/** Bulk save marks: { rows: [{ examScheduleId, studentId, cq?, mcq?, applied?, total?, note? }] }.
    Each row is validated against its paper's marks split (obtained marks can
    never exceed the paper's full/part marks) and upserted per
    (examScheduleId, studentId). Rows with no value at all are skipped. */
export async function POST(req: Request, { params }: Params) {
  const session = await requireRole("INSTITUTION_ADMIN");
  if (!session || !session.institutionId) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

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

  try {
    const body = await req.json();
    const raw: unknown[] = Array.isArray(body.rows) ? body.rows : [];
    const result = await validateMarkRows(raw, exam.id, exam.institutionId);
    if (!result.ok) {
      return NextResponse.json({ error: result.error }, { status: 400 });
    }
    const saved = await saveMarkRows(result.rows, exam.institutionId);
    return NextResponse.json({ saved });
  } catch {
    return NextResponse.json({ error: "Could not save marks" }, { status: 500 });
  }
}
