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";

/** Subscription menu access: which sidebar menus are hidden for the
 *  institution portal and each member audience. Only hidden keys are
 *  stored — an institution with no rows shows every menu. */

export async function GET() {
  const session = await requireRole("INSTITUTION_ADMIN");
  if (!session || !session.institutionId) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  const rows = await prisma.menuAccess.findMany({
    where: { institutionId: session.institutionId, 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({ hidden });
}

/** Replace the hidden-menu configuration for this institution.
 *  Body: { hidden: { INSTITUTION: string[], TEACHER: [], … } } — each
 *  list is the FULL desired hidden set for that audience. */
export async function PUT(req: Request) {
  const session = await requireRole("INSTITUTION_ADMIN");
  if (!session || !session.institutionId) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

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

    // validate: known audiences only, known catalog keys only, deduped
    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: session.institutionId, audience: aud, menuKey, visible: false });
      }
    }

    await prisma.$transaction([
      prisma.menuAccess.deleteMany({ where: { institutionId: session.institutionId } }),
      ...(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 });
  }
}
