"""
Validateur de configuration pour le SDK
"""
from typing import Dict, Any, List, Union


class ConfigValidator:
    """Validateur pour les configurations du SDK Lescopr"""
    
    # Champs obligatoires
    REQUIRED_FIELDS = {'api_key', 'sdk_key', 'environment'}
    
    # Environnements valides
    VALID_ENVIRONMENTS = {'development', 'production', 'staging'}
    
    # Champs optionnels
    OPTIONAL_FIELDS = {'sdk_id', 'project_name', 'project_stack', 'project_root'}
    
    def validate(self, config: Dict[str, Any]) -> bool:
        """
        Valide une configuration complète
        
        Args:
            config: Configuration à valider
            
        Returns:
            True si la configuration est valide, False sinon
        """
        if not isinstance(config, dict):
            return False
        
        # Vérifier les champs requis
        for field in self.REQUIRED_FIELDS:
            if not self._validate_required_field(config, field):
                return False
        
        # Valider l'environnement
        if not self._validate_environment(config.get('environment')):
            return False
        
        # Valider les clés
        if not self._validate_api_key(config.get('api_key')):
            return False
        
        if not self._validate_sdk_key(config.get('sdk_key')):
            return False
        
        # Valider les champs optionnels s'ils sont présents
        return self._validate_optional_fields(config)
    
    def validate_partial(self, config: Dict[str, Any], required_fields: List[str] = None) -> bool:
        """
        Valide une configuration partielle
        
        Args:
            config: Configuration à valider
            required_fields: Liste des champs requis pour cette validation
            
        Returns:
            True si la configuration partielle est valide
        """
        if not isinstance(config, dict):
            return False
        
        fields_to_check = required_fields or self.REQUIRED_FIELDS
        
        for field in fields_to_check:
            if field in config and not self._validate_field_value(field, config[field]):
                return False
        
        return True
    
    def get_validation_errors(self, config: Dict[str, Any]) -> List[str]:
        """
        Retourne la liste détaillée des erreurs de validation
        
        Args:
            config: Configuration à valider
            
        Returns:
            Liste des erreurs trouvées
        """
        errors = []
        
        if not isinstance(config, dict):
            errors.append("La configuration doit être un dictionnaire")
            return errors
        
        # Vérifier les champs requis
        for field in self.REQUIRED_FIELDS:
            if field not in config:
                errors.append(f"Champ requis manquant: {field}")
            elif not self._validate_field_value(field, config[field]):
                errors.append(f"Valeur invalide pour le champ: {field}")
        
        # Vérifier l'environnement
        if 'environment' in config:
            if not self._validate_environment(config['environment']):
                valid_envs = ', '.join(self.VALID_ENVIRONMENTS)
                errors.append(f"Environnement invalide. Valeurs acceptées: {valid_envs}")
        
        # Vérifier les clés
        if 'api_key' in config and not self._validate_api_key(config['api_key']):
            errors.append("Format de clé API invalide (doit commencer par 'lsk_api_')")
        
        if 'sdk_key' in config and not self._validate_sdk_key(config['sdk_key']):
            errors.append("Format de clé SDK invalide (doit commencer par 'lsk_')")
        
        return errors
    
    def _validate_required_field(self, config: Dict[str, Any], field: str) -> bool:
        """Valide la présence et la valeur d'un champ requis"""
        if field not in config:
            return False
        
        return self._validate_field_value(field, config[field])
    
    def _validate_field_value(self, field: str, value: Any) -> bool:
        """Valide la valeur d'un champ spécifique"""
        if not isinstance(value, str) or not value.strip():
            return False
        
        # Validations spécifiques par champ
        if field == 'environment':
            return self._validate_environment(value)
        elif field == 'api_key':
            return self._validate_api_key(value)
        elif field == 'sdk_key':
            return self._validate_sdk_key(value)
        
        return True
    
    def _validate_environment(self, environment: str) -> bool:
        """Valide l'environnement"""
        if not isinstance(environment, str):
            return False
        return environment.lower() in self.VALID_ENVIRONMENTS
    
    def _validate_api_key(self, api_key: str) -> bool:
        """Valide le format de la clé API"""
        if not isinstance(api_key, str):
            return False
        return (
            api_key.startswith('lsk_api_') and 
            len(api_key) > 15 and 
            api_key.replace('lsk_api_', '').replace('_', '').isalnum()
        )
    
    def _validate_sdk_key(self, sdk_key: str) -> bool:
        """Valide le format de la clé SDK"""
        if not isinstance(sdk_key, str):
            return False
        return (
            sdk_key.startswith('lsk_') and 
            len(sdk_key) > 10 and 
            sdk_key.replace('lsk_', '').replace('_', '').replace('-', '').isalnum()
        )
    
    def _validate_optional_fields(self, config: Dict[str, Any]) -> bool:
        """Valide les champs optionnels s'ils sont présents"""
        for field in self.OPTIONAL_FIELDS:
            if field in config:
                value = config[field]
                
                if field == 'project_stack' and not isinstance(value, list):
                    return False
                elif field in ['sdk_id', 'project_name', 'project_root']:
                    if not isinstance(value, str) or not value.strip():
                        return False
        
        return True