import {
    ConfigLoadResult,
    FeatureFlagConfig,
    FeatureState,
    FlattenedFeatures
} from './feature-types';
import { featureConfig } from './features.config';

/**
 * Default configuration path relative to project root
 */
const DEFAULT_CONFIG_PATH = 'apps/api/src/config/features.config.ts';

/**
 * Flattens nested feature configuration into a simple key-value map
 * 
 * Example:
 * Input: { sponsors: { portal: 'enabled' } }
 * Output: { 'sponsors.portal': 'enabled' }
 */
function flattenFeatures(
  config: Record<string, unknown>,
  prefix: string = ''
): FlattenedFeatures {
  const flattened: FlattenedFeatures = {};

  for (const [key, value] of Object.entries(config)) {
    const fullKey = prefix ? `${prefix}.${key}` : key;

    if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
      // Recursively flatten nested objects
      Object.assign(flattened, flattenFeatures(value as Record<string, unknown>, fullKey));
    } else if (isFeatureState(value)) {
      // Assign feature state
      flattened[fullKey] = value;
    }
  }

  return flattened;
}

/**
 * Type guard for FeatureState
 */
function isFeatureState(value: unknown): value is FeatureState {
  return (
    value === 'enabled' ||
    value === 'disabled' ||
    value === 'coming_soon' ||
    value === 'hidden'
  );
}

/**
 * Gets the current environment
 */
function getEnvironment(): string {
  return process.env.NODE_ENV || 'development';
}

/**
 * Validates that the environment exists in the config
 */
function validateEnvironment(
  env: string
): env is keyof FeatureFlagConfig {
  const validEnvs = ['development', 'test', 'staging', 'production'];
  if (!validEnvs.includes(env)) {
    throw new Error(
      `Invalid environment: "${env}". Valid environments: ${validEnvs.join(', ')}`
    );
  }
  return true;
}

/**
 * Loads feature configuration from the TypeScript config file
 */
export async function loadFeatureConfig(): Promise<ConfigLoadResult> {
  const env = getEnvironment();

  if (validateEnvironment(env)) {
    const envConfig = featureConfig[env];
    const flattened = flattenFeatures(envConfig);

    return {
      features: flattened,
      loadedFrom: 'config-file',
      configPath: DEFAULT_CONFIG_PATH,
    };
  }

  // Fallback to defaults
  return {
    features: {},
    loadedFrom: 'defaults',
  };
}

/**
 * Get a specific feature state
 */
export function getFeatureState(
  features: FlattenedFeatures,
  featurePath: string
): FeatureState {
  return features[featurePath] || 'disabled';
}

/**
 * Check if a feature is enabled
 */
export function isFeatureEnabled(
  features: FlattenedFeatures,
  featurePath: string
): boolean {
  return getFeatureState(features, featurePath) === 'enabled';
}

/**
 * Get all features for debugging
 */
export function getAllFeatures(): FlattenedFeatures {
  const env = getEnvironment();
  if (validateEnvironment(env)) {
    return flattenFeatures(featureConfig[env]);
  }
  return {};
}