/* ------------------------------------------------------------------ */
/* Subscription menu access — the catalog of sidebar menus that can be */
/* shown/hidden per audience for an institution.                       */
/*                                                                     */
/* Audiences: INSTITUTION (the admin portal sidebar) and the four      */
/* member audiences (TEACHER / STUDENT / PARENT / STAFF — the /me      */
/* sidebar). Keys are stable strings; the API stores ONLY hidden keys  */
/* (menu_access rows), so an institution with no rows sees everything  */
/* — the feature never breaks existing deployments.                    */
/*                                                                     */
/* Core items (dashboard, profile, packages, billing, verify, guide,   */
/* control panel) are deliberately NOT controllable: hiding them could */
/* lock an admin out of subscription/billing or settings.              */
/* ------------------------------------------------------------------ */

export type MenuAudience = "INSTITUTION" | "TEACHER" | "STUDENT" | "PARENT" | "STAFF";

export const MENU_AUDIENCES: readonly MenuAudience[] = [
  "INSTITUTION",
  "TEACHER",
  "STUDENT",
  "PARENT",
  "STAFF",
];

/** resolves the localized menu label from the i18n dictionary */
export type MenuLabelFn = (t: Record<string, unknown>) => string;

export interface MenuCatalogItem {
  key: string;
  label: MenuLabelFn;
}

const at = (path: string): MenuLabelFn => {
  const parts = path.split(".");
  return (t) => {
    let node: unknown = t;
    for (const p of parts) {
      node = (node as Record<string, unknown> | null)?.[p];
      if (node === undefined || node === null) return path;
    }
    return typeof node === "string" ? node : path;
  };
};

/** Portal sidebar menus the institution admin sees (controllable set). */
export const INSTITUTION_MENUS: MenuCatalogItem[] = [
  { key: "admissions", label: at("portal.admissionsPage.title") },
  { key: "inquiries", label: at("portal.inquiriesPage.title") },
  { key: "students", label: at("portal.studentsPage.title") },
  { key: "identity", label: at("portal.identityPage.title") },
  { key: "fees", label: at("portal.feesPage.title") },
  { key: "accounts", label: at("portal.accountsPage.title") },
  { key: "academic", label: at("common.academicInfo") },
  { key: "promotions", label: at("portal.promotionsPage.title") },
  { key: "schedule", label: at("portal.schedulePage.title") },
  { key: "exams", label: at("portal.examsPage.title") },
  { key: "results", label: at("portal.resultsPage.title") },
  { key: "lessonPlans", label: at("portal.lessonPlanPage.title") },
  { key: "omr", label: at("portal.omrPage.title") },
  { key: "campus", label: at("portal.campusAcademicPage.title") },
  { key: "hr", label: at("portal.hrPage.title") },
  { key: "library", label: at("portal.libraryPage.title") },
  { key: "hostel", label: at("portal.hostelPage.title") },
  { key: "inventory", label: at("portal.inventoryPage.title") },
  { key: "transport", label: at("portal.transportPage.title") },
  { key: "notices", label: at("portal.noticesPage.title") },
  { key: "events", label: at("portal.eventsPage.title") },
  { key: "committees", label: at("portal.committeesPage.title") },
  { key: "complaints", label: at("portal.complaintsPage.title") },
  { key: "support", label: at("portal.supportPage.title") },
  { key: "certificates", label: at("portal.certificatesPage.title") },
  { key: "competitions", label: at("portal.competitionsPage.title") },
  { key: "messages", label: at("portal.messagesPage.title") },
  { key: "communication", label: at("portal.communicationPage.title") },
];

/** /me sidebar menus per member audience (controllable set). */
export const MEMBER_MENUS: MenuCatalogItem[] = [
  { key: "results", label: at("me.navResults") },
  { key: "exams", label: at("me.navExams") },
  { key: "schedule", label: at("me.navSchedule") },
  { key: "attendance", label: at("me.navAttendance") },
  { key: "attendanceTake", label: at("me.navTakeAttendance") },
  { key: "fees", label: at("me.navFees") },
  { key: "marks", label: at("me.navMarks") },
  { key: "leaves", label: at("me.navLeaves") },
  { key: "payroll", label: at("me.navPayroll") },
  { key: "lessonPlans", label: at("me.navLessonPlans") },
  { key: "notices", label: at("me.navNotices") },
  { key: "complaints", label: at("me.navComplaints") },
  { key: "idcard", label: at("me.navIdCard") },
];

/** Which member-menu keys apply to which audience (mirrors the /me nav
 *  role filters in src/app/me/layout.tsx). */
export const AUDIENCE_MEMBER_KEYS: Record<Exclude<MenuAudience, "INSTITUTION">, string[]> = {
  STUDENT: ["results", "exams", "schedule", "attendance", "fees", "notices", "complaints", "idcard"],
  PARENT: ["results", "exams", "schedule", "attendance", "fees", "notices", "complaints", "idcard"],
  TEACHER: ["attendance", "attendanceTake", "marks", "leaves", "payroll", "lessonPlans", "notices", "complaints"],
  STAFF: ["attendance", "attendanceTake", "marks", "leaves", "payroll", "lessonPlans", "notices", "complaints"],
};

/** Full catalog per audience (drives the management UI). */
export const MENU_CATALOG: Record<MenuAudience, MenuCatalogItem[]> = {
  INSTITUTION: INSTITUTION_MENUS,
  TEACHER: MEMBER_MENUS,
  STAFF: MEMBER_MENUS,
  STUDENT: MEMBER_MENUS,
  PARENT: MEMBER_MENUS,
};

/** Valid keys per audience (drives server-side validation). */
export const MENU_CATALOG_KEYS: Record<MenuAudience, Set<string>> = Object.fromEntries(
  MENU_AUDIENCES.map((aud) => [
    aud,
    new Set(
      aud === "INSTITUTION"
        ? INSTITUTION_MENUS.map((m) => m.key)
        : MEMBER_MENUS.map((m) => m.key)
    ),
  ])
) as Record<MenuAudience, Set<string>>;

/** hidden-menu sets by audience, as delivered to the layouts */
export type HiddenMenus = Partial<Record<MenuAudience, string[]>>;

export function emptyHidden(): Record<MenuAudience, string[]> {
  return { INSTITUTION: [], TEACHER: [], STUDENT: [], PARENT: [], STAFF: [] };
}

/** Which member audience a session role maps to (null = none). */
export function audienceForRole(role: string): MenuAudience | null {
  switch (role) {
    case "STUDENT":
      return "STUDENT";
    case "PARENT":
      return "PARENT";
    case "TEACHER":
      return "TEACHER";
    case "STAFF":
      return "STAFF";
    default:
      return null;
  }
}
