/**
 * desktop/src/notifications.ts — B2: batch notification diff across sessions.
 *
 * Given the previous per-session snapshots and the latest poll, compute which
 * sessions warrant a native notification (delegating each decision to
 * notify-policy's shouldNotify) and the NEW snapshot map to carry forward.
 *
 * Pure: never mutates `prev`. The returned `next` map is rebuilt only from the
 * current snapshots, so sessions that ended (absent this round) naturally drop
 * out and won't re-fire on their next appearance.
 */

import { shouldNotify, type NotifyOptions } from './notify-policy.js'
import type { NotifyDecision, SessionStatusSnapshot } from './types.js'

/** Result of diffing a poll: what to fire now + the state to remember. */
export interface NotificationsResult {
  readonly decisions: readonly NotifyDecision[]
  /** Fresh snapshot map (sessionId → snapshot) for the next round. Handed off as
   *  ReadonlyMap so callers can't mutate the carried-forward state (immutability
   *  is a CRITICAL project rule); the concrete Map is still assignable. */
  readonly next: ReadonlyMap<string, SessionStatusSnapshot>
}

/**
 * Diff the latest snapshots against the previous round. Collect only the
 * notifying decisions, and build a new snapshot map keyed by sessionId. The
 * input `prev` map is treated as read-only and left untouched.
 */
export function computeNotifications(
  prev: ReadonlyMap<string, SessionStatusSnapshot>,
  snapshots: readonly SessionStatusSnapshot[],
  opts: NotifyOptions,
): NotificationsResult {
  const decisions: NotifyDecision[] = []
  const next = new Map<string, SessionStatusSnapshot>()

  for (const snapshot of snapshots) {
    const decision = shouldNotify(prev.get(snapshot.sessionId), snapshot, opts)
    if (decision.notify) decisions.push(decision)
    next.set(snapshot.sessionId, snapshot)
  }

  return { decisions, next }
}
