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

// ── Job payload ──────────────────────────────────────────────────────────────

export interface NotificationTargetJobData {
  campaignId: string;
  payload: Record<string, any>;
}

// ── Constants ────────────────────────────────────────────────────────────────

export const NOTIFICATION_TARGET_QUEUE = "notification-target";
export const MAX_RETRIES = 5;
export const RETRY_DELAY_MS = 15 * 60 * 1000; // 15 minutes

// ── Redis connection ─────────────────────────────────────────────────────────

// BullMQ requires maxRetriesPerRequest: null and works best with
// enableOfflineQueue: false so jobs fail fast on disconnect instead of
// queuing indefinitely inside the client.
export function getBullMQConnection(): ConnectionOptions {
  return {
    host: env.GetString("REDIS_HOST"),
    port: env.GetInt("REDIS_PORT"),
    username: process.env.REDIS_USERNAME || undefined,
    password: process.env.REDIS_PASSWORD || undefined,
    connectTimeout: env.GetInt("REDIS_CONNECTION_TIMEOUT") || 10000,
    maxRetriesPerRequest: null,
    enableOfflineQueue: false,
  };
}

// ── Queue singleton ──────────────────────────────────────────────────────────

let _queue: Queue<NotificationTargetJobData> | null = null;

export function getNotificationTargetQueue(): Queue<NotificationTargetJobData> {
  if (!_queue) {
    _queue = new Queue<NotificationTargetJobData>(NOTIFICATION_TARGET_QUEUE, {
      connection: getBullMQConnection(),
      defaultJobOptions: {
        attempts: MAX_RETRIES + 1, // 1 initial attempt + 5 retries
        backoff: {
          type: "fixed",
          delay: RETRY_DELAY_MS,
        },
        removeOnComplete: { count: 500 },
        removeOnFail: { count: 1000, age: 7 * 24 * 3600 }, // retain failed jobs for 7 days
      },
    });

    _queue.on("error", (err) => {
      console.error("[NotifTargetQueue] Queue error:", err);
    });
  }

  return _queue;
}

// ── Enqueue helper ───────────────────────────────────────────────────────────

export async function enqueueNotificationTarget(
  campaignId: string,
  payload: Record<string, any>,
): Promise<void> {
  const queue = getNotificationTargetQueue();
  await queue.add(
    `campaign-${campaignId}`,
    { campaignId, payload },
    { jobId: `notif-target-${campaignId}-${Date.now()}` },
  );
}
