// src/services/queues.server.test.ts
import { describe, it, expect, vi, beforeEach, type Mock } from 'vitest';

// --- Hoisted Mocks ---
const mocks = vi.hoisted(() => {
  return {
    // This will be our mock for the BullMQ Queue constructor
    MockQueue: vi.fn(),
    // This is a mock for the Redis connection object
    mockConnection: { id: 'mock-redis-connection' },
  };
});

// --- Mock Modules ---

// Mock the 'bullmq' library to replace the real Queue constructor with our mock.
vi.mock('bullmq', () => ({
  Queue: mocks.MockQueue,
}));

// Mock our internal redis connection module to export our mock connection object.
vi.mock('./redis.server', () => ({
  connection: mocks.mockConnection,
}));

describe('Queue Definitions', () => {
  beforeEach(async () => {
    // Clear any previous mock calls and reset module cache before each test.
    // This is crucial because the queues are instantiated at the module level.
    // Resetting modules ensures the `queues.server.ts` file is re-executed.
    vi.clearAllMocks();
    vi.resetModules();

    // Dynamically import the module under test. This will trigger the
    // `new Queue(...)` calls, which will be captured by our mock constructor.
    await import('./queues.server');
  });

  it('should create flyerQueue with the correct name and options', () => {
    expect(mocks.MockQueue).toHaveBeenCalledWith('flyer-processing', {
      connection: mocks.mockConnection,
      defaultJobOptions: {
        attempts: 3,
        backoff: {
          type: 'exponential',
          delay: 5000,
        },
      },
    });
  });

  it('should create emailQueue with the correct name and options', () => {
    expect(mocks.MockQueue).toHaveBeenCalledWith('email-sending', {
      connection: mocks.mockConnection,
      defaultJobOptions: {
        attempts: 5,
        backoff: {
          type: 'exponential',
          delay: 10000,
        },
      },
    });
  });

  it('should create analyticsQueue with the correct name and options', () => {
    expect(mocks.MockQueue).toHaveBeenCalledWith('analytics-reporting', {
      connection: mocks.mockConnection,
      defaultJobOptions: {
        attempts: 2,
        backoff: {
          type: 'exponential',
          delay: 60000,
        },
        removeOnComplete: true,
        removeOnFail: 50,
      },
    });
  });

  it('should create weeklyAnalyticsQueue with the correct name and options', () => {
    expect(mocks.MockQueue).toHaveBeenCalledWith('weekly-analytics-reporting', {
      connection: mocks.mockConnection,
      defaultJobOptions: {
        attempts: 2,
        backoff: { type: 'exponential', delay: 3600000 },
        removeOnComplete: true,
        removeOnFail: 50,
      },
    });
  });

  it('should create cleanupQueue with the correct name and options', () => {
    expect(mocks.MockQueue).toHaveBeenCalledWith('file-cleanup', {
      connection: mocks.mockConnection,
      defaultJobOptions: {
        attempts: 3,
        backoff: { type: 'exponential', delay: 30000 },
        removeOnComplete: true,
      },
    });
  });

  it('should create tokenCleanupQueue with the correct name and options', () => {
    expect(mocks.MockQueue).toHaveBeenCalledWith('token-cleanup', {
      connection: mocks.mockConnection,
      defaultJobOptions: {
        attempts: 2,
        backoff: { type: 'exponential', delay: 3600000 },
        removeOnComplete: true,
        removeOnFail: 10,
      },
    });
  });

  it('should create exactly 6 queues', () => {
    // This is a good sanity check to ensure no new queues were added without tests.
    expect(mocks.MockQueue).toHaveBeenCalledTimes(6);
  });
});