import { NextResponse } from "next/server";
import { requireRole } from "@/lib/auth";
import { resolveVerificationSetting } from "@/lib/notify";
import { ensureCode, formatCode, type VerifyKind } from "@/lib/verify-code";

/**
 * Mint (idempotently) the short verification code that gets printed as QR
 * text on a document. kind RESULT takes rows[] (one code per student);
 * EXAM_SCHEDULE / INVENTORY take refKey/label only. Kinds switched OFF in
 * the credential panels (institution row, central fallback) are refused —
 * already-issued codes still verify publicly.
 */
export async function POST(req: Request) {
  const session = await requireRole("INSTITUTION_ADMIN");
  if (!session?.institutionId) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }
  const body = (await req.json().catch(() => ({}))) as {
    kind?: string;
    refKey?: string;
    label?: string;
    rows?: { studentId: number; total?: string | number; grade?: string }[];
  };

  const kind = body.kind as VerifyKind;
  if (kind !== "RESULT" && kind !== "EXAM_SCHEDULE" && kind !== "INVENTORY" && kind !== "ADMIT_CARD") {
    return NextResponse.json({ error: "Invalid kind" }, { status: 400 });
  }

  const { toggles } = await resolveVerificationSetting(session.institutionId);
  // admit cards are exam documents — gated by the exam-schedule toggle
  const enabled =
    kind === "RESULT"
      ? toggles.result
      : kind === "EXAM_SCHEDULE" || kind === "ADMIT_CARD"
        ? toggles.examSchedule
        : toggles.inventory;
  if (!enabled) {
    return NextResponse.json({ error: "MODULE_DISABLED" }, { status: 403 });
  }

  const refKey = (body.refKey ?? "").trim();
  if (!refKey) return NextResponse.json({ error: "refKey required" }, { status: 400 });

  if (kind === "RESULT" || kind === "ADMIT_CARD") {
    const rows = body.rows ?? [];
    const codes: { studentId: number; code: string }[] = [];
    for (const r of rows) {
      if (!r.studentId) continue;
      const stored = await ensureCode({
        kind,
        institutionId: session.institutionId,
        refKey,
        studentId: r.studentId,
        label: body.label ?? null,
        total: r.total != null ? String(r.total) : null,
        grade: r.grade ?? null,
      });
      codes.push({ studentId: r.studentId, code: formatCode(stored) });
    }
    return NextResponse.json({ codes });
  }

  const stored = await ensureCode({
    kind,
    institutionId: session.institutionId,
    refKey,
    label: body.label ?? null,
  });
  return NextResponse.json({ code: formatCode(stored) });
}
