import 'reflect-metadata';

import { Test } from '@nestjs/testing';
import request from 'supertest';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { FeaturesModule } from './features.module';

// Mock the feature-loader to control test behavior
vi.mock('../config/feature-loader', () => ({
  loadFeatureConfig: vi.fn(),
}));

import { loadFeatureConfig } from '../config/feature-loader';

describe('Features HTTP Endpoint', () => {
  let app: import("@nestjs/common").INestApplication;

  beforeEach(async () => {
    const module = await Test.createTestingModule({
      imports: [FeaturesModule],
    }).compile();

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

  afterEach(async () => {
    await app?.close();
    vi.clearAllMocks();
  });

  it('GET /features returns 200 with correct shape', async () => {
    vi.mocked(loadFeatureConfig).mockResolvedValue({
      features: {
        'platform.dashboard': 'enabled',
        'platform.leagues': 'enabled',
        'sponsors.portal': 'enabled',
      },
      loadedFrom: 'config-file',
      configPath: 'apps/api/src/config/features.config.ts',
    });

    const response = await request(app.getHttpServer()).get('/features').expect(200);

    expect(response.body).toHaveProperty('features');
    expect(response.body).toHaveProperty('loadedFrom');
    expect(response.body).toHaveProperty('timestamp');

    expect(response.body.features).toEqual({
      'platform.dashboard': 'enabled',
      'platform.leagues': 'enabled',
      'sponsors.portal': 'enabled',
    });
    expect(response.body.loadedFrom).toBe('config-file');
    expect(response.body.timestamp).toMatch(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/);
  });

  it('GET /features returns 200 with empty features', async () => {
    vi.mocked(loadFeatureConfig).mockResolvedValue({
      features: {},
      loadedFrom: 'defaults',
    });

    const response = await request(app.getHttpServer()).get('/features').expect(200);

    expect(response.body.features).toEqual({});
    expect(response.body.loadedFrom).toBe('defaults');
    expect(typeof response.body.timestamp).toBe('string');
  });

  it('GET /features works without authentication', async () => {
    vi.mocked(loadFeatureConfig).mockResolvedValue({
      features: { 'test.feature': 'enabled' as const },
      loadedFrom: 'config-file',
    });

    // Should work without any auth headers
    const response = await request(app.getHttpServer()).get('/features').expect(200);

    expect(response.body.features).toHaveProperty('test.feature');
  });

  it('GET /features includes timestamp as ISO string', async () => {
    const beforeRequest = new Date();
    
    vi.mocked(loadFeatureConfig).mockResolvedValue({
      features: { 'platform.dashboard': 'enabled' as const },
      loadedFrom: 'config-file',
    });

    const response = await request(app.getHttpServer()).get('/features').expect(200);
    const afterRequest = new Date();

    const timestamp = new Date(response.body.timestamp);
    expect(timestamp instanceof Date).toBe(true);
    expect(timestamp.toISOString()).toBe(response.body.timestamp);
    
    // Timestamp should be within the request window
    expect(timestamp >= beforeRequest).toBe(true);
    expect(timestamp <= afterRequest).toBe(true);
  });
});