/**
 * In-memory pub/sub bus for in-app notifications.
 *
 * Producers (e.g. ticket action-notification route) call publishNotification();
 * SSE connections in server/api/notifications/stream.get.ts subscribe and forward
 * the payload to the matching client(s), where plugins/03.notifications-stream.client.ts
 * turns each event into an in-app toast via useToast().
 *
 * KNOWN LIMITATION — PM2 cluster mode (2 instances per ecosystem.config.js):
 *   This bus is per-process. A publish on instance A is not seen by SSE clients
 *   connected to instance B. With 2 instances and roughly even load-balancing,
 *   about half of events will be missed by the in-app toast layer for any given
 *   recipient. The OS push path (sw-notifications.js) is unaffected because the
 *   web-push server speaks directly to the device endpoint and doesn't go via
 *   this bus. If cross-instance toast delivery becomes important, add a SQLite-
 *   or Redis-backed backplane: publishNotification inserts a row, each instance
 *   polls for unseen rows and re-emits locally.
 *
 * The instance is stashed on globalThis so that Nitro's HMR in dev does not
 * blow away connected listeners on every file save.
 */

import { EventEmitter } from 'node:events'

export interface NotificationPayload {
  title: string
  body: string
  url?: string
  icon?: string
  type?: string
  ticketId?: number | string
  docNo?: string
  timestamp?: number
  [k: string]: any
}

export interface NotificationEvent {
  recipientRoleIds: number[]
  payload: NotificationPayload
}

const BUS_KEY = Symbol.for('logship.notificationBus')
const g = globalThis as any

if (!g[BUS_KEY]) {
  const bus = new EventEmitter()
  // One listener per connected SSE client. Default cap is 10; raise so we
  // don't get unbounded-listener warnings as more users sign in.
  bus.setMaxListeners(0)
  g[BUS_KEY] = bus
  console.log('[NotifBus] initialised')
}

export const notificationBus: EventEmitter = g[BUS_KEY]

export const publishNotification = (evt: NotificationEvent) => {
  if (!evt.payload.timestamp) evt.payload.timestamp = Date.now()
  notificationBus.emit('notification', evt)
  console.log(
    `[NotifBus] published — type=${evt.payload.type ?? 'generic'} recipients=${evt.recipientRoleIds.length}`
  )
}
