import { NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
import { requireRole } from "@/lib/auth";
import {
  MENU_AUDIENCES,
  MENU_CATALOG_KEYS,
  emptyHidden,
  type MenuAudience,
} from "@/lib/menu-access";

/** Central-side subscription menu access for ONE institution — same
 *  contract as /api/portal/menu-access, but scoped by path id and
 *  guarded by SUPER_ADMIN (the central credentials area manages this
 *  on behalf of any institution). */

async function resolveInstitution(idParam: string) {
  const id = Number(idParam);
  if (!Number.isInteger(id) || id <= 0) return null;
  return prisma.institution.findUnique({
    where: { id },
    select: { id: true, name: true },
  });
}

export async function GET(_req: Request, { params }: { params: Promise<{ id: string }> }) {
  const session = await requireRole("SUPER_ADMIN");
  if (!session) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }
  const { id } = await params;
  const institution = await resolveInstitution(id);
  if (!institution) {
    return NextResponse.json({ error: "Institution not found" }, { status: 404 });
  }

  const rows = await prisma.menuAccess.findMany({
    where: { institutionId: institution.id, visible: false },
    select: { audience: true, menuKey: true },
  });

  const hidden = emptyHidden();
  for (const row of rows) {
    if ((MENU_AUDIENCES as readonly string[]).includes(row.audience)) {
      hidden[row.audience as MenuAudience].push(row.menuKey);
    }
  }
  for (const aud of MENU_AUDIENCES) hidden[aud].sort();

  return NextResponse.json({ institution: { id: institution.id, name: institution.name }, hidden });
}

export async function PUT(req: Request, { params }: { params: Promise<{ id: string }> }) {
  const session = await requireRole("SUPER_ADMIN");
  if (!session) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }
  const { id } = await params;
  const institution = await resolveInstitution(id);
  if (!institution) {
    return NextResponse.json({ error: "Institution not found" }, { status: 404 });
  }

  try {
    const body = await req.json();
    const incoming = body?.hidden;
    if (!incoming || typeof incoming !== "object") {
      return NextResponse.json({ error: "Invalid payload" }, { status: 400 });
    }

    const rows: { institutionId: number; audience: string; menuKey: string; visible: boolean }[] = [];
    for (const aud of MENU_AUDIENCES) {
      const list = incoming[aud];
      if (!Array.isArray(list)) continue;
      const keys = new Set(
        list
          .map((k: unknown) => String(k))
          .filter((k) => MENU_CATALOG_KEYS[aud].has(k))
      );
      for (const menuKey of keys) {
        rows.push({ institutionId: institution.id, audience: aud, menuKey, visible: false });
      }
    }

    await prisma.$transaction([
      prisma.menuAccess.deleteMany({ where: { institutionId: institution.id } }),
      ...(rows.length ? [prisma.menuAccess.createMany({ data: rows })] : []),
    ]);

    return NextResponse.json({ ok: true, saved: rows.length });
  } catch {
    return NextResponse.json({ error: "Could not save menu access" }, { status: 500 });
  }
}
