import { eq } from 'drizzle-orm';
import type { DrizzleClient } from '../client.js';
import { users } from '../schema.js';

/** Convenience alias used by callers that import this module. */
export type Db = DrizzleClient;

export type NotifPrefs = {
  optional?: Record<string, boolean>;
  marketing?: Record<string, boolean>;
};

export async function loadPrefs(db: DrizzleClient, userId: string): Promise<NotifPrefs> {
  const [row] = await db
    .select({ p: users.notifPrefs })
    .from(users)
    .where(eq(users.id, userId))
    .limit(1);
  return (row?.p as NotifPrefs | undefined) ?? {};
}

export async function updatePrefs(
  db: DrizzleClient,
  userId: string,
  patch: NotifPrefs,
): Promise<NotifPrefs> {
  const current = await loadPrefs(db, userId);
  const merged: NotifPrefs = {
    optional: { ...(current.optional ?? {}), ...(patch.optional ?? {}) },
    marketing: { ...(current.marketing ?? {}), ...(patch.marketing ?? {}) },
  };
  await db.update(users).set({ notifPrefs: merged }).where(eq(users.id, userId));
  return merged;
}

/**
 * Tier-aware allow rule used by UserSessionDO.deliver (design apps/web/src/server/storage/imageVariants.ts.3).
 *
 * - critical: always delivered
 * - optional: delivered unless explicitly opted out (default = true)
 * - marketing: delivered only when explicitly opted in (default = false)
 */
export function allowsEvent(
  prefs: NotifPrefs,
  event: string,
  tier: 'critical' | 'optional' | 'marketing',
): boolean {
  if (tier === 'critical') return true;
  if (tier === 'optional') return prefs.optional?.[event] !== false;
  return prefs.marketing?.[event] === true;
}
