import { internal } from '../_generated/api';
import type { MutationCtx } from '../_generated/server';
import { NOTIFICATION_CATEGORIES, NOTIFICATION_SEVERITIES } from './schema';

type Category = (typeof NOTIFICATION_CATEGORIES)[number];
type Severity = (typeof NOTIFICATION_SEVERITIES)[number];

interface WriteNotificationArgs {
  organizationIds: string[];
  category: Category;
  severity: Severity;
  titleKey: string;
  bodyKey: string;
  params?: Record<string, unknown>;
  /**
   * The data subject this notification is *about* (distinct from the
   * audience — admins reading the notifications bell). Populating this
   * lets `eraseSubjectNotifications` (GDPR Art 17) match by userId
   * regardless of audit-pepper rotation or email change.
   */
  subjectUserId?: string;
}

/**
 * Insert one notification per organization. Used by background events
 * (e.g. login lockouts) that need to fan out to admins of every org the
 * affected user belongs to.
 */
export async function writeNotificationForOrgs(
  ctx: MutationCtx,
  args: WriteNotificationArgs,
): Promise<void> {
  const now = Date.now();
  for (const organizationId of args.organizationIds) {
    await ctx.db.insert('notifications', {
      organizationId,
      category: args.category,
      severity: args.severity,
      titleKey: args.titleKey,
      bodyKey: args.bodyKey,
      params: args.params,
      subjectUserId: args.subjectUserId,
      createdAt: now,
      readBy: [],
    });
  }

  // Mirror security alerts to external notification channels (Slack today).
  // The dispatcher/sink decide per-org whether Slack is connected and the
  // event enabled, so this stays an unconditional best-effort fan-out. We pass
  // the i18n KEYS plus the interpolation params (NOT pre-rendered text) so the
  // dispatcher can render in each org's locale — matching the in-app bell.
  if (args.category === 'security') {
    for (const organizationId of args.organizationIds) {
      await ctx.scheduler.runAfter(
        0,
        internal.notifications.dispatch_notification.dispatchNotificationAction,
        {
          organizationId,
          eventType: 'security.alert',
          params: {
            titleKey: args.titleKey,
            bodyKey: args.bodyKey,
            params: args.params,
          },
        },
      );
    }
  }
}
