import { NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
import { requireAnyRole } from "@/lib/auth";
import { getMemberStudentId } from "@/lib/member";
import { ensureCode, formatCode } from "@/lib/verify-code";
import { resolveVerificationSetting } from "@/lib/notify";

/** Admit-card data for one published exam routine of the caller's own
    (child's) class — the client renders/prints it with the same builder as
    the institution portal (lib/admit-card.ts). ?examId=<id> */
export async function GET(req: Request) {
  const session = await requireAnyRole(["STUDENT", "PARENT"]);
  if (!session || !session.institutionId) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  const examId = Number(new URL(req.url).searchParams.get("examId") ?? "");
  if (!Number.isInteger(examId) || examId <= 0) {
    return NextResponse.json({ error: "BAD_EXAM" }, { status: 400 });
  }

  const studentId = await getMemberStudentId(session.userId);
  if (!studentId) {
    return NextResponse.json({ error: "NO_LINKED_STUDENT" }, { status: 409 });
  }
  const student = await prisma.student.findUnique({
    where: { id: studentId },
    select: {
      id: true,
      roll: true,
      name: true,
      nameBn: true,
      photoUrl: true,
      status: true,
      classItemId: true,
      sectionItemId: true,
      classItem: { select: { name: true, nameBn: true } },
      sectionItem: { select: { name: true, nameBn: true } },
    },
  });
  if (!student || student.status !== "ACTIVE") {
    return NextResponse.json({ error: "NO_LINKED_STUDENT" }, { status: 409 });
  }

  // the exam must be published for the student's class (whole-class or own section)
  const exam = await prisma.exam.findFirst({
    where: {
      id: examId,
      institutionId: session.institutionId,
      schedulePublished: true,
      OR: [
        { classItemId: student.classItemId, sectionItemId: null },
        { classItemId: student.classItemId, sectionItemId: student.sectionItemId },
      ],
    },
    select: {
      id: true,
      name: true,
      nameBn: true,
      startDate: true,
      endDate: true,
      classItem: { select: { name: true, nameBn: true } },
      schedules: {
        orderBy: [{ date: "asc" }, { startTime: "asc" }],
        select: {
          id: true,
          date: true,
          startTime: true,
          endTime: true,
          fullMarks: true,
          totalPassMarks: true,
          cqMarks: true,
          cqPassMarks: true,
          mcqMarks: true,
          mcqPassMarks: true,
          appliedMarks: true,
          appliedPassMarks: true,
          appliedDate: true,
          note: true,
          subjectItem: { select: { name: true, nameBn: true } },
          roomItem: { select: { name: true, nameBn: true } },
        },
      },
    },
  });
  if (!exam) {
    return NextResponse.json({ error: "EXAM_NOT_FOUND" }, { status: 404 });
  }

  const institution = await prisma.institution.findUnique({
    where: { id: session.institutionId },
    select: { name: true, address: true, phone: true, logo: true },
  });

  // verification code for the student's own admit card (same exam toggle as
  // the institution's mint endpoint; null when the module is switched off)
  let verifyCode: string | null = null;
  try {
    const { toggles } = await resolveVerificationSetting(session.institutionId);
    if (toggles.examSchedule) {
      const stored = await ensureCode({
        kind: "ADMIT_CARD",
        institutionId: session.institutionId,
        refKey: `exam:${examId}`,
        studentId: student.id,
        label: exam.name,
      });
      verifyCode = formatCode(stored);
    }
  } catch {
    verifyCode = null;
  }

  return NextResponse.json({
    verifyCode,
    exam: {
      id: exam.id,
      name: exam.name,
      nameBn: exam.nameBn,
      className: exam.classItem?.name ?? null,
      classNameBn: exam.classItem?.nameBn ?? null,
      sectionName: student.sectionItem?.name ?? null,
      sectionNameBn: student.sectionItem?.nameBn ?? null,
      startDate: exam.startDate,
      endDate: exam.endDate,
    },
    student: {
      id: student.id,
      roll: student.roll,
      name: student.name,
      nameBn: student.nameBn,
      photoUrl: student.photoUrl,
      verifyCode,
    },
    papers: exam.schedules.map((s) => ({
      id: s.id,
      subjectName: s.subjectItem?.name ?? null,
      subjectNameBn: s.subjectItem?.nameBn ?? null,
      date: s.date,
      startTime: s.startTime,
      endTime: s.endTime,
      roomName: s.roomItem?.name ?? null,
      roomNameBn: s.roomItem?.nameBn ?? null,
      fullMarks: s.fullMarks,
      totalPassMarks: s.totalPassMarks,
      cqMarks: s.cqMarks,
      cqPassMarks: s.cqPassMarks,
      mcqMarks: s.mcqMarks,
      mcqPassMarks: s.mcqPassMarks,
      appliedMarks: s.appliedMarks,
      appliedPassMarks: s.appliedPassMarks,
      appliedDate: s.appliedDate,
      note: s.note,
    })),
    institution: institution ?? null,
  });
}
