package dev.lions.unionflow.client.view;

import jakarta.enterprise.context.SessionScoped;
import jakarta.inject.Named;
import jakarta.annotation.PostConstruct;
import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.math.BigDecimal;

@Named("cotisationsBean")
@SessionScoped
public class CotisationsBean implements Serializable {
    
    private static final long serialVersionUID = 1L;
    
    private List<Cotisation> toutesLesCotisations;
    private List<Cotisation> cotisationsFiltrees;
    private List<Cotisation> cotisationsSelectionnees;
    private Cotisation cotisationSelectionnee;
    private NouvelleCotisation nouvelleCotisation;
    private Filtres filtres;
    private StatistiquesFinancieres statistiques;
    private List<EvolutionPaiement> evolutionPaiements;
    private List<RepartitionMethode> repartitionMethodes;
    private List<RappelCotisation> rappelsEnAttente;
    
    @PostConstruct
    public void init() {
        initializeFiltres();
        initializeStatistiques();
        initializeCotisations();
        initializeNouvelleCotisation();
        initializeEvolutionPaiements();
        initializeRepartitionMethodes();
        initializeRappels();
        appliquerFiltres();
    }
    
    private void initializeFiltres() {
        filtres = new Filtres();
        cotisationsSelectionnees = new ArrayList<>();
    }
    
    private void initializeStatistiques() {
        statistiques = new StatistiquesFinancieres();
        statistiques.setTotalCollecte(new BigDecimal("45750000"));
        statistiques.setObjectifAnnuel(new BigDecimal("60000000"));
        statistiques.setTauxRecouvrement(76.25);
        statistiques.setCotisationsEnRetard(23);
        statistiques.setMontantRetard(new BigDecimal("3850000"));
        statistiques.setMoyenneMensuelle(new BigDecimal("3812500"));
    }
    
    private void initializeEvolutionPaiements() {
        evolutionPaiements = new ArrayList<>();
        String[] mois = {"Jan", "Fév", "Mar", "Avr", "Mai", "Jun", "Jul", "Aoû", "Sep", "Oct", "Nov", "Déc"};
        BigDecimal[] montants = {
            new BigDecimal("2850000"), new BigDecimal("3200000"), new BigDecimal("3650000"),
            new BigDecimal("3950000"), new BigDecimal("4200000"), new BigDecimal("3800000"),
            new BigDecimal("4100000"), new BigDecimal("3750000"), new BigDecimal("4300000"),
            new BigDecimal("3900000"), new BigDecimal("4150000"), new BigDecimal("4000000")
        };
        
        for (int i = 0; i < mois.length; i++) {
            EvolutionPaiement evolution = new EvolutionPaiement();
            evolution.setMois(mois[i]);
            evolution.setMontant(montants[i]);
            evolution.setHauteur((int) (montants[i].divide(new BigDecimal("50000")).intValue()));
            evolutionPaiements.add(evolution);
        }
    }
    
    private void initializeRepartitionMethodes() {
        repartitionMethodes = new ArrayList<>();
        
        RepartitionMethode wave = new RepartitionMethode();
        wave.setMethode("Wave Money");
        wave.setPourcentage(45.2);
        wave.setMontant(new BigDecimal("20689500"));
        wave.setCouleur("bg-blue-500");
        wave.setIcon("pi-mobile");
        repartitionMethodes.add(wave);
        
        RepartitionMethode especes = new RepartitionMethode();
        especes.setMethode("Espèces");
        especes.setPourcentage(32.1);
        especes.setMontant(new BigDecimal("14690750"));
        especes.setCouleur("bg-green-500");
        especes.setIcon("pi-money-bill");
        repartitionMethodes.add(especes);
        
        RepartitionMethode cheque = new RepartitionMethode();
        cheque.setMethode("Chèque");
        cheque.setPourcentage(15.8);
        cheque.setMontant(new BigDecimal("7228500"));
        cheque.setCouleur("bg-orange-500");
        cheque.setIcon("pi-credit-card");
        repartitionMethodes.add(cheque);
        
        RepartitionMethode virement = new RepartitionMethode();
        virement.setMethode("Virement");
        virement.setPourcentage(6.9);
        virement.setMontant(new BigDecimal("3156750"));
        virement.setCouleur("bg-purple-500");
        virement.setIcon("pi-send");
        repartitionMethodes.add(virement);
    }
    
    private void initializeRappels() {
        rappelsEnAttente = new ArrayList<>();
        
        RappelCotisation rappel1 = new RappelCotisation();
        rappel1.setNomMembre("Jean Kouassi");
        rappel1.setClub("Association Alpha");
        rappel1.setMontantDu(new BigDecimal("150000"));
        rappel1.setJoursRetard(15);
        rappel1.setPriorite("HAUTE");
        rappelsEnAttente.add(rappel1);
        
        RappelCotisation rappel2 = new RappelCotisation();
        rappel2.setNomMembre("Marie Traoré");
        rappel2.setClub("Club Beta");
        rappel2.setMontantDu(new BigDecimal("125000"));
        rappel2.setJoursRetard(8);
        rappel2.setPriorite("MOYENNE");
        rappelsEnAttente.add(rappel2);
        
        RappelCotisation rappel3 = new RappelCotisation();
        rappel3.setNomMembre("Ahmed Diallo");
        rappel3.setClub("Groupe Gamma");
        rappel3.setMontantDu(new BigDecimal("100000"));
        rappel3.setJoursRetard(3);
        rappel3.setPriorite("FAIBLE");
        rappelsEnAttente.add(rappel3);
    }
    
    private void initializeCotisations() {
        toutesLesCotisations = new ArrayList<>();
        
        String[] membres = {
            "Jean Kouassi", "Marie Traoré", "Ahmed Diallo", "Fatou Sanogo", "Paul Ouattara",
            "Aissata Koné", "Ibrahim Touré", "Aminata Bakayoko", "Yves Koffi", "Mariam Coulibaly",
            "Seydou Cissé", "Adjoa Mensah", "Kwame Asante", "Ama Gyamfi", "Kofi Adjei"
        };
        
        String[] clubs = {
            "Association Alpha", "Club Beta", "Groupe Gamma",
            "Association Delta", "Club Epsilon", "Groupe Zeta",
            "Association Eta", "Club Theta", "Groupe Iota"
        };
        
        String[] types = {"MENSUELLE", "TRIMESTRIELLE", "ANNUELLE", "EXCEPTIONNELLE"};
        String[] statuts = {"PAYEE", "EN_ATTENTE", "EN_RETARD", "PARTIELLEMENT_PAYEE"};
        String[] methodes = {"WAVE_MONEY", "ESPECES", "CHEQUE", "VIREMENT"};
        
        BigDecimal[] montants = {
            new BigDecimal("150000"), new BigDecimal("125000"), new BigDecimal("100000"),
            new BigDecimal("175000"), new BigDecimal("200000"), new BigDecimal("75000"),
            new BigDecimal("120000"), new BigDecimal("180000"), new BigDecimal("95000")
        };
        
        for (int i = 0; i < 50; i++) {
            Cotisation cotisation = new Cotisation();
            cotisation.setId((long) (i + 1));
            cotisation.setNumeroMembre("M" + String.format("%04d", (i % membres.length) + 1));
            cotisation.setNomMembre(membres[i % membres.length]);
            cotisation.setClub(clubs[i % clubs.length]);
            cotisation.setTypeCotisation(types[i % types.length]);
            cotisation.setMontantDu(montants[i % montants.length]);
            
            if (i % 5 == 0) {
                cotisation.setStatut("EN_RETARD");
                cotisation.setMontantPaye(BigDecimal.ZERO);
            } else if (i % 8 == 0) {
                cotisation.setStatut("PARTIELLEMENT_PAYEE");
                cotisation.setMontantPaye(cotisation.getMontantDu().multiply(new BigDecimal("0.5")));
            } else if (i % 12 == 0) {
                cotisation.setStatut("EN_ATTENTE");
                cotisation.setMontantPaye(BigDecimal.ZERO);
            } else {
                cotisation.setStatut("PAYEE");
                cotisation.setMontantPaye(cotisation.getMontantDu());
            }
            
            cotisation.setMethodePaiement(methodes[i % methodes.length]);
            cotisation.setDateEcheance(LocalDate.now().minusDays(i * 2).plusMonths(1));
            
            if (!cotisation.getStatut().equals("EN_ATTENTE")) {
                cotisation.setDatePaiement(LocalDateTime.now().minusDays(i + 1));
            }
            
            cotisation.setObservations(i % 7 == 0 ? "Paiement en plusieurs fois autorisé" : "");
            
            toutesLesCotisations.add(cotisation);
        }
    }
    
    private void initializeNouvelleCotisation() {
        nouvelleCotisation = new NouvelleCotisation();
    }
    
    private void appliquerFiltres() {
        cotisationsFiltrees = toutesLesCotisations.stream()
                .filter(this::appliquerFiltre)
                .collect(Collectors.toList());
    }
    
    private boolean appliquerFiltre(Cotisation cotisation) {
        if (filtres.getNomMembre() != null && !filtres.getNomMembre().trim().isEmpty()) {
            if (!cotisation.getNomMembre().toLowerCase().contains(filtres.getNomMembre().toLowerCase())) {
                return false;
            }
        }
        
        if (filtres.getClub() != null && !filtres.getClub().trim().isEmpty()) {
            if (!cotisation.getClub().toLowerCase().contains(filtres.getClub().toLowerCase())) {
                return false;
            }
        }
        
        if (filtres.getStatut() != null && !filtres.getStatut().trim().isEmpty()) {
            if (!cotisation.getStatut().equals(filtres.getStatut())) {
                return false;
            }
        }
        
        if (filtres.getTypeCotisation() != null && !filtres.getTypeCotisation().trim().isEmpty()) {
            if (!cotisation.getTypeCotisation().equals(filtres.getTypeCotisation())) {
                return false;
            }
        }
        
        if (filtres.getMethodePaiement() != null && !filtres.getMethodePaiement().trim().isEmpty()) {
            if (!cotisation.getMethodePaiement().equals(filtres.getMethodePaiement())) {
                return false;
            }
        }
        
        if (filtres.getDateDebut() != null) {
            if (cotisation.getDateEcheance().isBefore(filtres.getDateDebut())) {
                return false;
            }
        }
        
        if (filtres.getDateFin() != null) {
            if (cotisation.getDateEcheance().isAfter(filtres.getDateFin())) {
                return false;
            }
        }
        
        return true;
    }
    
    // Actions
    public void rechercher() {
        appliquerFiltres();
    }
    
    public void reinitialiserFiltres() {
        filtres = new Filtres();
        appliquerFiltres();
    }
    
    public void enregistrerCotisation() {
        Cotisation nouvelleCot = new Cotisation();
        nouvelleCot.setId((long) (toutesLesCotisations.size() + 1));
        nouvelleCot.setNumeroMembre(nouvelleCotisation.getNumeroMembre());
        nouvelleCot.setNomMembre(nouvelleCotisation.getNomMembre());
        nouvelleCot.setClub(nouvelleCotisation.getClub());
        nouvelleCot.setTypeCotisation(nouvelleCotisation.getTypeCotisation());
        nouvelleCot.setMontantDu(nouvelleCotisation.getMontantDu());
        nouvelleCot.setDateEcheance(nouvelleCotisation.getDateEcheance());
        nouvelleCot.setStatut("EN_ATTENTE");
        nouvelleCot.setMontantPaye(BigDecimal.ZERO);
        nouvelleCot.setObservations(nouvelleCotisation.getObservations());
        
        toutesLesCotisations.add(nouvelleCot);
        appliquerFiltres();
        
        System.out.println("Nouvelle cotisation enregistrée pour: " + nouvelleCot.getNomMembre());
        initializeNouvelleCotisation();
    }
    
    public void marquerCommePaye() {
        if (cotisationSelectionnee != null) {
            cotisationSelectionnee.setStatut("PAYEE");
            cotisationSelectionnee.setMontantPaye(cotisationSelectionnee.getMontantDu());
            cotisationSelectionnee.setDatePaiement(LocalDateTime.now());
            System.out.println("Cotisation marquée comme payée: " + cotisationSelectionnee.getNomMembre());
        }
    }
    
    public void enregistrerPaiementPartiel() {
        if (cotisationSelectionnee != null) {
            cotisationSelectionnee.setStatut("PARTIELLEMENT_PAYEE");
            cotisationSelectionnee.setDatePaiement(LocalDateTime.now());
            System.out.println("Paiement partiel enregistré: " + cotisationSelectionnee.getNomMembre());
        }
    }
    
    public void envoyerRappel() {
        if (cotisationSelectionnee != null) {
            System.out.println("Rappel envoyé à: " + cotisationSelectionnee.getNomMembre());
        }
    }
    
    public void envoyerRappelsGroupes() {
        System.out.println("Rappels envoyés à " + cotisationsSelectionnees.size() + " membres");
    }
    
    public void exporterCotisations() {
        System.out.println("Export de " + cotisationsFiltrees.size() + " cotisations");
    }
    
    public void genererRapportFinancier() {
        System.out.println("Rapport financier généré");
    }
    
    // Getters et Setters
    public List<Cotisation> getToutesLesCotisations() { return toutesLesCotisations; }
    public void setToutesLesCotisations(List<Cotisation> toutesLesCotisations) { this.toutesLesCotisations = toutesLesCotisations; }
    
    public List<Cotisation> getCotisationsFiltrees() { return cotisationsFiltrees; }
    public void setCotisationsFiltrees(List<Cotisation> cotisationsFiltrees) { this.cotisationsFiltrees = cotisationsFiltrees; }
    
    public List<Cotisation> getCotisationsSelectionnees() { return cotisationsSelectionnees; }
    public void setCotisationsSelectionnees(List<Cotisation> cotisationsSelectionnees) { this.cotisationsSelectionnees = cotisationsSelectionnees; }
    
    public Cotisation getCotisationSelectionnee() { return cotisationSelectionnee; }
    public void setCotisationSelectionnee(Cotisation cotisationSelectionnee) { this.cotisationSelectionnee = cotisationSelectionnee; }
    
    public NouvelleCotisation getNouvelleCotisation() { return nouvelleCotisation; }
    public void setNouvelleCotisation(NouvelleCotisation nouvelleCotisation) { this.nouvelleCotisation = nouvelleCotisation; }
    
    public Filtres getFiltres() { return filtres; }
    public void setFiltres(Filtres filtres) { this.filtres = filtres; }
    
    public StatistiquesFinancieres getStatistiques() { return statistiques; }
    public void setStatistiques(StatistiquesFinancieres statistiques) { this.statistiques = statistiques; }
    
    public List<EvolutionPaiement> getEvolutionPaiements() { return evolutionPaiements; }
    public void setEvolutionPaiements(List<EvolutionPaiement> evolutionPaiements) { this.evolutionPaiements = evolutionPaiements; }
    
    public List<RepartitionMethode> getRepartitionMethodes() { return repartitionMethodes; }
    public void setRepartitionMethodes(List<RepartitionMethode> repartitionMethodes) { this.repartitionMethodes = repartitionMethodes; }
    
    public List<RappelCotisation> getRappelsEnAttente() { return rappelsEnAttente; }
    public void setRappelsEnAttente(List<RappelCotisation> rappelsEnAttente) { this.rappelsEnAttente = rappelsEnAttente; }
    
    // Classes internes
    public static class Cotisation {
        private Long id;
        private String numeroMembre;
        private String nomMembre;
        private String club;
        private String typeCotisation;
        private BigDecimal montantDu;
        private BigDecimal montantPaye;
        private String statut;
        private String methodePaiement;
        private LocalDate dateEcheance;
        private LocalDateTime datePaiement;
        private String observations;
        
        // Getters et setters
        public Long getId() { return id; }
        public void setId(Long id) { this.id = id; }
        
        public String getNumeroMembre() { return numeroMembre; }
        public void setNumeroMembre(String numeroMembre) { this.numeroMembre = numeroMembre; }
        
        public String getNomMembre() { return nomMembre; }
        public void setNomMembre(String nomMembre) { this.nomMembre = nomMembre; }
        
        public String getClub() { return club; }
        public void setClub(String club) { this.club = club; }
        
        public String getTypeCotisation() { return typeCotisation; }
        public void setTypeCotisation(String typeCotisation) { this.typeCotisation = typeCotisation; }
        
        public BigDecimal getMontantDu() { return montantDu; }
        public void setMontantDu(BigDecimal montantDu) { this.montantDu = montantDu; }
        
        public BigDecimal getMontantPaye() { return montantPaye; }
        public void setMontantPaye(BigDecimal montantPaye) { this.montantPaye = montantPaye; }
        
        public String getStatut() { return statut; }
        public void setStatut(String statut) { this.statut = statut; }
        
        public String getMethodePaiement() { return methodePaiement; }
        public void setMethodePaiement(String methodePaiement) { this.methodePaiement = methodePaiement; }
        
        public LocalDate getDateEcheance() { return dateEcheance; }
        public void setDateEcheance(LocalDate dateEcheance) { this.dateEcheance = dateEcheance; }
        
        public LocalDateTime getDatePaiement() { return datePaiement; }
        public void setDatePaiement(LocalDateTime datePaiement) { this.datePaiement = datePaiement; }
        
        public String getObservations() { return observations; }
        public void setObservations(String observations) { this.observations = observations; }
        
        // Propriétés dérivées
        public String getStatutSeverity() {
            return switch (statut) {
                case "PAYEE" -> "success";
                case "EN_ATTENTE" -> "warning";
                case "EN_RETARD" -> "danger";
                case "PARTIELLEMENT_PAYEE" -> "info";
                default -> "secondary";
            };
        }
        
        public String getStatutIcon() {
            return switch (statut) {
                case "PAYEE" -> "pi-check";
                case "EN_ATTENTE" -> "pi-clock";
                case "EN_RETARD" -> "pi-exclamation-triangle";
                case "PARTIELLEMENT_PAYEE" -> "pi-minus";
                default -> "pi-circle";
            };
        }
        
        public String getMethodePaiementLibelle() {
            return switch (methodePaiement) {
                case "WAVE_MONEY" -> "Wave Money";
                case "ESPECES" -> "Espèces";
                case "CHEQUE" -> "Chèque";
                case "VIREMENT" -> "Virement";
                default -> methodePaiement;
            };
        }
        
        public String getTypeCotisationLibelle() {
            return switch (typeCotisation) {
                case "MENSUELLE" -> "Mensuelle";
                case "TRIMESTRIELLE" -> "Trimestrielle";
                case "ANNUELLE" -> "Annuelle";
                case "EXCEPTIONNELLE" -> "Exceptionnelle";
                default -> typeCotisation;
            };
        }
        
        public String getDateEcheanceFormatee() {
            if (dateEcheance == null) return "";
            return dateEcheance.format(DateTimeFormatter.ofPattern("dd/MM/yyyy"));
        }
        
        public String getDatePaiementFormatee() {
            if (datePaiement == null) return "";
            return datePaiement.format(DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm"));
        }
        
        public String getMontantDuFormatte() {
            return String.format("%,.0f FCFA", montantDu);
        }
        
        public String getMontantPayeFormatte() {
            return String.format("%,.0f FCFA", montantPaye);
        }
        
        public BigDecimal getMontantRestant() {
            return montantDu.subtract(montantPaye);
        }
        
        public String getMontantRestantFormatte() {
            return String.format("%,.0f FCFA", getMontantRestant());
        }
        
        public int getPourcentagePaye() {
            if (montantDu.equals(BigDecimal.ZERO)) return 0;
            return montantPaye.multiply(new BigDecimal("100")).divide(montantDu, 0, BigDecimal.ROUND_HALF_UP).intValue();
        }
        
        public long getJoursRetard() {
            if (dateEcheance == null || !statut.equals("EN_RETARD")) return 0;
            return ChronoUnit.DAYS.between(dateEcheance, LocalDate.now());
        }
    }
    
    public static class NouvelleCotisation {
        private String numeroMembre;
        private String nomMembre;
        private String club;
        private String typeCotisation;
        private BigDecimal montantDu;
        private LocalDate dateEcheance;
        private String observations;
        
        // Getters et setters
        public String getNumeroMembre() { return numeroMembre; }
        public void setNumeroMembre(String numeroMembre) { this.numeroMembre = numeroMembre; }
        
        public String getNomMembre() { return nomMembre; }
        public void setNomMembre(String nomMembre) { this.nomMembre = nomMembre; }
        
        public String getClub() { return club; }
        public void setClub(String club) { this.club = club; }
        
        public String getTypeCotisation() { return typeCotisation; }
        public void setTypeCotisation(String typeCotisation) { this.typeCotisation = typeCotisation; }
        
        public BigDecimal getMontantDu() { return montantDu; }
        public void setMontantDu(BigDecimal montantDu) { this.montantDu = montantDu; }
        
        public LocalDate getDateEcheance() { return dateEcheance; }
        public void setDateEcheance(LocalDate dateEcheance) { this.dateEcheance = dateEcheance; }
        
        public String getObservations() { return observations; }
        public void setObservations(String observations) { this.observations = observations; }
    }
    
    public static class Filtres {
        private String nomMembre;
        private String club;
        private String statut;
        private String typeCotisation;
        private String methodePaiement;
        private LocalDate dateDebut;
        private LocalDate dateFin;
        
        // Getters et setters
        public String getNomMembre() { return nomMembre; }
        public void setNomMembre(String nomMembre) { this.nomMembre = nomMembre; }
        
        public String getClub() { return club; }
        public void setClub(String club) { this.club = club; }
        
        public String getStatut() { return statut; }
        public void setStatut(String statut) { this.statut = statut; }
        
        public String getTypeCotisation() { return typeCotisation; }
        public void setTypeCotisation(String typeCotisation) { this.typeCotisation = typeCotisation; }
        
        public String getMethodePaiement() { return methodePaiement; }
        public void setMethodePaiement(String methodePaiement) { this.methodePaiement = methodePaiement; }
        
        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 StatistiquesFinancieres {
        private BigDecimal totalCollecte;
        private BigDecimal objectifAnnuel;
        private double tauxRecouvrement;
        private int cotisationsEnRetard;
        private BigDecimal montantRetard;
        private BigDecimal moyenneMensuelle;
        
        // Getters et setters
        public BigDecimal getTotalCollecte() { return totalCollecte; }
        public void setTotalCollecte(BigDecimal totalCollecte) { this.totalCollecte = totalCollecte; }
        
        public BigDecimal getObjectifAnnuel() { return objectifAnnuel; }
        public void setObjectifAnnuel(BigDecimal objectifAnnuel) { this.objectifAnnuel = objectifAnnuel; }
        
        public double getTauxRecouvrement() { return tauxRecouvrement; }
        public void setTauxRecouvrement(double tauxRecouvrement) { this.tauxRecouvrement = tauxRecouvrement; }
        
        public int getCotisationsEnRetard() { return cotisationsEnRetard; }
        public void setCotisationsEnRetard(int cotisationsEnRetard) { this.cotisationsEnRetard = cotisationsEnRetard; }
        
        public BigDecimal getMontantRetard() { return montantRetard; }
        public void setMontantRetard(BigDecimal montantRetard) { this.montantRetard = montantRetard; }
        
        public BigDecimal getMoyenneMensuelle() { return moyenneMensuelle; }
        public void setMoyenneMensuelle(BigDecimal moyenneMensuelle) { this.moyenneMensuelle = moyenneMensuelle; }
        
        // Méthodes de formatage
        public String getTotalCollecteFormatte() {
            return String.format("%,.0f FCFA", totalCollecte);
        }
        
        public String getObjectifAnnuelFormatte() {
            return String.format("%,.0f FCFA", objectifAnnuel);
        }
        
        public String getMontantRetardFormatte() {
            return String.format("%,.0f FCFA", montantRetard);
        }
        
        public String getMoyenneMensuelleFormattee() {
            return String.format("%,.0f FCFA", moyenneMensuelle);
        }
        
        public int getTauxRecouvrementInt() {
            return (int) tauxRecouvrement;
        }
    }
    
    public static class EvolutionPaiement {
        private String mois;
        private BigDecimal montant;
        private int hauteur;
        
        // Getters et setters
        public String getMois() { return mois; }
        public void setMois(String mois) { this.mois = mois; }
        
        public BigDecimal getMontant() { return montant; }
        public void setMontant(BigDecimal montant) { this.montant = montant; }
        
        public int getHauteur() { return hauteur; }
        public void setHauteur(int hauteur) { this.hauteur = hauteur; }
        
        public String getMontantFormatte() {
            return String.format("%.1fM", montant.divide(new BigDecimal("1000000")).doubleValue());
        }
    }
    
    public static class RepartitionMethode {
        private String methode;
        private double pourcentage;
        private BigDecimal montant;
        private String couleur;
        private String icon;
        
        // Getters et setters
        public String getMethode() { return methode; }
        public void setMethode(String methode) { this.methode = methode; }
        
        public double getPourcentage() { return pourcentage; }
        public void setPourcentage(double pourcentage) { this.pourcentage = pourcentage; }
        
        public BigDecimal getMontant() { return montant; }
        public void setMontant(BigDecimal montant) { this.montant = montant; }
        
        public String getCouleur() { return couleur; }
        public void setCouleur(String couleur) { this.couleur = couleur; }
        
        public String getIcon() { return icon; }
        public void setIcon(String icon) { this.icon = icon; }
        
        public String getMontantFormatte() {
            return String.format("%,.0f FCFA", montant);
        }
        
        public int getPourcentageInt() {
            return (int) pourcentage;
        }
        
        public int getLargeur() {
            return (int) (pourcentage * 2);
        }
    }
    
    public static class RappelCotisation {
        private String nomMembre;
        private String club;
        private BigDecimal montantDu;
        private int joursRetard;
        private String priorite;
        
        // Getters et setters
        public String getNomMembre() { return nomMembre; }
        public void setNomMembre(String nomMembre) { this.nomMembre = nomMembre; }
        
        public String getClub() { return club; }
        public void setClub(String club) { this.club = club; }
        
        public BigDecimal getMontantDu() { return montantDu; }
        public void setMontantDu(BigDecimal montantDu) { this.montantDu = montantDu; }
        
        public int getJoursRetard() { return joursRetard; }
        public void setJoursRetard(int joursRetard) { this.joursRetard = joursRetard; }
        
        public String getPriorite() { return priorite; }
        public void setPriorite(String priorite) { this.priorite = priorite; }
        
        public String getMontantDuFormatte() {
            return String.format("%,.0f FCFA", montantDu);
        }
        
        public String getPrioriteSeverity() {
            return switch (priorite) {
                case "HAUTE" -> "danger";
                case "MOYENNE" -> "warning";
                case "FAIBLE" -> "info";
                default -> "secondary";
            };
        }
    }
}