import { prisma } from "@/lib/prisma";

/* Push notification fan-out helper. One call inserts a single
   AppNotification row addressed to a set of audience role groups (plus an
   optional class scope); the per-recipient read state is tracked lazily via
   AppNotificationRead when a user opens/marks it. */

/** recipient role groups offered by the audience pickers */
export const NOTIFY_GROUPS: Record<string, string[]> = {
  students: ["STUDENT"],
  parents: ["PARENT"],
  teachers: ["TEACHER"],
  staff: ["STAFF", "PRINCIPAL", "VICE_PRINCIPAL", "EXECUTIVE_MEMBER"],
  admins: ["INSTITUTION_ADMIN"],
};

/** expand group keys ("students","parents",…) into a unique role CSV */
export function expandAudience(groups: string[]): string {
  const roles = new Set<string>();
  for (const g of groups) {
    for (const r of NOTIFY_GROUPS[g] ?? []) roles.add(r);
  }
  return `,${[...roles].join(",")},`;
}

/** default recipient groups for a notice-board audience value */
export function groupsForNoticeAudience(audience: string): string[] {
  if (audience === "STUDENTS") return ["students", "parents"];
  if (audience === "STAFF") return ["teachers", "staff"];
  return ["students", "parents", "teachers", "staff"];
}

export interface PushInput {
  institutionId: number | null;
  kind: "NOTICE" | "EVENT" | "RESULT" | "SYSTEM";
  title: string;
  body?: string | null;
  link?: string | null;
  /** role CSV from expandAudience(), or raw groups array */
  audience: string | string[];
  classItemId?: number | null;
  refId?: number | null;
  createdById?: number | null;
}

export async function pushNotification(input: PushInput): Promise<number | null> {
  try {
    const audienceRoles = Array.isArray(input.audience)
      ? expandAudience(input.audience)
      : input.audience;
    if (audienceRoles === "," || audienceRoles === "") return null;
    const row = await prisma.appNotification.create({
      data: {
        institutionId: input.institutionId,
        kind: input.kind,
        title: input.title.slice(0, 200),
        body: input.body ? input.body.slice(0, 600) : null,
        link: input.link ?? null,
        audienceRoles,
        classItemId: input.classItemId ?? null,
        refId: input.refId ?? null,
        createdById: input.createdById ?? null,
      },
      select: { id: true },
    });
    return row.id;
  } catch {
    // a failed push must never break the publishing action itself
    return null;
  }
}
