package dev.lions.unionflow.client.view;

import dev.lions.unionflow.client.service.CotisationService;
import dev.lions.unionflow.client.service.DashboardService;
import dev.lions.unionflow.server.api.dto.cotisation.response.CotisationResponse;
import dev.lions.unionflow.server.api.dto.dashboard.DashboardDataResponse;
import dev.lions.unionflow.server.api.dto.dashboard.DashboardStatsResponse;
import dev.lions.unionflow.server.api.dto.dashboard.RecentActivityResponse;
import dev.lions.unionflow.server.api.dto.dashboard.UpcomingEventResponse;
import jakarta.annotation.PostConstruct;
import jakarta.faces.context.FacesContext;
import jakarta.faces.view.ViewScoped;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import org.eclipse.microprofile.rest.client.inject.RestClient;
import java.io.IOException;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.jboss.logging.Logger;
import dev.lions.unionflow.client.service.ErrorHandlerService;
import dev.lions.unionflow.client.service.RetryService;

@Named("dashboardBean")
@ViewScoped
public class DashboardBean implements Serializable {
    
    private static final long serialVersionUID = 1L;
    private static final Logger LOG = Logger.getLogger(DashboardBean.class);
    
    // Constantes de navigation outcomes (WOU/DRY - réutilisables)
    private static final String OUTCOME_MEMBRE_INSCRIPTION = "membreInscriptionPage";
    private static final String OUTCOME_COTISATION_PAIEMENT = "cotisationPaiementPage";
    private static final String OUTCOME_EVENEMENT_CREATION = "evenementCreationPage";
    private static final String OUTCOME_ADHESION_VALIDATION = "adhesionValidationPage";
    private static final String OUTCOME_COTISATION_RELANCES = "cotisationRelancesPage";
    private static final String OUTCOME_AIDE_TRAITEMENT = "aideTraitementPage";
    private static final String OUTCOME_EVENEMENT_GESTION = "evenementGestionPage";
    
    @Inject
    @RestClient
    private DashboardService dashboardService;
    
    @Inject
    @RestClient
    private CotisationService cotisationService; // Utilisé uniquement pour calculerEvolutionFinanciere()
    
    @Inject
    private UserSession userSession;

    @Inject
    private dev.lions.unionflow.client.bean.MenuBean menuBean;

    @Inject
    ErrorHandlerService errorHandler;

    @Inject
    RetryService retryService;
    
    // Propriétés existantes
    private int activeMembers = 0;
    private String totalCotisations = "0";
    private int pendingAides = 0;
    private int upcomingEvents = 0;
    
    // Nouvelles propriétés pour le dashboard enrichi
    private int totalMembers = 0;
    private String aidesDistribuees = "0";
    private int tauxParticipation = 0;
    
    // Propriétés pour les alertes
    private int cotisationsRetard = 0;
    private int adhesionsExpiration = 0;
    private int demandesToTraiter = 0;
    private int tachesFinaliser = 0;
    
    // Propriétés pour les évolutions
    private int membresEvolutionPourcent = 0;
    private int cotisationsEvolutionPourcent = 0;
    private String objectifCotisations = "0";
    private int aidesApprouvees = 0;
    private int membresParticipants = 0;
    
    // Propriétés pour le graphique
    private String periodeGraph = "3M";
    private String filtreActivite = "ALL";
    
    // Propriétés pour les cotisations
    private int cotisationsAJour = 0;
    private int cotisationsRetardPourcent = 0;
    private int cotisationsImpayees = 0;
    private int cotisationsAJourPourcent = 0;
    private int cotisationsImpayeesPourcent = 0;
    private int tauxCollecte = 0;
    
    // Propriétés pour les tâches prioritaires
    private int adhesionsPendantes = 0;
    private int aidesEnAttente = 0;
    private int evenementsAPlanifier = 0;
    
    // Propriétés financières
    private Date moisSelectionne = new Date();
    private String recettesMois = "0";
    private String depensesMois = "0";
    private String soldeMois = "0";
    private String tresorerie = "0";
    
    // Date actuelle
    private String currentDate;
    
    // Propriétés manquantes pour les barres de progression
    private int tauxActivite = 0;
    private int tauxObjectifCotisations = 0;
    private int tauxAidesTraitees = 0;
    private int tauxEngagement = 0;
    private int tachesCompletees = 0;
    private boolean hasAlerts = false;
    
    // Liste des activités récentes (chargées depuis le backend)
    private List<Activity> recentActivities;
    
    // Évolution financière (3 derniers mois)
    private List<MoisFinancier> evolutionFinanciere;
    private int evolutionRecettesPourcent = 0;
    private int evolutionDepensesPourcent = 0;
    private String tendanceParticipation = "Stable";
    
    public DashboardBean() {
        this.currentDate = LocalDate.now().format(DateTimeFormatter.ofPattern("dd MMMM yyyy"));
        this.evolutionFinanciere = new ArrayList<>();
        this.recentActivities = new ArrayList<>();
    }
    
    @PostConstruct
    public void init() {
        // Charger les données pour les rôles administratifs
        chargerDonneesBackend();
    }

    /**
     * Méthode appelée par f:viewAction pour rediriger les MEMBRE_ACTIF.
     * S'exécute AVANT le rendu de la page (phase INVOKE_APPLICATION).
     */
    public void checkAccessAndRedirect() {
        if (menuBean == null) return;
        // SUPER_ADMIN → tableau de bord dédié avec vue globale toutes organisations
        if (menuBean.isSuperAdmin()) {
            try {
                FacesContext ctx = FacesContext.getCurrentInstance();
                String redirectUrl = ctx.getExternalContext().getRequestContextPath() +
                                   "/pages/super-admin/dashboard.xhtml";
                ctx.getExternalContext().redirect(redirectUrl);
                ctx.responseComplete();
                return;
            } catch (IOException e) {
                LOG.error("Erreur lors de la redirection vers le dashboard super-admin", e);
            }
        }
        // MEMBRE_ACTIF sans rôle fonctionnel → tableau de bord personnel
        if (menuBean.isMembreActif() &&
                !menuBean.isSecretaire() && !menuBean.isTresorier() &&
                !menuBean.isResponsableSocial() && !menuBean.isResponsableEvenements() &&
                !menuBean.isAdminOrganisation()) {
            try {
                FacesContext ctx = FacesContext.getCurrentInstance();
                String redirectUrl = ctx.getExternalContext().getRequestContextPath() +
                                   "/pages/secure/dashboard-membre.xhtml";
                ctx.getExternalContext().redirect(redirectUrl);
                ctx.responseComplete();
            } catch (IOException e) {
                LOG.error("Erreur lors de la redirection vers dashboard-membre", e);
            }
        }
    }
    
    /**
     * Charge toutes les données depuis le service Dashboard (DRY/WOU - un seul appel)
     */
    private void chargerDonneesBackend() {
        LOG.info("Chargement des données du dashboard depuis le backend...");

        try {
            // Obtenir organizationId et userId depuis UserSession
            final String organizationId;
            final String userId;
            
            if (userSession != null) {
                organizationId = (userSession.getEntite() != null && userSession.getEntite().getId() != null) 
                    ? userSession.getEntite().getId().toString() 
                    : null;
                userId = (userSession.getCurrentUser() != null && userSession.getCurrentUser().getId() != null) 
                    ? userSession.getCurrentUser().getId().toString() 
                    : null;
            } else {
                organizationId = null;
                userId = null;
            }
            
            // userId et organizationId sont obligatoires pour ce dashboard
            // Le SUPER_ADMIN est redirigé vers /pages/super-admin/dashboard.xhtml (pas ce bean)
            if (userId == null) {
                LOG.warn("UserId manquant — utilisateur non initialisé, abandon du chargement dashboard");
                initValuesParDefaut();
                return;
            }
            if (organizationId == null) {
                LOG.debug("OrganisationId absent (SUPER_ADMIN) — ce dashboard ne s'applique pas, valeurs par défaut");
                initValuesParDefaut();
                return;
            }

            DashboardDataResponse dashboardData = retryService.executeWithRetrySupplier(
                () -> dashboardService.getDashboardData(organizationId, userId),
                "chargement des données du dashboard"
            );
            
            if (dashboardData != null) {
                chargerDepuisDashboardData(dashboardData);
                LOG.info("Données du dashboard chargées avec succès depuis DashboardService");
            } else {
                LOG.warn("DashboardDataResponse est null - utilisation de valeurs par défaut");
                initValuesParDefaut();
            }
        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors du chargement du dashboard");
            // Initialiser avec des valeurs par défaut pour éviter les NullPointerException
            initValuesParDefaut();
        }
    }
    
    /**
     * Charge les données depuis DashboardDataResponse (DRY/WOU)
     */
    private void chargerDepuisDashboardData(DashboardDataResponse dashboardData) {
        // Charger les statistiques
        DashboardStatsResponse stats = dashboardData.getStats();
        if (stats != null) {
            chargerDepuisStats(stats);
        }
        
        // Charger les activités récentes
        List<RecentActivityResponse> activities = dashboardData.getRecentActivities();
        if (activities != null) {
            chargerActivitesRecentes(activities);
        }
        
        // Charger les événements à venir
        List<UpcomingEventResponse> events = dashboardData.getUpcomingEvents();
        if (events != null) {
            chargerEvenementsAvenir(events);
        }
        
        // Calculer les indicateurs dérivés
        calculerIndicateurs();
    }
    
    /**
     * Charge les données depuis DashboardStatsResponse (utilise uniquement les champs disponibles)
     */
    private void chargerDepuisStats(DashboardStatsResponse stats) {
        if (stats.getTotalMembers() != null) {
            totalMembers = stats.getTotalMembers().intValue();
        }
        if (stats.getActiveMembers() != null) {
            activeMembers = stats.getActiveMembers().intValue();
        }
        if (stats.getTotalContributionAmount() != null) {
            totalCotisations = String.format("%,.0f", stats.getTotalContributionAmount());
            tresorerie = totalCotisations; // Approximation
        }
        if (stats.getPendingRequests() != null) {
            pendingAides = stats.getPendingRequests().intValue();
            aidesEnAttente = pendingAides;
        }
        if (stats.getUpcomingEvents() != null) {
            upcomingEvents = stats.getUpcomingEvents().intValue();
            evenementsAPlanifier = upcomingEvents;
        }
        if (stats.getEngagementRate() != null) {
            tauxParticipation = (int)(stats.getEngagementRate() * 100); // engagementRate est 0-1
        }
        // Note: Les champs suivants ne sont pas dans DashboardStatsResponse actuel
        // Ils seront chargés depuis d'autres sources ou laissés à 0
        // - cotisationsRetard, cotisationsImpayees, cotisationsAJour
        // - adhesionsPendantes, adhesionsExpiration
        // - aidesDistribuees
    }
    
    /**
     * Charge les activités récentes depuis la liste DTO
     */
    private void chargerActivitesRecentes(List<RecentActivityResponse> activities) {
        recentActivities = new ArrayList<>();
        for (RecentActivityResponse activityDTO : activities) {
            // Convertir getActivityColor() (retourne un hex color) en severity PrimeFaces
            String severity = convertirCouleurEnSeverity(activityDTO.getActivityColor());
            // Convertir getActivityIcon() (retourne Material Icons) en PrimeIcons
            String icon = convertirIconEnPrimeIcon(activityDTO.getActivityIcon());
            
            Activity activity = new Activity(
                activityDTO.getTimestamp() != null ? activityDTO.getTimestamp() : LocalDateTime.now(),
                activityDTO.getType() != null ? activityDTO.getType() : "ACTION",
                severity,
                icon,
                activityDTO.getTitle() != null ? activityDTO.getTitle() : activityDTO.getType(),
                activityDTO.getDescription(),
                null, // RecentActivityResponse n'a pas de montant
                activityDTO.getUserName() != null ? activityDTO.getUserName() : "Système",
                "Utilisateur" // RecentActivityResponse n'a pas de userRole
            );
            recentActivities.add(activity);
        }
    }
    
    /**
     * Convertit une couleur hex en severity PrimeFaces
     */
    private String convertirCouleurEnSeverity(String color) {
        if (color == null) return "info";
        // #10B981 = success, #3B82F6 = info, #008B8B = teal, #4169E1 = info, #6B7280 = secondary
        if (color.contains("10B981")) return "success";
        if (color.contains("3B82F6") || color.contains("4169E1")) return "info";
        if (color.contains("008B8B")) return "info";
        return "info";
    }
    
    /**
     * Convertit Material Icons en PrimeIcons
     */
    private String convertirIconEnPrimeIcon(String materialIcon) {
        if (materialIcon == null) return "pi-info-circle";
        // Mapping Material Icons -> PrimeIcons
        switch (materialIcon) {
            case "person": return "pi-user";
            case "event": return "pi-calendar";
            case "payment": return "pi-money-bill";
            case "business": return "pi-building";
            case "settings": return "pi-cog";
            case "info": return "pi-info-circle";
            default: return "pi-info-circle";
        }
    }
    
    /**
     * Charge les événements à venir depuis la liste DTO
     */
    private void chargerEvenementsAvenir(List<UpcomingEventResponse> events) {
        upcomingEvents = events.size();
        evenementsAPlanifier = upcomingEvents;
    }

    /**
     * Initialise des valeurs par défaut en cas d'erreur de chargement backend
     */
    private void initValuesParDefaut() {
        if (recentActivities == null) {
            recentActivities = new ArrayList<>();
        }
        hasAlerts = (cotisationsRetard > 0 || adhesionsExpiration > 0);
    }
    
    // Méthodes supprimées - remplacées par chargerDepuisDashboardData (DRY/WOU)
    
    private void calculerIndicateurs() {
        // Calculer taux d'activité
        if (totalMembers > 0 && activeMembers > 0) {
            tauxActivite = (activeMembers * 100) / totalMembers;
        }
        
        // Calculer taux de participation
        tauxParticipation = tauxActivite; // Approximation
        
        // Calculer pourcentages de cotisations
        int totalCot = cotisationsAJour + cotisationsRetard + cotisationsImpayees;
        if (totalCot > 0) {
            cotisationsAJourPourcent = (cotisationsAJour * 100) / totalCot;
            cotisationsRetardPourcent = (cotisationsRetard * 100) / totalCot;
            cotisationsImpayeesPourcent = (cotisationsImpayees * 100) / totalCot;
            
            // Taux de collecte = cotisations à jour + en retard
            tauxCollecte = ((cotisationsAJour + cotisationsRetard) * 100) / totalCot;
        }
        
        // Calculer évolution financière
        calculerEvolutionFinanciere();
        
        // Déterminer s'il y a des alertes
        hasAlerts = (cotisationsRetard > 0 || adhesionsPendantes > 0 || demandesToTraiter > 0);
    }
    
    private void calculerEvolutionFinanciere() {
        evolutionFinanciere.clear();

        try {
            // Récupérer les statistiques des 3 derniers mois depuis le backend
            LocalDate now = LocalDate.now();
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMMM yyyy");

            for (int i = 2; i >= 0; i--) {
                LocalDate mois = now.minusMonths(i);
                String libelleMois = mois.format(formatter);
                int annee = mois.getYear();
                int numeroMois = mois.getMonthValue();

                // Appeler le backend pour obtenir les cotisations du mois
                BigDecimal montant = BigDecimal.ZERO;
                try {
                    List<CotisationResponse> cotisations =
                        retryService.executeWithRetrySupplier(
                            () -> cotisationService.rechercher(null, "PAYEE", null, annee, numeroMois, 0, 10000),
                            "recherche de cotisations pour évolution financière"
                        );

                    // Calculer le total des cotisations payées pour ce mois
                    montant = cotisations.stream()
                        .map(c -> c.getMontantPaye() != null ? c.getMontantPaye() : BigDecimal.ZERO)
                        .reduce(BigDecimal.ZERO, BigDecimal::add);

                    LOG.infof("Évolution financière: %s = %s FCFA", libelleMois, montant);
                } catch (Exception e) {
                    LOG.warnf(e, "Impossible de charger les cotisations pour %s", libelleMois);
                }

                evolutionFinanciere.add(new MoisFinancier(libelleMois, montant));
            }

            // Calculer tendances depuis les données réelles
            if (evolutionFinanciere.size() >= 2) {
                MoisFinancier dernierMois = evolutionFinanciere.get(evolutionFinanciere.size() - 1);
                MoisFinancier avantDernierMois = evolutionFinanciere.get(evolutionFinanciere.size() - 2);

                if (avantDernierMois.getMontant().compareTo(BigDecimal.ZERO) > 0) {
                    BigDecimal diff = dernierMois.getMontant().subtract(avantDernierMois.getMontant());
                    evolutionRecettesPourcent = diff.multiply(BigDecimal.valueOf(100))
                        .divide(avantDernierMois.getMontant(), 0, java.math.RoundingMode.HALF_UP).intValue();
                }
            }

        } catch (Exception e) {
            LOG.warnf(e, "Erreur lors du calcul de l'évolution financière");
        }
    }
    
    private String getSeverityFromAction(String action) {
        if (action == null) return "info";
        if (action.contains("ERREUR") || action.contains("ECHEC")) return "danger";
        if (action.contains("CREATION") || action.contains("PAIEMENT")) return "success";
        if (action.contains("MODIFICATION")) return "warning";
        return "info";
    }
    
    private String getIconFromAction(String action) {
        if (action == null) return "pi pi-info-circle";
        if (action.contains("MEMBRE")) return "pi pi-user";
        if (action.contains("COTISATION") || action.contains("PAIEMENT")) return "pi pi-money-bill";
        if (action.contains("ADHESION")) return "pi pi-user-plus";
        if (action.contains("EVENEMENT")) return "pi pi-calendar";
        return "pi pi-info-circle";
    }
    
    // Getters et Setters complets
    public int getActiveMembers() { return activeMembers; }
    public void setActiveMembers(int activeMembers) { this.activeMembers = activeMembers; }
    
    public String getTotalCotisations() { return totalCotisations; }
    public void setTotalCotisations(String totalCotisations) { this.totalCotisations = totalCotisations; }
    
    public int getPendingAides() { return pendingAides; }
    public void setPendingAides(int pendingAides) { this.pendingAides = pendingAides; }
    
    public int getUpcomingEvents() { return upcomingEvents; }
    public void setUpcomingEvents(int upcomingEvents) { this.upcomingEvents = upcomingEvents; }
    
    public int getTotalMembers() { return totalMembers; }
    public void setTotalMembers(int totalMembers) { this.totalMembers = totalMembers; }
    
    public String getAidesDistribuees() { return aidesDistribuees; }
    public void setAidesDistribuees(String aidesDistribuees) { this.aidesDistribuees = aidesDistribuees; }
    
    public int getTauxParticipation() { return tauxParticipation; }
    public void setTauxParticipation(int tauxParticipation) { this.tauxParticipation = tauxParticipation; }
    
    public int getCotisationsRetard() { return cotisationsRetard; }
    public void setCotisationsRetard(int cotisationsRetard) { this.cotisationsRetard = cotisationsRetard; }
    
    public int getAdhesionsExpiration() { return adhesionsExpiration; }
    public void setAdhesionsExpiration(int adhesionsExpiration) { this.adhesionsExpiration = adhesionsExpiration; }
    
    public int getDemandesToTraiter() { return demandesToTraiter; }
    public void setDemandesToTraiter(int demandesToTraiter) { this.demandesToTraiter = demandesToTraiter; }
    
    public int getTachesFinaliser() { return tachesFinaliser; }
    public void setTachesFinaliser(int tachesFinaliser) { this.tachesFinaliser = tachesFinaliser; }
    
    public int getMembresEvolutionPourcent() { return membresEvolutionPourcent; }
    public void setMembresEvolutionPourcent(int membresEvolutionPourcent) { this.membresEvolutionPourcent = membresEvolutionPourcent; }
    
    public int getCotisationsEvolutionPourcent() { return cotisationsEvolutionPourcent; }
    public void setCotisationsEvolutionPourcent(int cotisationsEvolutionPourcent) { this.cotisationsEvolutionPourcent = cotisationsEvolutionPourcent; }
    
    public String getObjectifCotisations() { return objectifCotisations; }
    public void setObjectifCotisations(String objectifCotisations) { this.objectifCotisations = objectifCotisations; }
    
    public int getAidesApprouvees() { return aidesApprouvees; }
    public void setAidesApprouvees(int aidesApprouvees) { this.aidesApprouvees = aidesApprouvees; }
    
    public int getMembresParticipants() { return membresParticipants; }
    public void setMembresParticipants(int membresParticipants) { this.membresParticipants = membresParticipants; }
    
    public String getPeriodeGraph() { return periodeGraph; }
    public void setPeriodeGraph(String periodeGraph) { this.periodeGraph = periodeGraph; }
    
    public String getFiltreActivite() { return filtreActivite; }
    public void setFiltreActivite(String filtreActivite) { this.filtreActivite = filtreActivite; }
    
    public int getCotisationsAJour() { return cotisationsAJour; }
    public void setCotisationsAJour(int cotisationsAJour) { this.cotisationsAJour = cotisationsAJour; }
    
    public int getCotisationsRetardPourcent() { return cotisationsRetardPourcent; }
    public void setCotisationsRetardPourcent(int cotisationsRetardPourcent) { this.cotisationsRetardPourcent = cotisationsRetardPourcent; }
    
    public int getCotisationsImpayees() { return cotisationsImpayees; }
    public void setCotisationsImpayees(int cotisationsImpayees) { this.cotisationsImpayees = cotisationsImpayees; }
    
    public int getAdhesionsPendantes() { return adhesionsPendantes; }
    public void setAdhesionsPendantes(int adhesionsPendantes) { this.adhesionsPendantes = adhesionsPendantes; }
    
    public int getAidesEnAttente() { return aidesEnAttente; }
    public void setAidesEnAttente(int aidesEnAttente) { this.aidesEnAttente = aidesEnAttente; }
    
    public int getEvenementsAPlanifier() { return evenementsAPlanifier; }
    public void setEvenementsAPlanifier(int evenementsAPlanifier) { this.evenementsAPlanifier = evenementsAPlanifier; }
    
    public Date getMoisSelectionne() { return moisSelectionne; }
    public void setMoisSelectionne(Date moisSelectionne) { this.moisSelectionne = moisSelectionne; }
    
    public String getRecettesMois() { return recettesMois; }
    public void setRecettesMois(String recettesMois) { this.recettesMois = recettesMois; }
    
    public String getDepensesMois() { return depensesMois; }
    public void setDepensesMois(String depensesMois) { this.depensesMois = depensesMois; }
    
    public String getSoldeMois() { return soldeMois; }
    public void setSoldeMois(String soldeMois) { this.soldeMois = soldeMois; }
    
    public String getTresorerie() { return tresorerie; }
    public void setTresorerie(String tresorerie) { this.tresorerie = tresorerie; }
    
    public String getCurrentDate() { return currentDate; }
    public void setCurrentDate(String currentDate) { this.currentDate = currentDate; }
    
    public int getTauxActivite() { return tauxActivite; }
    public void setTauxActivite(int tauxActivite) { this.tauxActivite = tauxActivite; }
    
    public int getTauxObjectifCotisations() { return tauxObjectifCotisations; }
    public void setTauxObjectifCotisations(int tauxObjectifCotisations) { this.tauxObjectifCotisations = tauxObjectifCotisations; }
    
    public int getTauxAidesTraitees() { return tauxAidesTraitees; }
    public void setTauxAidesTraitees(int tauxAidesTraitees) { this.tauxAidesTraitees = tauxAidesTraitees; }
    
    public int getTauxEngagement() { return tauxEngagement; }
    public void setTauxEngagement(int tauxEngagement) { this.tauxEngagement = tauxEngagement; }
    
    public int getTachesCompletees() { return tachesCompletees; }
    public void setTachesCompletees(int tachesCompletees) { this.tachesCompletees = tachesCompletees; }
    
    public boolean isHasAlerts() { return hasAlerts; }
    public void setHasAlerts(boolean hasAlerts) { this.hasAlerts = hasAlerts; }
    
    public int getCotisationsAJourPourcent() { return cotisationsAJourPourcent; }
    public void setCotisationsAJourPourcent(int cotisationsAJourPourcent) { this.cotisationsAJourPourcent = cotisationsAJourPourcent; }
    
    public int getCotisationsImpayeesPourcent() { return cotisationsImpayeesPourcent; }
    public void setCotisationsImpayeesPourcent(int cotisationsImpayeesPourcent) { this.cotisationsImpayeesPourcent = cotisationsImpayeesPourcent; }
    
    public int getTauxCollecte() { return tauxCollecte; }
    public void setTauxCollecte(int tauxCollecte) { this.tauxCollecte = tauxCollecte; }
    
    public List<MoisFinancier> getEvolutionFinanciere() { return evolutionFinanciere; }
    public void setEvolutionFinanciere(List<MoisFinancier> evolutionFinanciere) { this.evolutionFinanciere = evolutionFinanciere; }
    
    public int getEvolutionRecettesPourcent() { return evolutionRecettesPourcent; }
    public void setEvolutionRecettesPourcent(int evolutionRecettesPourcent) { this.evolutionRecettesPourcent = evolutionRecettesPourcent; }
    
    public int getEvolutionDepensesPourcent() { return evolutionDepensesPourcent; }
    public void setEvolutionDepensesPourcent(int evolutionDepensesPourcent) { this.evolutionDepensesPourcent = evolutionDepensesPourcent; }

    public String getTendanceParticipation() { return tendanceParticipation; }
    public void setTendanceParticipation(String tendanceParticipation) { this.tendanceParticipation = tendanceParticipation; }
    
    // Méthodes utilitaires pour l'affichage des tendances
    public String getEvolutionRecettesIcon() {
        return evolutionRecettesPourcent >= 0 ? "pi pi-arrow-up text-green-500" : "pi pi-arrow-down text-red-500";
    }
    
    public String getEvolutionRecettesPrefix() {
        return evolutionRecettesPourcent >= 0 ? "+" : "";
    }
    
    public String getEvolutionDepensesIcon() {
        return evolutionDepensesPourcent <= 0 ? "pi pi-arrow-down text-green-500" : "pi pi-arrow-up text-red-500";
    }
    
    public String getEvolutionDepensesPrefix() {
        return evolutionDepensesPourcent >= 0 ? "+" : "";
    }
    
    // Méthodes pour les activités récentes
    public List<Activity> getRecentActivities() {
        if (recentActivities == null) {
            return new ArrayList<>();
        }
        return recentActivities;
    }
    
    public void actualiser() {
        chargerDonneesBackend();
    }
    
    // Actions de navigation (WOU/DRY - utilisation de navigation outcomes)
    public String redirectToNewMember() {
        return OUTCOME_MEMBRE_INSCRIPTION + "?faces-redirect=true";
    }
    
    public String redirectToCotisation() {
        return OUTCOME_COTISATION_PAIEMENT + "?faces-redirect=true";
    }
    
    public String redirectToEvenement() {
        return OUTCOME_EVENEMENT_CREATION + "?faces-redirect=true";
    }
    
    public String redirectToAdhesionValidation() {
        return OUTCOME_ADHESION_VALIDATION + "?faces-redirect=true";
    }
    
    public String redirectToRelances() {
        return OUTCOME_COTISATION_RELANCES + "?faces-redirect=true";
    }
    
    public String redirectToAidesTraitement() {
        return OUTCOME_AIDE_TRAITEMENT + "?faces-redirect=true";
    }
    
    public String redirectToEvenementPlanning() {
        return OUTCOME_EVENEMENT_GESTION + "?faces-redirect=true";
    }
    
    public void generateRapport() {
        // Logique de génération de rapport
    }
    
    public void exportFinancialReport() {
        // Logique d'export du rapport financier
    }
    
    public void onMoisChange() {
        // Logique de mise à jour lors du changement de mois
    }
    
    // Classe interne pour les activités enrichie
    public static class Activity implements Serializable {
        private LocalDateTime date;
        private String type;
        private String severity;
        private String icon;
        private String titre;
        private String description;
        private String montant;
        private String userNom;
        private String userRole;
        
        public Activity(LocalDateTime date, String type, String severity, String icon, 
                       String titre, String description, String montant, String userNom, String userRole) {
            this.date = date;
            this.type = type;
            this.severity = severity;
            this.icon = icon;
            this.titre = titre;
            this.description = description;
            this.montant = montant;
            this.userNom = userNom;
            this.userRole = userRole;
        }
        
        // Getters et setters
        public LocalDateTime getDate() { return date; }
        public void setDate(LocalDateTime date) { this.date = date; }
        
        public String getType() { return type; }
        public void setType(String type) { this.type = type; }
        
        public String getSeverity() { return severity; }
        public void setSeverity(String severity) { this.severity = severity; }
        
        public String getIcon() { return icon; }
        public void setIcon(String icon) { this.icon = icon; }
        
        public String getTitre() { return titre; }
        public void setTitre(String titre) { this.titre = titre; }
        
        public String getDescription() { return description; }
        public void setDescription(String description) { this.description = description; }
        
        public String getMontant() { return montant; }
        public void setMontant(String montant) { this.montant = montant; }
        
        public String getUserNom() { return userNom; }
        public void setUserNom(String userNom) { this.userNom = userNom; }
        
        public String getUserRole() { return userRole; }
        public void setUserRole(String userRole) { this.userRole = userRole; }
    }
    
    /**
     * Classe interne pour représenter les données financières d'un mois
     */
    public static class MoisFinancier implements Serializable {
        private static final long serialVersionUID = 1L;
        private String libelle;
        private BigDecimal montant;
        private int hauteur; // Pour l'affichage visuel en pixels
        
        public MoisFinancier(String libelle, BigDecimal montant) {
            this.libelle = libelle;
            this.montant = montant != null ? montant : BigDecimal.ZERO;
            // Calculer la hauteur proportionnelle (entre 40 et 120 pixels)
            this.hauteur = calculerHauteur(this.montant);
        }
        
        private int calculerHauteur(BigDecimal montant) {
            if (montant.compareTo(BigDecimal.ZERO) == 0) {
                return 40; // Hauteur minimale
            }
            // Normaliser entre 40 et 120 pixels
            // On suppose un max de 10M FCFA pour l'échelle
            BigDecimal maxRef = new BigDecimal("10000000");
            double ratio = montant.divide(maxRef, 4, java.math.RoundingMode.HALF_UP).doubleValue();
            int hauteur = 40 + (int)(ratio * 80);
            return Math.min(Math.max(hauteur, 40), 120); // Entre 40 et 120
        }
        
        public String getLibelle() { return libelle; }
        public void setLibelle(String libelle) { this.libelle = libelle; }
        
        public BigDecimal getMontant() { return montant; }
        public void setMontant(BigDecimal montant) { 
            this.montant = montant;
            this.hauteur = calculerHauteur(montant);
        }
        
        public String getMontantFormatte() {
            if (montant.compareTo(new BigDecimal("1000000")) >= 0) {
                // Afficher en millions
                BigDecimal millions = montant.divide(new BigDecimal("1000000"), 1, java.math.RoundingMode.HALF_UP);
                return millions.toString() + "M FCFA";
            } else if (montant.compareTo(BigDecimal.ZERO) == 0) {
                return "0 FCFA";
            } else {
                return String.format("%,d FCFA", montant.longValue());
            }
        }
        
        public int getHauteur() { return hauteur; }
        public void setHauteur(int hauteur) { this.hauteur = hauteur; }
    }
}
