/// Exception levée lorsque la configuration de l'environnement est invalide.
class ConfigurationException implements Exception {
  ConfigurationException(this.message);
  
  final String message;
  
  @override
  String toString() => 'ConfigurationException: $message';
}

/// Configuration centralisée de l'environnement de l'application.
///
/// Ce fichier gère toutes les variables d'environnement et secrets
/// de l'application de manière sécurisée. Les valeurs peuvent être
/// définies au moment du build via des variables d'environnement.
///
/// **Usage en développement:**
/// ```dart
/// final apiUrl = EnvConfig.apiBaseUrl; // Utilise la valeur par défaut
/// ```
///
/// **Usage en production:**
/// ```bash
/// flutter build apk --dart-define=API_BASE_URL=https://api.example.com
/// ```
///
/// **Validation:**
/// ```dart
/// // Valider au démarrage de l'application
/// EnvConfig.validate(throwOnError: true);
/// ```
class EnvConfig {
  /// Constructeur privé pour empêcher l'instanciation
  EnvConfig._();

  // ============================================================================
  // CONFIGURATION API
  // ============================================================================

  /// URL de base de l'API backend.
  ///
  /// Cette valeur peut être définie au moment du build avec:
  /// `--dart-define=API_BASE_URL=https://api.example.com`
  ///
  /// **Valeur par défaut:** `http://192.168.1.145:8080` (développement)
  static const String apiBaseUrl = String.fromEnvironment(
    'API_BASE_URL',
    defaultValue: 'http://192.168.1.145:8080',
  );

  /// Timeout pour les requêtes réseau (en secondes).
  ///
  /// **Valeur par défaut:** 30 secondes
  static const int networkTimeout = int.fromEnvironment(
    'NETWORK_TIMEOUT',
    defaultValue: 30,
  );

  // ============================================================================
  // ENVIRONNEMENT
  // ============================================================================

  /// Environnement actuel de l'application.
  ///
  /// Valeurs possibles: `development`, `staging`, `production`
  ///
  /// **Valeur par défaut:** `development`
  static const String environment = String.fromEnvironment(
    'ENVIRONMENT',
    defaultValue: 'development',
  );

  /// Vérifie si l'environnement est en production.
  ///
  /// Returns `true` si l'environnement est `production`, `false` sinon.
  static bool get isProduction => environment == 'production';

  /// Vérifie si l'environnement est en développement.
  ///
  /// Returns `true` si l'environnement est `development`, `false` sinon.
  static bool get isDevelopment => environment == 'development';

  /// Vérifie si l'environnement est en staging.
  ///
  /// Returns `true` si l'environnement est `staging`, `false` sinon.
  static bool get isStaging => environment == 'staging';

  // ============================================================================
  // CONFIGURATION DEBUG
  // ============================================================================

  /// Mode debug activé.
  ///
  /// Quand activé, des logs supplémentaires sont affichés et certaines
  /// fonctionnalités de débogage sont disponibles.
  ///
  /// **Valeur par défaut:** `true`
  static const bool isDebugMode = bool.fromEnvironment(
    'DEBUG_MODE',
    defaultValue: true,
  );

  /// Active les logs détaillés.
  ///
  /// **Valeur par défaut:** `true` en développement, `false` en production
  static bool get enableDetailedLogs => isDevelopment || isDebugMode;

  // ============================================================================
  // SERVICES EXTERNES
  // ============================================================================

  /// Clé API Google Maps (si nécessaire).
  ///
  /// Cette valeur doit être définie au moment du build avec:
  /// `--dart-define=GOOGLE_MAPS_API_KEY=your_api_key`
  ///
  /// **Note:** Ne jamais commiter cette clé dans le code source.
  static const String googleMapsApiKey = String.fromEnvironment(
    'GOOGLE_MAPS_API_KEY',
  );

  // ============================================================================
  // MÉTHODES UTILITAIRES
  // ============================================================================

  /// Valide que la configuration est correcte.
  ///
  /// Cette méthode vérifie que toutes les valeurs requises sont définies
  /// et valides pour l'environnement actuel.
  ///
  /// Throws [ConfigurationException] si la validation échoue en production.
  /// Returns `true` si la configuration est valide, `false` sinon en développement.
  ///
  /// **Validations effectuées:**
  /// - URL API non vide et format valide
  /// - HTTPS obligatoire en production
  /// - Clés API requises en production
  /// - Timeout réseau valide (> 0)
  static bool validate({bool throwOnError = false}) {
    final errors = <String>[];

    // Validation de l'URL API
    if (apiBaseUrl.isEmpty) {
      errors.add('API_BASE_URL ne peut pas être vide');
    } else {
      try {
        final uri = Uri.parse(apiBaseUrl);
        if (!uri.hasScheme || (!uri.scheme.startsWith('http'))) {
          errors.add('API_BASE_URL doit être une URL HTTP/HTTPS valide');
        }
      } catch (e) {
        errors.add('API_BASE_URL n\'est pas une URL valide: $e');
      }
    }

    // Validation HTTPS en production
    if (isProduction && !apiBaseUrl.startsWith('https://')) {
      errors.add('API_BASE_URL doit utiliser HTTPS en production');
    }

    // Validation du timeout réseau
    if (networkTimeout <= 0) {
      errors.add('NETWORK_TIMEOUT doit être supérieur à 0');
    }

    // Validation des clés API en production (si nécessaire)
    if (isProduction) {
      // Google Maps API Key est optionnelle mais recommandée si on utilise Google Maps
      // On ne force pas car elle peut ne pas être nécessaire selon les fonctionnalités
    }

    // Si des erreurs sont trouvées
    if (errors.isNotEmpty) {
      final errorMessage = 'Erreurs de configuration:\n${errors.join('\n')}';
      
      if (throwOnError || isProduction) {
        throw ConfigurationException(errorMessage);
      }
      
      // En développement, on log juste les erreurs
      if (isDevelopment) {
        // Utiliser print car AppLogger pourrait ne pas être initialisé
        print('[EnvConfig] ⚠️ $errorMessage');
      }
      
      return false;
    }

    return true;
  }

  /// Retourne un résumé de la configuration actuelle.
  ///
  /// Cette méthode est utile pour le débogage et les logs.
  ///
  /// **Note:** Les valeurs sensibles (comme les clés API) ne sont pas incluses.
  ///
  /// Returns une chaîne décrivant la configuration actuelle.
  static String getConfigSummary() {
    return '''
Environment: $environment
API Base URL: $apiBaseUrl
Network Timeout: ${networkTimeout}s
Debug Mode: $isDebugMode
Google Maps API Key: ${googleMapsApiKey.isNotEmpty ? '***configured***' : 'not configured'}
''';
  }
}

