package dev.lions.unionflow.client.view;

import dev.lions.unionflow.server.api.dto.membre.response.MembreResponse;
import dev.lions.unionflow.server.api.dto.membre.response.MembreSummaryResponse;
import dev.lions.unionflow.server.api.dto.common.PagedResponse;
import dev.lions.unionflow.client.service.MembreService;
import dev.lions.unionflow.client.service.OrganisationService;
import dev.lions.unionflow.server.api.dto.organisation.response.OrganisationSummaryResponse;
import jakarta.enterprise.context.SessionScoped;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import jakarta.annotation.PostConstruct;
import org.eclipse.microprofile.rest.client.inject.RestClient;
import java.io.Serializable;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
import org.jboss.logging.Logger;

@Named("membreRechercheBean")
@SessionScoped
public class MembreRechercheBean implements Serializable {

    private static final long serialVersionUID = 1L;
    private static final Logger LOG = Logger.getLogger(MembreRechercheBean.class);

    // Constantes de navigation outcomes (WOU/DRY - réutilisables)
    private static final String OUTCOME_MEMBRE_PROFIL = "membreProfilPage";

    @Inject
    @RestClient
    private MembreService membreService;

    @Inject
    @RestClient
    private OrganisationService organisationService;

    private Filtres filtres;
    private Statistiques statistiques;
    private List<Membre> resultats;
    private List<Membre> selectedMembres;
    private List<Membre> tousLesMembres;
    private List<Entite> entitesDisponibles;
    private List<RechercheSauvegardee> recherchesSauvegardees;
    private RechercheSauvegardee nouvelleRechercheSauvegardee;
    private MessageGroupe messageGroupe;

    @PostConstruct
    public void init() {
        initializeFiltres();
        initializeStatistiques();
        initializeDonnees();
        initializeEntites();
        initializeRecherchesSauvegardees();
        initializeMessageGroupe();
        effectuerRecherche();
    }

    private void initializeFiltres() {
        filtres = new Filtres();
        filtres.setStatuts(new ArrayList<>());
        filtres.setTypesMembre(new ArrayList<>());
        filtres.setEntites(new ArrayList<UUID>());
        filtres.setStatutsCotisation(new ArrayList<>());
        filtres.setGenres(new ArrayList<>());
    }

    private void initializeStatistiques() {
        statistiques = new Statistiques();
        try {
            List<MembreSummaryResponse> membres = membreService.listerTous().getData();
            statistiques.setTotalMembres(membres.size());
        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors du calcul des statistiques");
            statistiques.setTotalMembres(0);
        }
        statistiques.setResultatsActuels(0);
        statistiques.setFiltresActifs(0);
        statistiques.setTempsRecherche(0);
    }

    private void initializeDonnees() {
        tousLesMembres = new ArrayList<>();
        selectedMembres = new ArrayList<>();

        try {
            List<MembreSummaryResponse> membresDTO = membreService.listerTous().getData();
            for (MembreSummaryResponse dto : membresDTO) {
                Membre membre = convertToMembre(dto);
                tousLesMembres.add(membre);
            }
            resultats = new ArrayList<>(tousLesMembres);
        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors du chargement des membres");
            resultats = new ArrayList<>();
        }
    }

    private Membre convertToMembre(MembreResponse dto) {
        Membre membre = new Membre();
        membre.setId(dto.getId());
        membre.setNumeroMembre(dto.getNumeroMembre());
        membre.setNom(dto.getNom());
        membre.setPrenom(dto.getPrenom());
        membre.setEmail(dto.getEmail());
        membre.setTelephone(dto.getTelephone());
        membre.setProfession(dto.getProfession());
        membre.setVille("");
        membre.setTypeMembre("ACTIF");
        if (dto.getStatutCompte() != null) {
            membre.setStatut(dto.getStatutCompte());
        } else {
            membre.setStatut("ACTIF");
        }
        membre.setDateAdhesion(dto.getDateAdhesion());
        membre.setCotisationStatut("N/A");
        return membre;
    }

    private Membre convertToMembre(MembreSummaryResponse dto) {
        Membre membre = new Membre();
        membre.setId(dto.getId());
        membre.setNumeroMembre(dto.getNumeroMembre());
        membre.setNom(dto.getNom());
        membre.setPrenom(dto.getPrenom());
        membre.setEmail(dto.getEmail());
        membre.setTelephone(dto.getTelephone());
        membre.setProfession(dto.getProfession());
        membre.setVille("");
        membre.setTypeMembre("ACTIF");
        if (dto.getStatutCompte() != null) {
            membre.setStatut(dto.getStatutCompte());
        } else {
            membre.setStatut("ACTIF");
        }
        membre.setDateAdhesion(dto.getDateAdhesion());
        membre.setCotisationStatut("N/A");
        return membre;
    }

    private void initializeEntites() {
        entitesDisponibles = new ArrayList<>();
        try {
            PagedResponse<OrganisationSummaryResponse> response = organisationService
                    .listerToutes(0, 1000);
            if (response != null && response.getData() != null) {
                for (dev.lions.unionflow.server.api.dto.organisation.response.OrganisationSummaryResponse assoc : response.getData()) {
                    Entite entite = new Entite();
                    entite.setId(assoc.getId());
                    entite.setNom(assoc.getNom());
                    entitesDisponibles.add(entite);
                }
            }
        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors du chargement des entités");
        }
    }

    private void initializeRecherchesSauvegardees() {
        recherchesSauvegardees = new ArrayList<>();
        nouvelleRechercheSauvegardee = new RechercheSauvegardee();
    }

    private void initializeMessageGroupe() {
        messageGroupe = new MessageGroupe();
        messageGroupe.setCanaux(new ArrayList<>());
    }

    // Actions principales
    public void effectuerRecherche() {
        long startTime = System.currentTimeMillis();

        try {
            List<MembreResponse> membresDTO = membreService.rechercher(
                    filtres.getNom(),
                    filtres.getPrenom(),
                    filtres.getEmail(),
                    filtres.getTelephone(),
                    filtres.getStatuts() != null && !filtres.getStatuts().isEmpty() ? filtres.getStatuts().get(0)
                            : null,
                    null,
                    0,
                    100);

            resultats = membresDTO.stream()
                    .map(this::convertToMembre)
                    .collect(Collectors.toList());
        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors de la recherche");
            resultats = new ArrayList<>();
        }

        long endTime = System.currentTimeMillis();

        // Mise à jour des statistiques
        statistiques.setResultatsActuels(resultats.size());
        statistiques.setFiltresActifs(compterFiltresActifs());
        statistiques.setTempsRecherche((int) (endTime - startTime));

        selectedMembres.clear();
    }

    private boolean appliquerFiltres(Membre membre) {
        // Filtre nom
        if (filtres.getNom() != null && !filtres.getNom().trim().isEmpty()) {
            if (!membre.getNom().toLowerCase().contains(filtres.getNom().toLowerCase())) {
                return false;
            }
        }

        // Filtre prénom
        if (filtres.getPrenom() != null && !filtres.getPrenom().trim().isEmpty()) {
            if (!membre.getPrenom().toLowerCase().contains(filtres.getPrenom().toLowerCase())) {
                return false;
            }
        }

        // Filtre email
        if (filtres.getEmail() != null && !filtres.getEmail().trim().isEmpty()) {
            if (!membre.getEmail().toLowerCase().contains(filtres.getEmail().toLowerCase())) {
                return false;
            }
        }

        // Filtre téléphone
        if (filtres.getTelephone() != null && !filtres.getTelephone().trim().isEmpty()) {
            if (membre.getTelephone() == null || !membre.getTelephone().contains(filtres.getTelephone())) {
                return false;
            }
        }

        // Filtre numéro membre
        if (filtres.getNumeroMembre() != null && !filtres.getNumeroMembre().trim().isEmpty()) {
            if (!membre.getNumeroMembre().toLowerCase().contains(filtres.getNumeroMembre().toLowerCase())) {
                return false;
            }
        }

        // Filtre profession
        if (filtres.getProfession() != null && !filtres.getProfession().trim().isEmpty()) {
            if (!membre.getProfession().toLowerCase().contains(filtres.getProfession().toLowerCase())) {
                return false;
            }
        }

        // Filtre statuts
        if (filtres.getStatuts() != null && !filtres.getStatuts().isEmpty()) {
            if (!filtres.getStatuts().contains(membre.getStatut())) {
                return false;
            }
        }

        // Filtre types membre
        if (filtres.getTypesMembre() != null && !filtres.getTypesMembre().isEmpty()) {
            if (!filtres.getTypesMembre().contains(membre.getTypeMembre())) {
                return false;
            }
        }

        // Filtre âge
        if (filtres.getAgeMin() != null && membre.getAge() < filtres.getAgeMin()) {
            return false;
        }
        if (filtres.getAgeMax() != null && membre.getAge() > filtres.getAgeMax()) {
            return false;
        }

        // Filtre ville
        if (filtres.getVille() != null && !filtres.getVille().trim().isEmpty()) {
            if (!membre.getVille().toLowerCase().contains(filtres.getVille().toLowerCase())) {
                return false;
            }
        }

        // Filtre genres
        if (filtres.getGenres() != null && !filtres.getGenres().isEmpty()) {
            if (!filtres.getGenres().contains(membre.getGenre())) {
                return false;
            }
        }

        // Filtre taux participation
        if (filtres.getTauxParticipationMin() != null
                && membre.getTauxParticipation() < filtres.getTauxParticipationMin()) {
            return false;
        }

        // Filtre événements min
        if (filtres.getEvenementsMin() != null && membre.getEvenementsAnnee() < filtres.getEvenementsMin()) {
            return false;
        }

        // Filtre a des enfants
        if (filtres.getADesEnfants() != null && filtres.getADesEnfants() && !membre.isADesEnfants()) {
            return false;
        }

        // Filtre a reçu aides
        if (filtres.getARecuAides() != null && filtres.getARecuAides() && !membre.isARecuAides()) {
            return false;
        }

        // Filtre dates d'adhésion
        if (filtres.getDateAdhesionDebut() != null && membre.getDateAdhesion() != null
                && membre.getDateAdhesion().isBefore(filtres.getDateAdhesionDebut())) {
            return false;
        }
        if (filtres.getDateAdhesionFin() != null && membre.getDateAdhesion() != null
                && membre.getDateAdhesion().isAfter(filtres.getDateAdhesionFin())) {
            return false;
        }

        return true;
    }

    private int compterFiltresActifs() {
        int count = 0;

        if (filtres.getNom() != null && !filtres.getNom().trim().isEmpty())
            count++;
        if (filtres.getPrenom() != null && !filtres.getPrenom().trim().isEmpty())
            count++;
        if (filtres.getEmail() != null && !filtres.getEmail().trim().isEmpty())
            count++;
        if (filtres.getTelephone() != null && !filtres.getTelephone().trim().isEmpty())
            count++;
        if (filtres.getNumeroMembre() != null && !filtres.getNumeroMembre().trim().isEmpty())
            count++;
        if (filtres.getProfession() != null && !filtres.getProfession().trim().isEmpty())
            count++;
        if (filtres.getStatuts() != null && !filtres.getStatuts().isEmpty())
            count++;
        if (filtres.getTypesMembre() != null && !filtres.getTypesMembre().isEmpty())
            count++;
        if (filtres.getAgeMin() != null)
            count++;
        if (filtres.getAgeMax() != null)
            count++;
        if (filtres.getVille() != null && !filtres.getVille().trim().isEmpty())
            count++;
        if (filtres.getGenres() != null && !filtres.getGenres().isEmpty())
            count++;
        if (filtres.getTauxParticipationMin() != null)
            count++;
        if (filtres.getEvenementsMin() != null)
            count++;
        if (filtres.getCotisationsMin() != null)
            count++;
        if (filtres.getADesEnfants() != null && filtres.getADesEnfants())
            count++;
        if (filtres.getARecuAides() != null && filtres.getARecuAides())
            count++;
        if (filtres.getDateAdhesionDebut() != null)
            count++;
        if (filtres.getDateAdhesionFin() != null)
            count++;

        return count;
    }

    public void reinitialiserFiltres() {
        initializeFiltres();
        effectuerRecherche();
    }

    public void actualiserResultats() {
        effectuerRecherche();
    }

    public void nouvelleRecherche() {
        reinitialiserFiltres();
    }

    // Actions sur les membres
    public String voirProfil(Membre membre) {
        // Utilisation de navigation outcome au lieu de chemin direct (WOU/DRY)
        return OUTCOME_MEMBRE_PROFIL + "?id=" + membre.getId() + "&faces-redirect=true";
    }

    public void contacterMembre(Membre membre) {
        LOG.infof("Contacter le membre: %s", membre.getNomComplet());
    }

    public void ajouterAuGroupe(Membre membre) {
        LOG.infof("Ajouter au groupe: %s", membre.getNomComplet());
    }

    // Gestion des recherches sauvegardées
    public void sauvegarderRecherche() {
        nouvelleRechercheSauvegardee.setId(UUID.randomUUID());
        nouvelleRechercheSauvegardee.setNombreCriteres(compterFiltresActifs());
        nouvelleRechercheSauvegardee.setDateCreation(LocalDate.now());

        recherchesSauvegardees.add(nouvelleRechercheSauvegardee);

        LOG.infof("Recherche sauvegardée: %s", nouvelleRechercheSauvegardee.getNom());

        nouvelleRechercheSauvegardee = new RechercheSauvegardee();
    }

    public void chargerRecherche(RechercheSauvegardee recherche) {
        // Simuler le chargement des critères
        reinitialiserFiltres();

        if (recherche.getNom().contains("actifs")) {
            filtres.getStatuts().add("ACTIF");
        }
        if (recherche.getNom().contains("retard")) {
            filtres.getStatutsCotisation().add("EN_RETARD");
        }

        effectuerRecherche();
        LOG.infof("Recherche chargée: %s", recherche.getNom());
    }

    public void supprimerRecherche(RechercheSauvegardee recherche) {
        recherchesSauvegardees.remove(recherche);
        LOG.infof("Recherche supprimée: %s", recherche.getNom());
    }

    // Actions groupées
    public void envoyerMessageGroupe() {
        LOG.infof("Message '%s' envoyé à %d membres via %s",
                messageGroupe.getSujet(), selectedMembres.size(), messageGroupe.getCanaux());

        messageGroupe = new MessageGroupe();
        messageGroupe.setCanaux(new ArrayList<>());
    }

    public void exporterSelection() {
        LOG.infof("Export de %d membres sélectionnés", selectedMembres.size());
    }

    // Méthodes d'autocomplétion
    public List<String> completerProfessions(String query) {
        List<String> professions = List.of("Enseignant", "Médecin", "Ingénieur", "Commerçant", "Agriculteur",
                "Fonctionnaire", "Artisan", "Avocat", "Architecte", "Pharmacien");
        return professions.stream()
                .filter(profession -> profession.toLowerCase().contains(query.toLowerCase()))
                .collect(Collectors.toList());
    }

    public List<String> completerVilles(String query) {
        List<String> villes = List.of("Dakar", "Thiès", "Kaolack", "Saint-Louis", "Ziguinchor",
                "Diourbel", "Tambacounda", "Kolda", "Fatick", "Louga");
        return villes.stream()
                .filter(ville -> ville.toLowerCase().contains(query.toLowerCase()))
                .collect(Collectors.toList());
    }

    // Getters et Setters
    public Filtres getFiltres() {
        return filtres;
    }

    public void setFiltres(Filtres filtres) {
        this.filtres = filtres;
    }

    public Statistiques getStatistiques() {
        return statistiques;
    }

    public void setStatistiques(Statistiques statistiques) {
        this.statistiques = statistiques;
    }

    public List<Membre> getResultats() {
        return resultats;
    }

    public void setResultats(List<Membre> resultats) {
        this.resultats = resultats;
    }

    public List<Membre> getSelectedMembres() {
        return selectedMembres;
    }

    public void setSelectedMembres(List<Membre> selectedMembres) {
        this.selectedMembres = selectedMembres;
    }

    public List<Entite> getEntitesDisponibles() {
        return entitesDisponibles;
    }

    public void setEntitesDisponibles(List<Entite> entitesDisponibles) {
        this.entitesDisponibles = entitesDisponibles;
    }

    public List<RechercheSauvegardee> getRecherchesSauvegardees() {
        return recherchesSauvegardees;
    }

    public void setRecherchesSauvegardees(List<RechercheSauvegardee> recherchesSauvegardees) {
        this.recherchesSauvegardees = recherchesSauvegardees;
    }

    public RechercheSauvegardee getNouvelleRechercheSauvegardee() {
        return nouvelleRechercheSauvegardee;
    }

    public void setNouvelleRechercheSauvegardee(RechercheSauvegardee nouvelleRechercheSauvegardee) {
        this.nouvelleRechercheSauvegardee = nouvelleRechercheSauvegardee;
    }

    public MessageGroupe getMessageGroupe() {
        return messageGroupe;
    }

    public void setMessageGroupe(MessageGroupe messageGroupe) {
        this.messageGroupe = messageGroupe;
    }

    // Classes internes
    public static class Filtres {
        private String nom;
        private String prenom;
        private String email;
        private String telephone;
        private String numeroMembre;
        private String profession;
        private List<String> statuts = new ArrayList<>();
        private List<String> typesMembre = new ArrayList<>();
        private List<UUID> entites = new ArrayList<>();
        private List<String> statutsCotisation = new ArrayList<>();
        private List<String> genres = new ArrayList<>();
        private Integer ageMin;
        private Integer ageMax;
        private String ville;
        private LocalDate dateAdhesionDebut;
        private LocalDate dateAdhesionFin;
        private Integer tauxParticipationMin;
        private Integer evenementsMin;
        private Integer cotisationsMin;
        private Boolean aDesEnfants;
        private Boolean aRecuAides;

        // Getters et setters
        public String getNom() {
            return nom;
        }

        public void setNom(String nom) {
            this.nom = nom;
        }

        public String getPrenom() {
            return prenom;
        }

        public void setPrenom(String prenom) {
            this.prenom = prenom;
        }

        public String getEmail() {
            return email;
        }

        public void setEmail(String email) {
            this.email = email;
        }

        public String getTelephone() {
            return telephone;
        }

        public void setTelephone(String telephone) {
            this.telephone = telephone;
        }

        public String getNumeroMembre() {
            return numeroMembre;
        }

        public void setNumeroMembre(String numeroMembre) {
            this.numeroMembre = numeroMembre;
        }

        public String getProfession() {
            return profession;
        }

        public void setProfession(String profession) {
            this.profession = profession;
        }

        public List<String> getStatuts() {
            return statuts;
        }

        public void setStatuts(List<String> statuts) {
            this.statuts = statuts;
        }

        public List<String> getTypesMembre() {
            return typesMembre;
        }

        public void setTypesMembre(List<String> typesMembre) {
            this.typesMembre = typesMembre;
        }

        public List<UUID> getEntites() {
            return entites;
        }

        public void setEntites(List<UUID> entites) {
            this.entites = entites;
        }

        public List<String> getStatutsCotisation() {
            return statutsCotisation;
        }

        public void setStatutsCotisation(List<String> statutsCotisation) {
            this.statutsCotisation = statutsCotisation;
        }

        public List<String> getGenres() {
            return genres;
        }

        public void setGenres(List<String> genres) {
            this.genres = genres;
        }

        public Integer getAgeMin() {
            return ageMin;
        }

        public void setAgeMin(Integer ageMin) {
            this.ageMin = ageMin;
        }

        public Integer getAgeMax() {
            return ageMax;
        }

        public void setAgeMax(Integer ageMax) {
            this.ageMax = ageMax;
        }

        public String getVille() {
            return ville;
        }

        public void setVille(String ville) {
            this.ville = ville;
        }

        public LocalDate getDateAdhesionDebut() {
            return dateAdhesionDebut;
        }

        public void setDateAdhesionDebut(LocalDate dateAdhesionDebut) {
            this.dateAdhesionDebut = dateAdhesionDebut;
        }

        public LocalDate getDateAdhesionFin() {
            return dateAdhesionFin;
        }

        public void setDateAdhesionFin(LocalDate dateAdhesionFin) {
            this.dateAdhesionFin = dateAdhesionFin;
        }

        public Integer getTauxParticipationMin() {
            return tauxParticipationMin;
        }

        public void setTauxParticipationMin(Integer tauxParticipationMin) {
            this.tauxParticipationMin = tauxParticipationMin;
        }

        public Integer getEvenementsMin() {
            return evenementsMin;
        }

        public void setEvenementsMin(Integer evenementsMin) {
            this.evenementsMin = evenementsMin;
        }

        public Integer getCotisationsMin() {
            return cotisationsMin;
        }

        public void setCotisationsMin(Integer cotisationsMin) {
            this.cotisationsMin = cotisationsMin;
        }

        // Getter pour JSF/EL - utilise is* pour les booléens
        public Boolean isADesEnfants() {
            return aDesEnfants;
        }

        public Boolean getADesEnfants() {
            return aDesEnfants;
        }

        public void setADesEnfants(Boolean aDesEnfants) {
            this.aDesEnfants = aDesEnfants;
        }

        // Getter pour JSF/EL - utilise is* pour les booléens
        public Boolean isARecuAides() {
            return aRecuAides;
        }

        public Boolean getARecuAides() {
            return aRecuAides;
        }

        public void setARecuAides(Boolean aRecuAides) {
            this.aRecuAides = aRecuAides;
        }
    }

    public static class Statistiques {
        private int totalMembres;
        private int resultatsActuels;
        private int filtresActifs;
        private int tempsRecherche;

        // Getters et setters
        public int getTotalMembres() {
            return totalMembres;
        }

        public void setTotalMembres(int totalMembres) {
            this.totalMembres = totalMembres;
        }

        public int getResultatsActuels() {
            return resultatsActuels;
        }

        public void setResultatsActuels(int resultatsActuels) {
            this.resultatsActuels = resultatsActuels;
        }

        public int getFiltresActifs() {
            return filtresActifs;
        }

        public void setFiltresActifs(int filtresActifs) {
            this.filtresActifs = filtresActifs;
        }

        public int getTempsRecherche() {
            return tempsRecherche;
        }

        public void setTempsRecherche(int tempsRecherche) {
            this.tempsRecherche = tempsRecherche;
        }
    }

    public static class Membre {
        private UUID id;
        private String numeroMembre;
        private String nom;
        private String prenom;
        private String email;
        private String telephone;
        private String profession;
        private String ville;
        private String typeMembre;
        private String statut;
        private String entite;
        private LocalDate dateAdhesion;
        private String cotisationStatut;
        private int tauxParticipation;
        private int evenementsAnnee;
        private String photoUrl;
        private String genre;
        private int age;
        private boolean aDesEnfants;
        private boolean aRecuAides;

        // Getters et setters
        public UUID getId() {
            return id;
        }

        public void setId(UUID id) {
            this.id = id;
        }

        public String getNumeroMembre() {
            return numeroMembre;
        }

        public void setNumeroMembre(String numeroMembre) {
            this.numeroMembre = numeroMembre;
        }

        public String getNom() {
            return nom;
        }

        public void setNom(String nom) {
            this.nom = nom;
        }

        public String getPrenom() {
            return prenom;
        }

        public void setPrenom(String prenom) {
            this.prenom = prenom;
        }

        public String getEmail() {
            return email;
        }

        public void setEmail(String email) {
            this.email = email;
        }

        public String getTelephone() {
            return telephone;
        }

        public void setTelephone(String telephone) {
            this.telephone = telephone;
        }

        public String getProfession() {
            return profession;
        }

        public void setProfession(String profession) {
            this.profession = profession;
        }

        public String getVille() {
            return ville;
        }

        public void setVille(String ville) {
            this.ville = ville;
        }

        public String getTypeMembre() {
            return typeMembre;
        }

        public void setTypeMembre(String typeMembre) {
            this.typeMembre = typeMembre;
        }

        public String getStatut() {
            return statut;
        }

        public void setStatut(String statut) {
            this.statut = statut;
        }

        public String getEntite() {
            return entite;
        }

        public void setEntite(String entite) {
            this.entite = entite;
        }

        public LocalDate getDateAdhesion() {
            return dateAdhesion;
        }

        public void setDateAdhesion(LocalDate dateAdhesion) {
            this.dateAdhesion = dateAdhesion;
        }

        public String getCotisationStatut() {
            return cotisationStatut;
        }

        public void setCotisationStatut(String cotisationStatut) {
            this.cotisationStatut = cotisationStatut;
        }

        public int getTauxParticipation() {
            return tauxParticipation;
        }

        public void setTauxParticipation(int tauxParticipation) {
            this.tauxParticipation = tauxParticipation;
        }

        public int getEvenementsAnnee() {
            return evenementsAnnee;
        }

        public void setEvenementsAnnee(int evenementsAnnee) {
            this.evenementsAnnee = evenementsAnnee;
        }

        public String getPhotoUrl() {
            return photoUrl;
        }

        public void setPhotoUrl(String photoUrl) {
            this.photoUrl = photoUrl;
        }

        public String getGenre() {
            return genre;
        }

        public void setGenre(String genre) {
            this.genre = genre;
        }

        public int getAge() {
            return age;
        }

        public void setAge(int age) {
            this.age = age;
        }

        public boolean isADesEnfants() {
            return aDesEnfants;
        }

        public void setADesEnfants(boolean aDesEnfants) {
            this.aDesEnfants = aDesEnfants;
        }

        public boolean isARecuAides() {
            return aRecuAides;
        }

        public void setARecuAides(boolean aRecuAides) {
            this.aRecuAides = aRecuAides;
        }

        // Propriétés dérivées
        public String getNomComplet() {
            return prenom + " " + nom;
        }

        public String getInitiales() {
            return (prenom != null ? prenom.substring(0, 1) : "") +
                    (nom != null ? nom.substring(0, 1) : "");
        }

        public String getTypeSeverity() {
            return switch (typeMembre) {
                case "ACTIF" -> "info";
                case "ASSOCIE" -> "success";
                case "BIENFAITEUR" -> "warning";
                case "HONORAIRE" -> "secondary";
                default -> "info";
            };
        }

        public String getTypeIcon() {
            return switch (typeMembre) {
                case "ACTIF" -> "pi-user";
                case "ASSOCIE" -> "pi-users";
                case "BIENFAITEUR" -> "pi-star";
                case "HONORAIRE" -> "pi-crown";
                default -> "pi-user";
            };
        }

        public String getStatutSeverity() {
            return switch (statut) {
                case "ACTIF" -> "success";
                case "INACTIF" -> "warning";
                case "SUSPENDU" -> "danger";
                default -> "secondary";
            };
        }

        public String getStatutIcon() {
            return switch (statut) {
                case "ACTIF" -> "pi-check";
                case "INACTIF" -> "pi-pause";
                case "SUSPENDU" -> "pi-ban";
                default -> "pi-circle";
            };
        }

        public String getAnciennete() {
            if (dateAdhesion == null)
                return "N/A";
            long mois = java.time.temporal.ChronoUnit.MONTHS.between(dateAdhesion, LocalDate.now());
            if (mois < 12)
                return mois + " mois";
            return (mois / 12) + " an" + (mois / 12 > 1 ? "s" : "");
        }

        public String getDernierPaiement() {
            return "À jour".equals(cotisationStatut) ? "Ce mois" : "En retard";
        }

        public String getCotisationColor() {
            return "À jour".equals(cotisationStatut) ? "text-green-500" : "text-red-500";
        }
    }

    public static class Entite {
        private UUID id;
        private String nom;

        public UUID getId() {
            return id;
        }

        public void setId(UUID id) {
            this.id = id;
        }

        public String getNom() {
            return nom;
        }

        public void setNom(String nom) {
            this.nom = nom;
        }
    }

    public static class RechercheSauvegardee {
        private UUID id;
        private String nom;
        private String description;
        private int nombreCriteres;
        private LocalDate dateCreation;
        private boolean publique;

        // Getters et setters
        public UUID getId() {
            return id;
        }

        public void setId(UUID id) {
            this.id = id;
        }

        public String getNom() {
            return nom;
        }

        public void setNom(String nom) {
            this.nom = nom;
        }

        public String getDescription() {
            return description;
        }

        public void setDescription(String description) {
            this.description = description;
        }

        public int getNombreCriteres() {
            return nombreCriteres;
        }

        public void setNombreCriteres(int nombreCriteres) {
            this.nombreCriteres = nombreCriteres;
        }

        public LocalDate getDateCreation() {
            return dateCreation;
        }

        public void setDateCreation(LocalDate dateCreation) {
            this.dateCreation = dateCreation;
        }

        public boolean isPublique() {
            return publique;
        }

        public void setPublique(boolean publique) {
            this.publique = publique;
        }
    }

    public static class MessageGroupe {
        private String sujet;
        private String contenu;
        private List<String> canaux = new ArrayList<>();

        // Getters et setters
        public String getSujet() {
            return sujet;
        }

        public void setSujet(String sujet) {
            this.sujet = sujet;
        }

        public String getContenu() {
            return contenu;
        }

        public void setContenu(String contenu) {
            this.contenu = contenu;
        }

        public List<String> getCanaux() {
            return canaux;
        }

        public void setCanaux(List<String> canaux) {
            this.canaux = canaux;
        }
    }
}
