package dev.lions.unionflow.client.view;

import dev.lions.unionflow.server.api.dto.evenement.response.EvenementResponse;
import dev.lions.unionflow.server.api.enums.evenement.PrioriteEvenement;
import dev.lions.unionflow.server.api.enums.evenement.StatutEvenement;
import dev.lions.unionflow.server.api.enums.evenement.TypeEvenementMetier;
import dev.lions.unionflow.client.service.EvenementService;
import jakarta.annotation.PostConstruct;
import jakarta.enterprise.context.SessionScoped;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import org.eclipse.microprofile.rest.client.inject.RestClient;
import org.jboss.logging.Logger;
import org.primefaces.event.SelectEvent;
import dev.lions.unionflow.client.service.ErrorHandlerService;
import dev.lions.unionflow.client.service.RetryService;
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.stream.Collectors;

/**
 * Bean JSF pour la gestion des événements
 * Refactorisé pour utiliser directement EvenementResponse 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 LOG = Logger.getLogger(EvenementsBean.class);
    
    @Inject
    @RestClient
    private EvenementService evenementService;
    
    @Inject
    private UserSession userSession;
    
    @Inject
    ErrorHandlerService errorHandler;
    
    @Inject
    RetryService retryService;
    
    // Date sélectionnée dans le calendrier
    private LocalDate dateSelectionnee;
    
    // Données principales - Utilisation directe de EvenementResponse
    private List<EvenementResponse> tousLesEvenements;
    private List<EvenementResponse> evenementsFiltres;
    private List<EvenementResponse> evenementsSelectionnes;
    private List<EvenementResponse> evenementsProchains;
    private EvenementResponse evenementSelectionne;
    
    // Formulaire nouveau événement
    private EvenementResponse nouvelEvenement;
    
    // Filtres
    private FiltresEvenement filtres;
    
    // Statistiques
    private StatistiquesEvenements statistiques;
    
    @PostConstruct
    public void init() {
        LOG.info("Initialisation de EvenementsBean");
        initializeFiltres();
        initializeNouvelEvenement();
        chargerEvenements();
        chargerEvenementsProchains();
        chargerStatistiques();
    }
    
    private void initializeFiltres() {
        filtres = new FiltresEvenement();
        evenementsSelectionnes = new ArrayList<>();
    }
    
    private void initializeNouvelEvenement() {
        nouvelEvenement = new EvenementResponse();
        nouvelEvenement.setPriorite(PrioriteEvenement.NORMALE);
        nouvelEvenement.setStatut(StatutEvenement.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 {
            LOG.info("Chargement des événements depuis le backend");
            var response = retryService.executeWithRetrySupplier(
                () -> evenementService.listerTous(0, 1000, "dateDebut", "asc"),
                "chargement de tous les événements"
            );

            tousLesEvenements = new ArrayList<>();

            // Récupérer les données depuis PagedResponse
            if (response != null && response.getData() != null) {
                tousLesEvenements.addAll(response.getData());
            }
            
            appliquerFiltres();
            LOG.infof("Événements chargés: %d", tousLesEvenements.size());
            
        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors du chargement des événements");
            tousLesEvenements = new ArrayList<>();
            errorHandler.handleException(e, "lors du chargement des événements", null);
        }
    }
    
    /**
     * Charge les événements à venir
     */
    public void chargerEvenementsProchains() {
        try {
            LOG.info("Chargement des événements à venir");
            var response = retryService.executeWithRetrySupplier(
                () -> evenementService.listerAVenir(0, 6),
                "chargement des événements à venir"
            );

            if (response != null && response.getData() != null) {
                evenementsProchains = new ArrayList<>(response.getData());
            } else {
                evenementsProchains = new ArrayList<>();
            }

        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors du chargement des événements à venir");
            evenementsProchains = new ArrayList<>();
        }
    }
    
    /**
     * Charge les statistiques depuis le backend
     */
    public void chargerStatistiques() {
        try {
            LOG.info("Chargement des statistiques");
            Map<String, Object> countResponse = retryService.executeWithRetrySupplier(
                () -> evenementService.compter(),
                "chargement des statistiques d'événements"
            );
            
            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 -> e.getStatut() == StatutEvenement.PLANIFIE ||
                                e.getStatut() == StatutEvenement.CONFIRME ||
                                e.getStatut() == StatutEvenement.EN_COURS)
                    .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);

                // Calculer les événements créés ce mois depuis les données backend
                LocalDate debutMois = LocalDate.now().withDayOfMonth(1);
                long evenementsCeMois = tousLesEvenements.stream()
                    .filter(e -> e.getDateCreation() != null &&
                                !e.getDateCreation().isBefore(debutMois.atStartOfDay()))
                    .count();
                statistiques.setEvenementsCeMois((int) evenementsCeMois);

                // Calculer le taux de participation moyen depuis les données backend
                double tauxMoyen = tousLesEvenements.stream()
                    .filter(e -> e.getCapaciteMax() != null && e.getCapaciteMax() > 0)
                    .mapToDouble(e -> {
                        int inscrits = e.getParticipantsInscrits() != null ? e.getParticipantsInscrits() : 0;
                        return (double) inscrits / e.getCapaciteMax() * 100.0;
                    })
                    .average()
                    .orElse(0.0);
                statistiques.setTauxParticipationMoyen((int) tauxMoyen);
            } else {
                statistiques.setTotalEvenements(0);
                statistiques.setEvenementsActifs(0);
                statistiques.setParticipantsTotal(0);
                statistiques.setBudgetTotal("0 FCFA");
                statistiques.setMoyenneParticipants(0);
                statistiques.setEvenementsCeMois(0);
                statistiques.setTauxParticipationMoyen(0);
            }
            
        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors du chargement des statistiques");
            statistiques = new StatistiquesEvenements();
            statistiques.setTotalEvenements(0);
            statistiques.setEvenementsActifs(0);
            statistiques.setParticipantsTotal(0);
            statistiques.setBudgetTotal("0 FCFA");
            statistiques.setMoyenneParticipants(0);
        }
    }
    
    /**
     * Convertit une Map en EvenementResponse
     */
    private EvenementResponse convertMapToDTO(Map<String, Object> map) {
        EvenementResponse dto = new EvenementResponse();
        
        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
            // Gérer à la fois "typeEvenement" et "type" pour compatibilité
            Object typeObj = map.get("typeEvenement");
            if (typeObj == null) {
                typeObj = map.get("type"); // Fallback sur "type" si "typeEvenement" n'existe pas
            }
            if (typeObj != null) {
                String typeStr = typeObj.toString();
                try {
                    dto.setTypeEvenement(TypeEvenementMetier.valueOf(typeStr));
                } catch (IllegalArgumentException e) {
                    // Ignorer si enum invalide
                }
            }

            // Statut - peut être un enum ou une String
            if (map.get("statut") != null) {
                String statutStr = map.get("statut").toString();
                try {
                    dto.setStatut(StatutEvenement.valueOf(statutStr));
                } catch (IllegalArgumentException e) {
                    // Ignorer si enum invalide
                }
            }

            // Priorité - peut être un enum ou une String
            if (map.get("priorite") != null) {
                String prioriteStr = map.get("priorite").toString();
                try {
                    dto.setPriorite(PrioriteEvenement.valueOf(prioriteStr));
                } catch (IllegalArgumentException e) {
                    // Ignorer si enum invalide
                }
            }
            
            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) {
            LOG.warnf(e, "Erreur lors de la conversion Map vers DTO");
        }
        
        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(EvenementResponse 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 (evenement.getTypeEvenement() == null ||
                    !filtres.getType().equals(evenement.getTypeEvenement().name())) {
                return false;
            }
        }

        if (filtres.getStatut() != null && !filtres.getStatut().trim().isEmpty()) {
            if (evenement.getStatut() == null ||
                    !filtres.getStatut().equals(evenement.getStatut().name())) {
                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 (evenement.getPriorite() == null ||
                    !filtres.getPriorite().equals(evenement.getPriorite().name())) {
                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 {
            LOG.infof("Création d'un nouvel événement: %s", nouvelEvenement.getTitre());
            
            EvenementResponse evenementCree = retryService.executeWithRetrySupplier(
                () -> evenementService.creer(nouvelEvenement),
                "création d'un événement"
            );
            
            // Recharger les événements
            chargerEvenements();
            chargerEvenementsProchains();
            chargerStatistiques();
            
            // Réinitialiser le formulaire
            initializeNouvelEvenement();
            
            errorHandler.showSuccess("Succès", "Événement créé avec succès");
            
        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors de la création de l'événement");
            errorHandler.handleException(e, "lors de la création d'un événement", null);
        }
    }
    
    /**
     * Modifie un événement existant
     */
    public void modifierEvenement() {
        try {
            if (evenementSelectionne == null || evenementSelectionne.getId() == null) {
                errorHandler.showWarning("Attention", "Aucun événement sélectionné");
                return;
            }
            
            LOG.infof("Modification de l'événement: %s", evenementSelectionne.getId());
            
            EvenementResponse evenementModifie = retryService.executeWithRetrySupplier(
                () -> evenementService.modifier(evenementSelectionne.getId(), evenementSelectionne),
                "modification d'un événement"
            );
            
            // Recharger les événements
            chargerEvenements();
            chargerEvenementsProchains();
            chargerStatistiques();
            
            errorHandler.showSuccess("Succès", "Événement modifié avec succès");
            
        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors de la modification");
            errorHandler.handleException(e, "lors de la modification d'un événement", null);
        }
    }
    
    /**
     * Supprime un événement
     */
    public void supprimerEvenement() {
        try {
            if (evenementSelectionne == null || evenementSelectionne.getId() == null) {
                errorHandler.showWarning("Attention", "Aucun événement sélectionné");
                return;
            }
            
            LOG.infof("Suppression de l'événement: %s", evenementSelectionne.getId());
            
            retryService.executeWithRetrySupplier(
                () -> {
                    evenementService.supprimer(evenementSelectionne.getId());
                    return null;
                },
                "suppression d'un événement"
            );
            
            // Recharger les événements
            chargerEvenements();
            chargerEvenementsProchains();
            chargerStatistiques();
            
            evenementSelectionne = null;
            
            errorHandler.showSuccess("Succès", "Événement supprimé avec succès");
            
        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors de la suppression");
            errorHandler.handleException(e, "lors de la suppression d'un événement", null);
        }
    }
    
    /**
     * Annule un événement
     */
    public void annulerEvenement() {
        try {
            if (evenementSelectionne == null || evenementSelectionne.getId() == null) {
                errorHandler.showWarning("Attention", "Aucun événement sélectionné");
                return;
            }

            evenementSelectionne.setStatut(StatutEvenement.ANNULE);
            modifierEvenement();

        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors de l'annulation");
            errorHandler.handleException(e, "lors de l'annulation d'un événement", null);
        }
    }
    
    /**
     * Sélectionne un événement
     */
    public void selectionnerEvenement(EvenementResponse evenement) {
        this.evenementSelectionne = evenement;
    }
    
    /**
     * Actualise les données
     */
    public void actualiser() {
        chargerEvenements();
        chargerEvenementsProchains();
        chargerStatistiques();
    }
    
    /**
     * Inscrit le membre actuel à un événement
     */
    public void sinscrireEvenement(EvenementResponse evenement) {
        try {
            if (evenement == null || evenement.getId() == null) {
                errorHandler.showWarning("Attention", "Événement invalide");
                return;
            }
            
            // Vérifier la capacité avec les méthodes existantes de EvenementResponse
            if (evenement.estComplet()) {
                errorHandler.showWarning("Complet", "Cet événement est complet");
                return;
            }
            
            LOG.infof("Inscription à l'événement: %s", evenement.getId());
            
            // Créer un participant pour l'utilisateur courant
            UUID userId = userSession.getCurrentUser() != null ? userSession.getCurrentUser().getId() : null;
            if (userId == null) {
                errorHandler.showWarning("Erreur", "Vous devez être connecté pour vous inscrire");
                return;
            }
            
            // Appeler le service backend pour l'inscription
            retryService.executeWithRetrySupplier(
                () -> {
                    evenementService.inscrireParticipant(evenement.getId());
                    return null;
                },
                "inscription à un événement"
            );
            
            // Mettre à jour le nombre d'inscrits localement
            Integer inscrits = evenement.getParticipantsInscrits();
            evenement.setParticipantsInscrits(inscrits != null ? inscrits + 1 : 1);
            
            errorHandler.showSuccess("Succès", "Inscription à l'événement enregistrée");
            
            // Actualiser les données
            chargerEvenements();
        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors de l'inscription");
            errorHandler.handleException(e, "lors de l'inscription à un événement", null);
        }
    }
    
    /**
     * 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 EvenementResponse();
            this.nouvelEvenement.setDateDebut(dateSelectionnee);
            this.nouvelEvenement.setDateFin(dateSelectionnee);
            this.nouvelEvenement.setHeureDebut(LocalTime.of(9, 0));
            this.nouvelEvenement.setHeureFin(LocalTime.of(18, 0));
            
            LOG.infof("Date sélectionnée: %s", 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 (EvenementResponse evt : tousLesEvenements) {
                            if (evt.getId() != null && evt.getId().toString().equals(eventId)) {
                                this.evenementSelectionne = evt;
                                LOG.infof("Événement sélectionné: %s", evt.getTitre());
                                break;
                            }
                        }
                    }
                }
            } catch (Exception e) {
                LOG.warnf(e, "Erreur sélection événement");
            }
        }
    }
    
    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
        LOG.info("Événement déplacé - actualisation nécessaire");
        errorHandler.showInfo("Information", "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
        LOG.info("Événement redimensionné - actualisation nécessaire");
        errorHandler.showInfo("Information", "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; }
    
    // Getters et Setters
    
    public List<EvenementResponse> getTousLesEvenements() { return tousLesEvenements; }
    public void setTousLesEvenements(List<EvenementResponse> tousLesEvenements) { 
        this.tousLesEvenements = tousLesEvenements; 
    }
    
    public List<EvenementResponse> getEvenementsFiltres() { return evenementsFiltres; }
    public void setEvenementsFiltres(List<EvenementResponse> evenementsFiltres) { 
        this.evenementsFiltres = evenementsFiltres; 
    }
    
    public List<EvenementResponse> getEvenementsSelectionnes() { return evenementsSelectionnes; }
    public void setEvenementsSelectionnes(List<EvenementResponse> evenementsSelectionnes) { 
        this.evenementsSelectionnes = evenementsSelectionnes; 
    }
    
    public List<EvenementResponse> getEvenementsProchains() { return evenementsProchains; }
    public void setEvenementsProchains(List<EvenementResponse> evenementsProchains) { 
        this.evenementsProchains = evenementsProchains; 
    }
    
    public EvenementResponse getEvenementSelectionne() { return evenementSelectionne; }
    public void setEvenementSelectionne(EvenementResponse evenementSelectionne) { 
        this.evenementSelectionne = evenementSelectionne; 
    }
    
    public EvenementResponse getNouvelEvenement() { return nouvelEvenement; }
    public void setNouvelEvenement(EvenementResponse 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;
        private int evenementsCeMois;
        private int tauxParticipationMoyen;

        // 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;
        }

        public int getEvenementsCeMois() { return evenementsCeMois; }
        public void setEvenementsCeMois(int evenementsCeMois) {
            this.evenementsCeMois = evenementsCeMois;
        }

        public int getTauxParticipationMoyen() { return tauxParticipationMoyen; }
        public void setTauxParticipationMoyen(int tauxParticipationMoyen) {
            this.tauxParticipationMoyen = tauxParticipationMoyen;
        }
    }
}
