import { describe, expect, it, vi } from 'vitest';
import { CronJobExecutionStatus } from '@prisma/client';
import { InternalCronService } from '../src/modules/internal-cron/internal-cron.service';

describe('InternalCronService', () => {
  it('skips execution when the same job is already running', async () => {
    const prisma = {
      cronJobLog: {
        findFirst: vi.fn().mockResolvedValue({ id: 'running-log' }),
      },
    } as never;

    const service = new InternalCronService(prisma, {} as never, {} as never);
    const result = await service.runMonthlyGenerate('127.0.0.1');

    expect(result).toEqual({
      skipped: true,
      reason: 'Job already running',
      logId: 'running-log',
    });
  });

  it('logs successful execution', async () => {
    const prisma = {
      cronJobLog: {
        findFirst: vi.fn().mockResolvedValue(null),
        create: vi.fn().mockResolvedValue({ id: 'log-1' }),
        update: vi.fn().mockResolvedValue(undefined),
      },
    } as never;
    const campaignsService = {
      generateMonthly: vi.fn().mockResolvedValue({ id: 'campaign-1' }),
    } as never;

    const service = new InternalCronService(prisma, campaignsService, {} as never);
    const result = await service.runMonthlyGenerate('127.0.0.1');

    expect(result).toMatchObject({
      skipped: false,
      logId: 'log-1',
      campaignId: 'campaign-1',
    });
    expect(prisma.cronJobLog.create).toHaveBeenCalled();
    expect(prisma.cronJobLog.update).toHaveBeenCalledWith({
      where: { id: 'log-1' },
      data: expect.objectContaining({
        status: CronJobExecutionStatus.SUCCESS,
      }),
    });
  });

  it('runs recurring campaign generation jobs', async () => {
    const prisma = {
      cronJobLog: {
        findFirst: vi.fn().mockResolvedValue(null),
        create: vi.fn().mockResolvedValue({ id: 'log-2' }),
        update: vi.fn().mockResolvedValue(undefined),
      },
    } as never;
    const campaignsService = {
      runRecurringGeneration: vi.fn().mockResolvedValue({
        generatedCount: 2,
        assignmentCount: 10,
        recurringCampaignsProcessed: 1,
      }),
    } as never;

    const service = new InternalCronService(prisma, campaignsService, {} as never);
    const result = await service.runRecurringGenerate('127.0.0.1');

    expect(result).toMatchObject({
      skipped: false,
      logId: 'log-2',
      generatedCount: 2,
      assignmentCount: 10,
    });
  });
});
