package dev.lions.unionflow.client.view;

import dev.lions.unionflow.client.dto.EvenementDTO;
import dev.lions.unionflow.client.service.EvenementService;
import jakarta.annotation.PostConstruct;
import jakarta.enterprise.context.SessionScoped;
import jakarta.faces.application.FacesMessage;
import jakarta.faces.context.FacesContext;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import org.eclipse.microprofile.rest.client.inject.RestClient;
import org.primefaces.event.SelectEvent;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.logging.Logger;
import java.util.stream.Collectors;

/**
 * Bean JSF pour la gestion des événements
 * Refactorisé pour utiliser directement EvenementDTO et se connecter au backend
 * 
 * @author UnionFlow Team
 * @version 2.0
 */
@Named("evenementsBean")
@SessionScoped
public class EvenementsBean implements Serializable {
    
    private static final long serialVersionUID = 1L;
    private static final Logger LOGGER = Logger.getLogger(EvenementsBean.class.getName());
    
    @Inject
    @RestClient
    private EvenementService evenementService;
    
    @Inject
    private UserSession userSession;
    
    // Date sélectionnée dans le calendrier
    private LocalDate dateSelectionnee;
    
    // Données principales - Utilisation directe de EvenementDTO
    private List<EvenementDTO> tousLesEvenements;
    private List<EvenementDTO> evenementsFiltres;
    private List<EvenementDTO> evenementsSelectionnes;
    private List<EvenementDTO> evenementsProchains;
    private EvenementDTO evenementSelectionne;
    
    // Formulaire nouveau événement
    private EvenementDTO nouvelEvenement;
    
    // Filtres
    private FiltresEvenement filtres;
    
    // Statistiques
    private StatistiquesEvenements statistiques;
    
    @PostConstruct
    public void init() {
        LOGGER.info("Initialisation de EvenementsBean");
        initializeFiltres();
        initializeNouvelEvenement();
        chargerEvenements();
        chargerEvenementsProchains();
        chargerStatistiques();
    }
    
    private void initializeFiltres() {
        filtres = new FiltresEvenement();
        evenementsSelectionnes = new ArrayList<>();
    }
    
    private void initializeNouvelEvenement() {
        nouvelEvenement = new EvenementDTO();
        nouvelEvenement.setPriorite("NORMALE");
        nouvelEvenement.setStatut("PLANIFIE");
        nouvelEvenement.setDateDebut(LocalDate.now().plusWeeks(1));
        nouvelEvenement.setHeureDebut(LocalTime.of(9, 0));
        nouvelEvenement.setHeureFin(LocalTime.of(17, 0));
        nouvelEvenement.setCodeDevise("XOF");
        nouvelEvenement.setEvenementPublic(true);
        nouvelEvenement.setInscriptionObligatoire(false);
    }
    
    /**
     * Méthode publique pour réinitialiser le formulaire
     */
    public void reinitialiserFormulaire() {
        initializeNouvelEvenement();
    }
    
    /**
     * Charge tous les événements depuis le backend
     */
    public void chargerEvenements() {
        try {
            LOGGER.info("Chargement des événements depuis le backend");
            Map<String, Object> response = evenementService.listerTous(0, 1000, "dateDebut", "asc");
            
            tousLesEvenements = new ArrayList<>();
            
            // Le backend peut retourner soit une liste de DTOs, soit une Map avec "data"
            if (response.containsKey("data")) {
                @SuppressWarnings("unchecked")
                List<Object> data = (List<Object>) response.get("data");
                
                if (data != null) {
                    for (Object item : data) {
                        if (item instanceof EvenementDTO) {
                            tousLesEvenements.add((EvenementDTO) item);
                        } else if (item instanceof Map) {
                            @SuppressWarnings("unchecked")
                            EvenementDTO dto = convertMapToDTO((Map<String, Object>) item);
                            tousLesEvenements.add(dto);
                        }
                    }
                }
            } else {
                // Si la réponse est directement une liste
                @SuppressWarnings("unchecked")
                List<Object> data = (List<Object>) response.get("evenements");
                if (data != null) {
                    for (Object item : data) {
                        if (item instanceof EvenementDTO) {
                            tousLesEvenements.add((EvenementDTO) item);
                        } else if (item instanceof Map) {
                            @SuppressWarnings("unchecked")
                            EvenementDTO dto = convertMapToDTO((Map<String, Object>) item);
                            tousLesEvenements.add(dto);
                        }
                    }
                }
            }
            
            appliquerFiltres();
            LOGGER.info("Événements chargés: " + tousLesEvenements.size());
            
        } catch (Exception e) {
            LOGGER.severe("Erreur lors du chargement des événements: " + e.getMessage());
            e.printStackTrace();
            tousLesEvenements = new ArrayList<>();
            ajouterMessage(FacesMessage.SEVERITY_ERROR, "Erreur", 
                "Erreur lors du chargement des événements: " + e.getMessage());
        }
    }
    
    /**
     * Charge les événements à venir
     */
    public void chargerEvenementsProchains() {
        try {
            LOGGER.info("Chargement des événements à venir");
            Map<String, Object> response = evenementService.listerAVenir(0, 6);
            
            @SuppressWarnings("unchecked")
            List<Map<String, Object>> data = (List<Map<String, Object>>) response.get("data");
            
            if (data != null) {
                evenementsProchains = data.stream()
                    .map(this::convertMapToDTO)
                    .collect(Collectors.toList());
            } else {
                evenementsProchains = new ArrayList<>();
            }
            
        } catch (Exception e) {
            LOGGER.severe("Erreur lors du chargement des événements à venir: " + e.getMessage());
            evenementsProchains = new ArrayList<>();
        }
    }
    
    /**
     * Charge les statistiques depuis le backend
     */
    public void chargerStatistiques() {
        try {
            LOGGER.info("Chargement des statistiques");
            Map<String, Object> countResponse = evenementService.compter();
            
            statistiques = new StatistiquesEvenements();
            
            // Calculer les statistiques depuis les événements chargés
            if (tousLesEvenements != null && !tousLesEvenements.isEmpty()) {
                statistiques.setTotalEvenements(tousLesEvenements.size());
                
                long actifs = tousLesEvenements.stream()
                    .filter(e -> "PLANIFIE".equals(e.getStatut()) || 
                                "CONFIRME".equals(e.getStatut()) || 
                                "EN_COURS".equals(e.getStatut()))
                    .count();
                statistiques.setEvenementsActifs((int) actifs);
                
                int totalParticipants = tousLesEvenements.stream()
                    .mapToInt(e -> e.getParticipantsInscrits() != null ? e.getParticipantsInscrits() : 0)
                    .sum();
                statistiques.setParticipantsTotal(totalParticipants);
                
                BigDecimal totalBudget = tousLesEvenements.stream()
                    .map(e -> e.getBudget() != null ? e.getBudget() : BigDecimal.ZERO)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
                statistiques.setBudgetTotal(String.format("%,.0f FCFA", totalBudget.doubleValue()));
                
                double moyenne = (double) totalParticipants / tousLesEvenements.size();
                statistiques.setMoyenneParticipants((int) moyenne);
            } else {
                statistiques.setTotalEvenements(0);
                statistiques.setEvenementsActifs(0);
                statistiques.setParticipantsTotal(0);
                statistiques.setBudgetTotal("0 FCFA");
                statistiques.setMoyenneParticipants(0);
            }
            
        } catch (Exception e) {
            LOGGER.severe("Erreur lors du chargement des statistiques: " + e.getMessage());
            statistiques = new StatistiquesEvenements();
            statistiques.setTotalEvenements(0);
            statistiques.setEvenementsActifs(0);
            statistiques.setParticipantsTotal(0);
            statistiques.setBudgetTotal("0 FCFA");
            statistiques.setMoyenneParticipants(0);
        }
    }
    
    /**
     * Convertit une Map en EvenementDTO
     */
    private EvenementDTO convertMapToDTO(Map<String, Object> map) {
        EvenementDTO dto = new EvenementDTO();
        
        try {
            if (map.get("id") != null) {
                if (map.get("id") instanceof UUID) {
                    dto.setId((UUID) map.get("id"));
                } else {
                    dto.setId(UUID.fromString(map.get("id").toString()));
                }
            }
            
            if (map.get("titre") != null) dto.setTitre(map.get("titre").toString());
            if (map.get("description") != null) dto.setDescription(map.get("description").toString());
            
            // Type d'événement - peut être un enum ou une String
            if (map.get("typeEvenement") != null) {
                Object type = map.get("typeEvenement");
                dto.setTypeEvenement(type instanceof Enum ? type.toString() : type.toString());
            }
            
            // Statut - peut être un enum ou une String
            if (map.get("statut") != null) {
                Object statut = map.get("statut");
                dto.setStatut(statut instanceof Enum ? statut.toString() : statut.toString());
            }
            
            // Priorité - peut être un enum ou une String
            if (map.get("priorite") != null) {
                Object priorite = map.get("priorite");
                dto.setPriorite(priorite instanceof Enum ? priorite.toString() : priorite.toString());
            }
            
            if (map.get("lieu") != null) dto.setLieu(map.get("lieu").toString());
            if (map.get("adresse") != null) dto.setAdresse(map.get("adresse").toString());
            if (map.get("ville") != null) dto.setVille(map.get("ville").toString());
            if (map.get("region") != null) dto.setRegion(map.get("region").toString());
            if (map.get("organisateur") != null) dto.setOrganisateur(map.get("organisateur").toString());
            if (map.get("emailOrganisateur") != null) dto.setEmailOrganisateur(map.get("emailOrganisateur").toString());
            if (map.get("telephoneOrganisateur") != null) dto.setTelephoneOrganisateur(map.get("telephoneOrganisateur").toString());
            
            // Conversion des nombres
            if (map.get("capaciteMax") != null) {
                Object cap = map.get("capaciteMax");
                if (cap instanceof Number) {
                    dto.setCapaciteMax(((Number) cap).intValue());
                } else {
                    dto.setCapaciteMax(Integer.parseInt(cap.toString()));
                }
            }
            
            if (map.get("participantsInscrits") != null) {
                Object part = map.get("participantsInscrits");
                if (part instanceof Number) {
                    dto.setParticipantsInscrits(((Number) part).intValue());
                } else {
                    dto.setParticipantsInscrits(Integer.parseInt(part.toString()));
                }
            }
            
            if (map.get("participantsPresents") != null) {
                Object part = map.get("participantsPresents");
                if (part instanceof Number) {
                    dto.setParticipantsPresents(((Number) part).intValue());
                } else {
                    dto.setParticipantsPresents(Integer.parseInt(part.toString()));
                }
            }
            
            // Conversion des BigDecimal
            if (map.get("budget") != null) {
                Object budget = map.get("budget");
                if (budget instanceof BigDecimal) {
                    dto.setBudget((BigDecimal) budget);
                } else if (budget instanceof Number) {
                    dto.setBudget(BigDecimal.valueOf(((Number) budget).doubleValue()));
                } else {
                    dto.setBudget(new BigDecimal(budget.toString()));
                }
            }
            
            if (map.get("coutReel") != null) {
                Object cout = map.get("coutReel");
                if (cout instanceof BigDecimal) {
                    dto.setCoutReel((BigDecimal) cout);
                } else if (cout instanceof Number) {
                    dto.setCoutReel(BigDecimal.valueOf(((Number) cout).doubleValue()));
                } else {
                    dto.setCoutReel(new BigDecimal(cout.toString()));
                }
            }
            
            if (map.get("codeDevise") != null) dto.setCodeDevise(map.get("codeDevise").toString());
            
            // Conversion des dates
            if (map.get("dateDebut") != null) {
                Object date = map.get("dateDebut");
                if (date instanceof LocalDate) {
                    dto.setDateDebut((LocalDate) date);
                } else if (date instanceof String) {
                    dto.setDateDebut(LocalDate.parse(date.toString()));
                }
            }
            
            if (map.get("dateFin") != null) {
                Object date = map.get("dateFin");
                if (date instanceof LocalDate) {
                    dto.setDateFin((LocalDate) date);
                } else if (date instanceof String) {
                    dto.setDateFin(LocalDate.parse(date.toString()));
                }
            }
            
            // Conversion des heures
            if (map.get("heureDebut") != null) {
                Object heure = map.get("heureDebut");
                if (heure instanceof LocalTime) {
                    dto.setHeureDebut((LocalTime) heure);
                } else if (heure instanceof String) {
                    dto.setHeureDebut(LocalTime.parse(heure.toString()));
                }
            }
            
            if (map.get("heureFin") != null) {
                Object heure = map.get("heureFin");
                if (heure instanceof LocalTime) {
                    dto.setHeureFin((LocalTime) heure);
                } else if (heure instanceof String) {
                    dto.setHeureFin(LocalTime.parse(heure.toString()));
                }
            }
            
            // Association
            if (map.get("associationId") != null) {
                Object assocId = map.get("associationId");
                if (assocId instanceof UUID) {
                    dto.setAssociationId((UUID) assocId);
                } else {
                    dto.setAssociationId(UUID.fromString(assocId.toString()));
                }
            }
            
            if (map.get("nomAssociation") != null) dto.setNomAssociation(map.get("nomAssociation").toString());
            
            // Options booléennes
            if (map.get("inscriptionObligatoire") != null) {
                Object insc = map.get("inscriptionObligatoire");
                dto.setInscriptionObligatoire(insc instanceof Boolean ? (Boolean) insc : Boolean.parseBoolean(insc.toString()));
            }
            
            if (map.get("evenementPublic") != null) {
                Object pub = map.get("evenementPublic");
                dto.setEvenementPublic(pub instanceof Boolean ? (Boolean) pub : Boolean.parseBoolean(pub.toString()));
            }
            
        } catch (Exception e) {
            LOGGER.warning("Erreur lors de la conversion Map vers DTO: " + e.getMessage());
        }
        
        return dto;
    }
    
    /**
     * Applique les filtres sur les événements
     */
    public void appliquerFiltres() {
        if (tousLesEvenements == null) {
            evenementsFiltres = new ArrayList<>();
            return;
        }
        
        evenementsFiltres = tousLesEvenements.stream()
            .filter(this::appliquerFiltre)
            .collect(Collectors.toList());
    }
    
    private boolean appliquerFiltre(EvenementDTO evenement) {
        if (filtres == null) return true;
        
        if (filtres.getTitre() != null && !filtres.getTitre().trim().isEmpty()) {
            if (evenement.getTitre() == null || 
                !evenement.getTitre().toLowerCase().contains(filtres.getTitre().toLowerCase())) {
                return false;
            }
        }
        
        if (filtres.getType() != null && !filtres.getType().trim().isEmpty()) {
            if (!filtres.getType().equals(evenement.getTypeEvenement())) {
                return false;
            }
        }
        
        if (filtres.getStatut() != null && !filtres.getStatut().trim().isEmpty()) {
            if (!filtres.getStatut().equals(evenement.getStatut())) {
                return false;
            }
        }
        
        if (filtres.getOrganisateur() != null && !filtres.getOrganisateur().trim().isEmpty()) {
            if (evenement.getOrganisateur() == null || 
                !evenement.getOrganisateur().toLowerCase().contains(filtres.getOrganisateur().toLowerCase())) {
                return false;
            }
        }
        
        if (filtres.getPriorite() != null && !filtres.getPriorite().trim().isEmpty()) {
            if (!filtres.getPriorite().equals(evenement.getPriorite())) {
                return false;
            }
        }
        
        if (filtres.getDateDebut() != null && evenement.getDateDebut() != null) {
            if (evenement.getDateDebut().isBefore(filtres.getDateDebut())) {
                return false;
            }
        }
        
        if (filtres.getDateFin() != null && evenement.getDateDebut() != null) {
            if (evenement.getDateDebut().isAfter(filtres.getDateFin())) {
                return false;
            }
        }
        
        return true;
    }
    
    /**
     * Recherche d'événements
     */
    public void rechercher() {
        appliquerFiltres();
    }
    
    /**
     * Réinitialise les filtres
     */
    public void reinitialiserFiltres() {
        filtres = new FiltresEvenement();
        appliquerFiltres();
    }
    
    /**
     * Crée un nouvel événement
     */
    public void creerEvenement() {
        try {
            LOGGER.info("Création d'un nouvel événement: " + nouvelEvenement.getTitre());
            
            EvenementDTO evenementCree = evenementService.creer(nouvelEvenement);
            
            // Recharger les événements
            chargerEvenements();
            chargerEvenementsProchains();
            chargerStatistiques();
            
            // Réinitialiser le formulaire
            initializeNouvelEvenement();
            
            ajouterMessage(FacesMessage.SEVERITY_INFO, "Succès", 
                "Événement créé avec succès");
            
        } catch (Exception e) {
            LOGGER.severe("Erreur lors de la création de l'événement: " + e.getMessage());
            e.printStackTrace();
            ajouterMessage(FacesMessage.SEVERITY_ERROR, "Erreur", 
                "Erreur lors de la création de l'événement: " + e.getMessage());
        }
    }
    
    /**
     * Modifie un événement existant
     */
    public void modifierEvenement() {
        try {
            if (evenementSelectionne == null || evenementSelectionne.getId() == null) {
                ajouterMessage(FacesMessage.SEVERITY_WARN, "Attention", 
                    "Aucun événement sélectionné");
                return;
            }
            
            LOGGER.info("Modification de l'événement: " + evenementSelectionne.getId());
            
            EvenementDTO evenementModifie = evenementService.modifier(
                evenementSelectionne.getId(), evenementSelectionne);
            
            // Recharger les événements
            chargerEvenements();
            chargerEvenementsProchains();
            chargerStatistiques();
            
            ajouterMessage(FacesMessage.SEVERITY_INFO, "Succès", 
                "Événement modifié avec succès");
            
        } catch (Exception e) {
            LOGGER.severe("Erreur lors de la modification: " + e.getMessage());
            ajouterMessage(FacesMessage.SEVERITY_ERROR, "Erreur", 
                "Erreur lors de la modification: " + e.getMessage());
        }
    }
    
    /**
     * Supprime un événement
     */
    public void supprimerEvenement() {
        try {
            if (evenementSelectionne == null || evenementSelectionne.getId() == null) {
                ajouterMessage(FacesMessage.SEVERITY_WARN, "Attention", 
                    "Aucun événement sélectionné");
                return;
            }
            
            LOGGER.info("Suppression de l'événement: " + evenementSelectionne.getId());
            
            evenementService.supprimer(evenementSelectionne.getId());
            
            // Recharger les événements
            chargerEvenements();
            chargerEvenementsProchains();
            chargerStatistiques();
            
            evenementSelectionne = null;
            
            ajouterMessage(FacesMessage.SEVERITY_INFO, "Succès", 
                "Événement supprimé avec succès");
            
        } catch (Exception e) {
            LOGGER.severe("Erreur lors de la suppression: " + e.getMessage());
            ajouterMessage(FacesMessage.SEVERITY_ERROR, "Erreur", 
                "Erreur lors de la suppression: " + e.getMessage());
        }
    }
    
    /**
     * Annule un événement
     */
    public void annulerEvenement() {
        try {
            if (evenementSelectionne == null || evenementSelectionne.getId() == null) {
                ajouterMessage(FacesMessage.SEVERITY_WARN, "Attention", 
                    "Aucun événement sélectionné");
                return;
            }
            
            evenementSelectionne.setStatut("ANNULE");
            modifierEvenement();
            
        } catch (Exception e) {
            LOGGER.severe("Erreur lors de l'annulation: " + e.getMessage());
            ajouterMessage(FacesMessage.SEVERITY_ERROR, "Erreur", 
                "Erreur lors de l'annulation: " + e.getMessage());
        }
    }
    
    /**
     * Sélectionne un événement
     */
    public void selectionnerEvenement(EvenementDTO evenement) {
        this.evenementSelectionne = evenement;
    }
    
    /**
     * Actualise les données
     */
    public void actualiser() {
        chargerEvenements();
        chargerEvenementsProchains();
        chargerStatistiques();
    }
    
    /**
     * Inscrit le membre actuel à un événement
     */
    public void sinscrireEvenement(EvenementDTO evenement) {
        try {
            if (evenement == null || evenement.getId() == null) {
                ajouterMessage(FacesMessage.SEVERITY_WARN, "Attention", "Événement invalide");
                return;
            }
            
            // Vérifier la capacité avec les méthodes existantes de EvenementDTO
            if (evenement.isComplet()) {
                ajouterMessage(FacesMessage.SEVERITY_WARN, "Complet", 
                    "Cet événement est complet");
                return;
            }
            
            LOGGER.info("Inscription à l'événement: " + evenement.getId());
            
            // Créer un participant pour l'utilisateur courant
            UUID userId = userSession.getCurrentUser() != null ? userSession.getCurrentUser().getId() : null;
            if (userId == null) {
                ajouterMessage(FacesMessage.SEVERITY_ERROR, "Erreur", 
                    "Vous devez être connecté pour vous inscrire");
                return;
            }
            
            // Appeler le service backend pour l'inscription
            evenementService.inscrireParticipant(evenement.getId(), userId);
            
            // Mettre à jour le nombre d'inscrits localement
            Integer inscrits = evenement.getParticipantsInscrits();
            evenement.setParticipantsInscrits(inscrits != null ? inscrits + 1 : 1);
            
            ajouterMessage(FacesMessage.SEVERITY_INFO, "Succès", 
                "Inscription à l'événement enregistrée");
            
            // Actualiser les données
            chargerEvenements();
        } catch (Exception e) {
            LOGGER.severe("Erreur lors de l'inscription: " + e.getMessage());
            ajouterMessage(FacesMessage.SEVERITY_ERROR, "Erreur", 
                "Erreur lors de l'inscription: " + e.getMessage());
        }
    }
    
    /**
     * Handlers pour le calendrier PrimeFaces Schedule
     */
    public void onDateSelect(SelectEvent<Date> event) {
        if (event != null && event.getObject() != null) {
            Date date = event.getObject();
            this.dateSelectionnee = date.toInstant()
                .atZone(ZoneId.systemDefault())
                .toLocalDate();
            
            // Préparer un nouvel événement à cette date
            this.nouvelEvenement = new EvenementDTO();
            this.nouvelEvenement.setDateDebut(dateSelectionnee);
            this.nouvelEvenement.setDateFin(dateSelectionnee);
            this.nouvelEvenement.setHeureDebut(LocalTime.of(9, 0));
            this.nouvelEvenement.setHeureFin(LocalTime.of(18, 0));
            
            LOGGER.info("Date sélectionnée: " + dateSelectionnee);
        }
    }
    
    public void onEventSelect(SelectEvent<Object> event) {
        if (event != null && event.getObject() != null) {
            try {
                // Récupérer l'événement sélectionné depuis le ScheduleModel
                Object eventObject = event.getObject();
                
                // Essayer de trouver l'événement correspondant
                if (eventObject instanceof org.primefaces.model.ScheduleEvent) {
                    org.primefaces.model.ScheduleEvent<?> scheduleEvent = 
                        (org.primefaces.model.ScheduleEvent<?>) eventObject;
                    String eventId = scheduleEvent.getId();
                    
                    if (eventId != null) {
                        // Chercher dans la liste des événements
                        for (EvenementDTO evt : tousLesEvenements) {
                            if (evt.getId() != null && evt.getId().toString().equals(eventId)) {
                                this.evenementSelectionne = evt;
                                LOGGER.info("Événement sélectionné: " + evt.getTitre());
                                break;
                            }
                        }
                    }
                }
            } catch (Exception e) {
                LOGGER.warning("Erreur sélection événement: " + e.getMessage());
            }
        }
    }
    
    public void onEventMove(Object event) {
        // Les modifications de date sont gérées par le backend lors de la sauvegarde
        // Cette méthode capture l'événement de déplacement mais la logique est simplifiée
        // car les classes ScheduleEntryMoveEvent ne sont pas disponibles
        LOGGER.info("Événement déplacé - actualisation nécessaire");
        ajouterMessage(FacesMessage.SEVERITY_INFO, "Info", 
            "Pour modifier les dates, veuillez éditer l'événement");
    }
    
    public void onEventResize(Object event) {
        // Les modifications de durée sont gérées par le backend lors de la sauvegarde
        // Cette méthode capture l'événement de redimensionnement mais la logique est simplifiée
        // car les classes ScheduleEntryResizeEvent ne sont pas disponibles
        LOGGER.info("Événement redimensionné - actualisation nécessaire");
        ajouterMessage(FacesMessage.SEVERITY_INFO, "Info", 
            "Pour modifier la durée, veuillez éditer l'événement");
    }
    
    // Getters/Setters pour les nouvelles propriétés
    public LocalDate getDateSelectionnee() { return dateSelectionnee; }
    public void setDateSelectionnee(LocalDate dateSelectionnee) { this.dateSelectionnee = dateSelectionnee; }
    
    // Méthodes utilitaires
    
    private void ajouterMessage(FacesMessage.Severity severity, String resume, String detail) {
        FacesContext.getCurrentInstance()
            .addMessage(null, new FacesMessage(severity, resume, detail));
    }
    
    // Getters et Setters
    
    public List<EvenementDTO> getTousLesEvenements() { return tousLesEvenements; }
    public void setTousLesEvenements(List<EvenementDTO> tousLesEvenements) { 
        this.tousLesEvenements = tousLesEvenements; 
    }
    
    public List<EvenementDTO> getEvenementsFiltres() { return evenementsFiltres; }
    public void setEvenementsFiltres(List<EvenementDTO> evenementsFiltres) { 
        this.evenementsFiltres = evenementsFiltres; 
    }
    
    public List<EvenementDTO> getEvenementsSelectionnes() { return evenementsSelectionnes; }
    public void setEvenementsSelectionnes(List<EvenementDTO> evenementsSelectionnes) { 
        this.evenementsSelectionnes = evenementsSelectionnes; 
    }
    
    public List<EvenementDTO> getEvenementsProchains() { return evenementsProchains; }
    public void setEvenementsProchains(List<EvenementDTO> evenementsProchains) { 
        this.evenementsProchains = evenementsProchains; 
    }
    
    public EvenementDTO getEvenementSelectionne() { return evenementSelectionne; }
    public void setEvenementSelectionne(EvenementDTO evenementSelectionne) { 
        this.evenementSelectionne = evenementSelectionne; 
    }
    
    public EvenementDTO getNouvelEvenement() { return nouvelEvenement; }
    public void setNouvelEvenement(EvenementDTO nouvelEvenement) { 
        this.nouvelEvenement = nouvelEvenement; 
    }
    
    public FiltresEvenement getFiltres() { return filtres; }
    public void setFiltres(FiltresEvenement filtres) { this.filtres = filtres; }
    
    public StatistiquesEvenements getStatistiques() { return statistiques; }
    public void setStatistiques(StatistiquesEvenements statistiques) { 
        this.statistiques = statistiques; 
    }
    
    // Classes internes pour les filtres et statistiques
    
    public static class FiltresEvenement implements Serializable {
        private static final long serialVersionUID = 1L;
        
        private String titre;
        private String type;
        private String statut;
        private String organisateur;
        private String priorite;
        private LocalDate dateDebut;
        private LocalDate dateFin;
        
        // Getters et setters
        public String getTitre() { return titre; }
        public void setTitre(String titre) { this.titre = titre; }
        
        public String getType() { return type; }
        public void setType(String type) { this.type = type; }
        
        public String getStatut() { return statut; }
        public void setStatut(String statut) { this.statut = statut; }
        
        public String getOrganisateur() { return organisateur; }
        public void setOrganisateur(String organisateur) { this.organisateur = organisateur; }
        
        public String getPriorite() { return priorite; }
        public void setPriorite(String priorite) { this.priorite = priorite; }
        
        public LocalDate getDateDebut() { return dateDebut; }
        public void setDateDebut(LocalDate dateDebut) { this.dateDebut = dateDebut; }
        
        public LocalDate getDateFin() { return dateFin; }
        public void setDateFin(LocalDate dateFin) { this.dateFin = dateFin; }
    }
    
    public static class StatistiquesEvenements implements Serializable {
        private static final long serialVersionUID = 1L;
        
        private int totalEvenements;
        private int evenementsActifs;
        private int participantsTotal;
        private String budgetTotal;
        private int moyenneParticipants;
        
        // Getters et setters
        public int getTotalEvenements() { return totalEvenements; }
        public void setTotalEvenements(int totalEvenements) { 
            this.totalEvenements = totalEvenements; 
        }
        
        public int getEvenementsActifs() { return evenementsActifs; }
        public void setEvenementsActifs(int evenementsActifs) { 
            this.evenementsActifs = evenementsActifs; 
        }
        
        public int getParticipantsTotal() { return participantsTotal; }
        public void setParticipantsTotal(int participantsTotal) { 
            this.participantsTotal = participantsTotal; 
        }
        
        public String getBudgetTotal() { return budgetTotal; }
        public void setBudgetTotal(String budgetTotal) { 
            this.budgetTotal = budgetTotal; 
        }
        
        public int getMoyenneParticipants() { return moyenneParticipants; }
        public void setMoyenneParticipants(int moyenneParticipants) { 
            this.moyenneParticipants = moyenneParticipants; 
        }
    }
}
