import { Test } from '@nestjs/testing';
import { INestApplication } from '@nestjs/common';
import request from 'supertest';

import { DatabasePostgresModule } from '../../../../src/modules/free/database/db_postgres/postgres.module';
import { DatabasePostgresHealthModule } from '../../../../src/health/postgres-health.module';
import { DatabasePostgresService } from '../../../../src/modules/free/database/db_postgres/postgres.service';

async function createApplication(): Promise<INestApplication> {
  const moduleRef = await Test.createTestingModule({
    imports: [DatabasePostgresModule, DatabasePostgresHealthModule],
  }).compile();

  const app = moduleRef.createNestApplication();
  await app.init();
  return app;
}

describe('DatabasePostgresModule (Integration)', () => {
  let app: INestApplication;
  let service: DatabasePostgresService;

  beforeAll(async () => {
    app = await createApplication();
    service = app.get(DatabasePostgresService);
  });

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

  it('provides DatabasePostgresService instance', () => {
    expect(service).toBeDefined();
    expect(typeof service.getConfig).toBe('function');
    expect(typeof service.getDatabaseUrl).toBe('function');
  });

  it('masks credentials when requesting database URL', () => {
    const masked = service.getDatabaseUrl(true);
    expect(masked).toContain('postgresql://');
    expect(masked).toContain('***');
  });

  it('exposes health status endpoint', async () => {
    const poolMock = {
      pool_size: 5,
      checked_in: 5,
      checked_out: 0,
      overflow: 0,
      total_connections: 5,
      waiting: 0,
    };

    jest.spyOn(service, 'checkHealth').mockResolvedValue(undefined);
    jest.spyOn(service, 'getPoolStatus').mockResolvedValue(poolMock);
    jest
      .spyOn(service, 'getDatabaseUrl')
      .mockImplementation(() => 'postgresql://masked');

    const server = app.getHttpServer();
    const response = await request(server).get('/api/health/module/postgres');

    expect(response.status).toBe(200);
    expect(response.body).toHaveProperty('status');
    expect(response.body).toHaveProperty('module', '{{ rapidkit_vendor_module }}');
    expect(response.body).toHaveProperty('pool');
  });
});
