package dev.lions.unionflow.client.service;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.Validator;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

@ApplicationScoped
public class ValidationService {
    
    @Inject
    Validator validator;
    
    /**
     * Valide un objet et retourne la liste des erreurs
     */
    public <T> ValidationResult validate(T object) {
        Set<ConstraintViolation<T>> violations = validator.validate(object);
        
        ValidationResult result = new ValidationResult();
        result.setValid(violations.isEmpty());
        
        List<String> messages = new ArrayList<>();
        for (ConstraintViolation<T> violation : violations) {
            messages.add(violation.getPropertyPath() + ": " + violation.getMessage());
        }
        result.setErrorMessages(messages);
        
        return result;
    }
    
    /**
     * Valide une propriété spécifique d'un objet
     */
    public <T> ValidationResult validateProperty(T object, String propertyName) {
        Set<ConstraintViolation<T>> violations = validator.validateProperty(object, propertyName);
        
        ValidationResult result = new ValidationResult();
        result.setValid(violations.isEmpty());
        
        List<String> messages = new ArrayList<>();
        for (ConstraintViolation<T> violation : violations) {
            messages.add(violation.getMessage());
        }
        result.setErrorMessages(messages);
        
        return result;
    }
    
    /**
     * Valide une valeur contre les contraintes d'une propriété
     */
    public <T> ValidationResult validateValue(Class<T> beanType, String propertyName, Object value) {
        Set<ConstraintViolation<T>> violations = validator.validateValue(beanType, propertyName, value);
        
        ValidationResult result = new ValidationResult();
        result.setValid(violations.isEmpty());
        
        List<String> messages = new ArrayList<>();
        for (ConstraintViolation<T> violation : violations) {
            messages.add(violation.getMessage());
        }
        result.setErrorMessages(messages);
        
        return result;
    }
    
    /**
     * Classe pour encapsuler le résultat de validation
     */
    public static class ValidationResult {
        private boolean valid;
        private List<String> errorMessages = new ArrayList<>();
        
        public boolean isValid() {
            return valid;
        }
        
        public void setValid(boolean valid) {
            this.valid = valid;
        }
        
        public List<String> getErrorMessages() {
            return errorMessages;
        }
        
        public void setErrorMessages(List<String> errorMessages) {
            this.errorMessages = errorMessages;
        }
        
        public String getFirstErrorMessage() {
            return errorMessages.isEmpty() ? null : errorMessages.get(0);
        }
        
        public String getAllErrorMessages() {
            return String.join(", ", errorMessages);
        }
    }
}