import { Test, TestingModule } from '@nestjs/testing';
import { INestApplication, ExecutionContext } from '@nestjs/common';
import * as request from 'supertest';
import { ScheduledJobsController } from '../src/scheduled-jobs/scheduled-jobs.controller';
import { ScheduledJobsService } from '../src/scheduled-jobs/scheduled-jobs.service';
import { ServiceCredentialGuard } from '../src/common/guards/service-credential/service-credential.guard';
import { ConfigModule } from '@nestjs/config';

/** Guard stub that always rejects — simulates a request with no valid service key. */
const denyingGuard = {
  canActivate: jest.fn((_ctx: ExecutionContext) => false),
};

/** Service stub — should never be reached when guard denies. */
const mockScheduledJobsService = {
  register: jest.fn(),
  unregister: jest.fn(),
  runNow: jest.fn(),
  runIfDue: jest.fn(),
  reconcile: jest.fn(),
};

describe('ScheduledJobs (e2e) — auth rejection', () => {
  let app: INestApplication;

  beforeAll(async () => {
    const moduleFixture: TestingModule = await Test.createTestingModule({
      imports: [
        ConfigModule.forRoot({
          isGlobal: true,
          ignoreEnvFile: true,
          load: [
            () => ({
              NODE_ENV: 'test',
              API_KEY: 'test-api-key',
              SERVICE_CREDENTIALS_ENABLED: false,
            }),
          ],
        }),
      ],
      controllers: [ScheduledJobsController],
      providers: [
        {
          provide: ScheduledJobsService,
          useValue: mockScheduledJobsService,
        },
        {
          provide: ServiceCredentialGuard,
          useValue: denyingGuard,
        },
      ],
    })
      .overrideGuard(ServiceCredentialGuard)
      .useValue(denyingGuard)
      .compile();

    app = moduleFixture.createNestApplication();
    await app.init();
  });

  afterAll(async () => {
    if (app) {
      await app.close();
    }
  });

  beforeEach(() => {
    jest.clearAllMocks();
  });

  it('POST /scheduled-jobs/register — sem service key → 403', () => {
    return request(app.getHttpServer())
      .post('/scheduled-jobs/register')
      .send({
        job: {
          jobId: 'test-job',
          scheduleType: 'INTERVAL',
          intervalEvery: 5,
          intervalUnit: 'MINUTES',
        },
      })
      .expect((res) => {
        expect([401, 403]).toContain(res.status);
      });
  });

  it('POST /scheduled-jobs/unregister — sem service key → 401 ou 403', () => {
    return request(app.getHttpServer())
      .post('/scheduled-jobs/unregister')
      .send({ jobId: 'test-job' })
      .expect((res) => {
        expect([401, 403]).toContain(res.status);
      });
  });

  it('POST /scheduled-jobs/run-now — sem service key → 401 ou 403', () => {
    return request(app.getHttpServer())
      .post('/scheduled-jobs/run-now')
      .send({ jobId: 'test-job' })
      .expect((res) => {
        expect([401, 403]).toContain(res.status);
      });
  });
});
