/**
 * Test file for the new feature flag configuration system
 * 
 * Run with: npm test -- feature-loader.test.ts
 */

import { beforeEach, describe, expect, it } from 'vitest';
import { getAllFeatures, getFeatureState, isFeatureEnabled, loadFeatureConfig } from './feature-loader';
import { FlattenedFeatures } from './feature-types';

describe('Feature Flag Configuration', () => {
  const originalEnv = process.env.NODE_ENV;

  beforeEach(() => {
    // Reset environment if needed
  });

  afterAll(() => {
    // Restore original environment
    process.env.NODE_ENV = originalEnv;
  });

  describe('loadFeatureConfig', () => {
    it('should load development config when NODE_ENV=development', async () => {
      process.env.NODE_ENV = 'development';
      const result = await loadFeatureConfig();

      expect(result.loadedFrom).toBe('config-file');
      expect(result.features).toBeDefined();
      
      // Core platform features (alpha mode - all enabled)
      expect(result.features['platform.dashboard']).toBe('enabled');
      expect(result.features['platform.leagues']).toBe('enabled');
      
      // Sponsor features
      expect(result.features['sponsors.portal']).toBe('enabled');
      expect(result.features['sponsors.management']).toBe('enabled');
      
      // Admin features
      expect(result.features['admin.dashboard']).toBe('enabled');
      
      // Beta features (development has them enabled for testing)
      expect(result.features['beta.newUI']).toBe('enabled');
    });

    it('should load test config when NODE_ENV=test', async () => {
      process.env.NODE_ENV = 'test';
      const result = await loadFeatureConfig();

      expect(result.loadedFrom).toBe('config-file');
      
      // Core platform features
      expect(result.features['platform.dashboard']).toBe('enabled');
      
      // Sponsor features
      expect(result.features['sponsors.portal']).toBe('enabled');
      
      // Admin features
      expect(result.features['admin.dashboard']).toBe('enabled');
      
      // Beta features (disabled in test)
      expect(result.features['beta.newUI']).toBe('disabled');
    });

    it('should load production config when NODE_ENV=production', async () => {
      process.env.NODE_ENV = 'production';
      const result = await loadFeatureConfig();

      expect(result.loadedFrom).toBe('config-file');
      
      // Core platform features (stable)
      expect(result.features['platform.dashboard']).toBe('enabled');
      
      // Sponsor features (gradual rollout - management disabled)
      expect(result.features['sponsors.portal']).toBe('enabled');
      expect(result.features['sponsors.management']).toBe('disabled');
      
      // Admin features (analytics disabled)
      expect(result.features['admin.dashboard']).toBe('enabled');
      expect(result.features['admin.analytics']).toBe('disabled');
      
      // Beta features (disabled in production)
      expect(result.features['beta.newUI']).toBe('disabled');
    });

    it('should handle invalid environment', async () => {
      process.env.NODE_ENV = 'invalid-env';

      await expect(loadFeatureConfig()).rejects.toThrow('Invalid environment');
    });
  });

  describe('isFeatureEnabled', () => {
    it('should return true for enabled features', () => {
      const features: FlattenedFeatures = { 'sponsors.portal': 'enabled' };
      expect(isFeatureEnabled(features, 'sponsors.portal')).toBe(true);
    });

    it('should return false for disabled features', () => {
      const features: FlattenedFeatures = { 'sponsors.portal': 'disabled' };
      expect(isFeatureEnabled(features, 'sponsors.portal')).toBe(false);
    });

    it('should return false for non-existent features', () => {
      const features: FlattenedFeatures = { 'sponsors.portal': 'enabled' };
      expect(isFeatureEnabled(features, 'nonexistent.feature')).toBe(false);
    });
  });

  describe('getFeatureState', () => {
    it('should return correct state for existing features', () => {
      const features: FlattenedFeatures = { 'sponsors.portal': 'coming_soon' };
      expect(getFeatureState(features, 'sponsors.portal')).toBe('coming_soon');
    });

    it('should return disabled for non-existent features', () => {
      const features: FlattenedFeatures = { 'sponsors.portal': 'enabled' };
      expect(getFeatureState(features, 'nonexistent')).toBe('disabled');
    });
  });

  describe('getAllFeatures', () => {
    it('should return all features for current environment', () => {
      process.env.NODE_ENV = 'development';
      const features = getAllFeatures();

      expect(features).toBeDefined();
      expect(Object.keys(features).length).toBeGreaterThan(0);
    });
  });

  describe('Flattening behavior', () => {
    it('should flatten nested feature configurations', async () => {
      process.env.NODE_ENV = 'development';
      const result = await loadFeatureConfig();

      // Should flatten nested objects
      expect(result.features['sponsors.portal']).toBeDefined();
      expect(result.features['sponsors.dashboard']).toBeDefined();
      expect(result.features['admin.dashboard']).toBeDefined();
    });
  });

  describe('Feature state differences', () => {
    it('should correctly handle all feature states', async () => {
      process.env.NODE_ENV = 'staging';
      const result = await loadFeatureConfig();

      // 'enabled' - fully available
      expect(result.features['platform.dashboard']).toBe('enabled');
      
      // 'disabled' - turned off completely
      expect(result.features['beta.experimental']).toBe('hidden');
      
      // 'coming_soon' - visible but not available
      expect(result.features['sponsors.management']).toBe('coming_soon');
      expect(result.features['beta.newUI']).toBe('coming_soon');
      
      // 'hidden' - completely invisible
      expect(result.features['beta.experimental']).toBe('hidden');
    });
  });
});