import { Queue, type ConnectionOptions } from 'bullmq';
import { env } from '@/lib/env';

const redisUrl = env.REDIS_URL;

// 10 queues matching 11-REALTIME-AND-BACKGROUND-JOBS.md Section 3.1
//
// `backoffDelayMs` is the *base* exponential delay; the actual delays
// follow `delay * 2^(attempt-1)` plus BullMQ's jitter. Defaults to 1 s
// for short-lived jobs; outbound `webhooks` overrides to 30 s base so
// the retry curve spans hours instead of seconds (outbound-webhook-
// auditor H2: a 30 s receiver blip during a deploy used to dead-letter
// every in-flight event).
const QUEUE_CONFIGS = {
  email: { concurrency: 5, maxAttempts: 5, backoffDelayMs: 1_000 },
  documents: { concurrency: 3, maxAttempts: 5, backoffDelayMs: 1_000 },
  notifications: { concurrency: 10, maxAttempts: 3, backoffDelayMs: 1_000 },
  import: { concurrency: 1, maxAttempts: 1, backoffDelayMs: 1_000 },
  export: { concurrency: 2, maxAttempts: 3, backoffDelayMs: 1_000 },
  reports: { concurrency: 1, maxAttempts: 3, backoffDelayMs: 1_000 },
  webhooks: { concurrency: 5, maxAttempts: 8, backoffDelayMs: 30_000 },
  maintenance: { concurrency: 1, maxAttempts: 3, backoffDelayMs: 1_000 },
  ai: { concurrency: 2, maxAttempts: 3, backoffDelayMs: 1_000 },
  bulk: { concurrency: 2, maxAttempts: 3, backoffDelayMs: 1_000 },
} as const;

export type QueueName = keyof typeof QUEUE_CONFIGS;

const queues = new Map<QueueName, Queue>();

export function getQueue(name: QueueName): Queue {
  let queue = queues.get(name);
  if (!queue) {
    queue = new Queue(name, {
      connection: { url: redisUrl } as ConnectionOptions,
      defaultJobOptions: {
        attempts: QUEUE_CONFIGS[name].maxAttempts,
        backoff: { type: 'exponential', delay: QUEUE_CONFIGS[name].backoffDelayMs },
        removeOnComplete: { age: 24 * 3600 }, // keep completed jobs 24 hours
        removeOnFail: { age: 7 * 24 * 3600 }, // keep failed jobs 7 days
      },
    });
    queues.set(name, queue);
  }
  return queue;
}

export { QUEUE_CONFIGS };
