package dev.lions.unionflow.client.view;

import dev.lions.unionflow.server.api.dto.organisation.response.OrganisationResponse;
import dev.lions.unionflow.server.api.dto.organisation.response.OrganisationSummaryResponse;
import dev.lions.unionflow.server.api.dto.common.PagedResponse;
import dev.lions.unionflow.server.api.dto.souscription.SouscriptionStatutResponse;
import dev.lions.unionflow.server.api.dto.common.PagedResponse;
import dev.lions.unionflow.client.service.OrganisationService;
import dev.lions.unionflow.client.service.CotisationService;
import dev.lions.unionflow.client.service.ErrorHandlerService;
import dev.lions.unionflow.client.service.SouscriptionService;
import dev.lions.unionflow.client.service.TypeCatalogueService;
import jakarta.faces.model.SelectItem;
import java.util.Map;
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.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
import org.jboss.logging.Logger;

@Named("entitesGestionBean")
@SessionScoped
public class EntitesGestionBean implements Serializable {

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

    // Constantes de navigation outcomes (WOU/DRY - réutilisables)
    private static final String OUTCOME_ENTITE_DETAILS = "entiteDetailsPage";
    private static final String OUTCOME_ADMIN_MEMBRES_GESTION = "adminMembresGestionPage";
    private static final String OUTCOME_ENTITE_CONFIGURATION = "entiteConfigurationPage";
    private static final String OUTCOME_ENTITE_RAPPORTS = "entiteRapportsPage";

    @Inject
    @RestClient
    private OrganisationService organisationService;

    @Inject
    @RestClient
    private CotisationService cotisationService;

    @Inject
    @RestClient
    private SouscriptionService souscriptionService;

    @Inject
    TypeCatalogueService typeCatalogueService;

    @Inject
    ErrorHandlerService errorHandler;

    private List<Entite> toutesLesEntites;
    private List<Entite> entitesFiltrees;
    private List<Entite> entitesSelectionnees;
    private Entite entiteSelectionne;
    private OrganisationResponse entiteEnEdition;
    private Entite nouvelleEntite;
    private Filtres filtres;
    private Statistiques statistiques;

    @PostConstruct
    public void init() {
        initializeFiltres();
        initializeEntites();
        initializeStatistiques();
        initializeNouvelleEntite();
        appliquerFiltres();
    }

    public List<SelectItem> getTypesSelectItems() {
        return typeCatalogueService.getSelectItems("Tous les types");
    }

    public List<SelectItem> getTypesSelectItemsForForm() {
        return typeCatalogueService.getSelectItems("Sélectionner un type *");
    }

    public List<SelectItem> getRegionsDisponibles() {
        List<SelectItem> items = new ArrayList<>();
        items.add(new SelectItem("", "Toutes les régions"));
        if (toutesLesEntites != null) {
            toutesLesEntites.stream()
                    .map(Entite::getRegion)
                    .filter(r -> r != null && !r.trim().isEmpty())
                    .distinct()
                    .sorted()
                    .forEach(r -> items.add(new SelectItem(r, r)));
        }
        return items;
    }

    private void initializeFiltres() {
        filtres = new Filtres();
        entitesSelectionnees = new ArrayList<>();
    }

    private void initializeStatistiques() {
        statistiques = new Statistiques();
        try {
            PagedResponse<OrganisationSummaryResponse> response = organisationService.listerToutes(0, 1000);
            List<OrganisationSummaryResponse> associations = new ArrayList<>();
            if (response != null && response.getData() != null) {
                associations = response.getData();
            }
            statistiques.setTotalEntites(associations.size());
            long actives = associations.stream().filter(a -> "ACTIVE".equals(a.getStatut())).count();
            statistiques.setEntitesActives((int) actives);
            int totalMembres = associations.stream()
                    .mapToInt(a -> a.getNombreMembres() != null ? a.getNombreMembres() : 0)
                    .sum();
            statistiques.setTotalMembres(totalMembres);
            double moyenne = associations.isEmpty() ? 0 : (double) totalMembres / associations.size();
            statistiques.setMoyenneMembresParEntite((int) moyenne);
            initializeRevenusStats();
            statistiques.setSouscriptionsExpirantes(0);
            statistiques.setEntitesQuotaAtteint(0);
            initializeSouscriptionStats(associations);
            statistiques.setFormulairePopulaire("N/A");
            statistiques.setTauxRenouvellement(0.0f);
        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors du calcul des statistiques");
            statistiques.setTotalEntites(0);
            statistiques.setEntitesActives(0);
            statistiques.setTotalMembres(0);
            statistiques.setMoyenneMembresParEntite(0);
        }
        calculerStatistiquesSouscriptions();
    }

    private void initializeEntites() {
        toutesLesEntites = new ArrayList<>();
        try {
            PagedResponse<OrganisationSummaryResponse> response = organisationService.listerToutes(0, 1000);
            if (response != null && response.getData() != null) {
                for (OrganisationSummaryResponse dto : response.getData()) {
                    Entite entite = convertToEntite(dto);
                    toutesLesEntites.add(entite);
                }
            }
        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors du chargement des entités");
        }
    }

    private Entite convertToEntite(OrganisationSummaryResponse dto) {
        Entite entite = new Entite();
        entite.setId(dto.getId());
        entite.setNom(dto.getNom());
        entite.setCodeEntite(dto.getNomCourt()); // Using nomCourt as code
        entite.setType(dto.getTypeOrganisation());
        entite.setTypeLibelle(typeCatalogueService.resolveLibelle(dto.getTypeOrganisation()));
        entite.setRegion(null); // Not available in Summary
        entite.setStatut(dto.getStatut());
        entite.setNombreMembres(dto.getNombreMembres() != null ? dto.getNombreMembres() : 0);
        entite.setMembresUtilises(dto.getNombreMembres() != null ? dto.getNombreMembres() : 0);
        entite.setAdresse(null); // Not available in Summary
        entite.setTelephone(null); // Not available in Summary
        entite.setEmail(null); // Not available in Summary
        entite.setDescription(null); // Not available in Summary
        entite.setDerniereActivite(null); // Not available in Summary

        try {
            SouscriptionStatutResponse souscription = souscriptionService.obtenirActive(dto.getId());
            if (souscription != null) {
                entite.setForfaitSouscrit(
                        souscription.getPlanCommercial() != null ? souscription.getPlanCommercial() : "Non défini");
                entite.setMembresQuota(
                        souscription.getQuotaMax() != null ? souscription.getQuotaMax() : 0);
                entite.setMontantMensuel(souscription.getMontantTotal() != null
                        ? String.format("%,.0f FCFA", souscription.getMontantTotal().doubleValue())
                        : "0 FCFA");
                entite.setDateExpirationSouscription(souscription.getDateFin());
                entite.setStatutSouscription(
                        souscription.getStatut() != null ? souscription.getStatut() : "NON_DEFINI");
            } else {
                entite.setForfaitSouscrit("Non défini");
                entite.setMembresQuota(0);
                entite.setMontantMensuel("0 FCFA");
                entite.setDateExpirationSouscription(null);
                entite.setStatutSouscription("NON_DEFINI");
            }
        } catch (Exception e) {
            entite.setForfaitSouscrit("Non défini");
            entite.setMembresQuota(0);
            entite.setMontantMensuel("0 FCFA");
            entite.setDateExpirationSouscription(null);
            entite.setStatutSouscription("NON_DEFINI");
        }

        return entite;
    }

    // Overload for full OrganisationResponse (CRUD operations)
    private Entite convertToEntite(OrganisationResponse dto) {
        Entite entite = new Entite();
        entite.setId(dto.getId());
        entite.setNom(dto.getNom());
        entite.setCodeEntite(dto.getNomCourt());
        entite.setType(dto.getTypeOrganisation());
        entite.setTypeLibelle(typeCatalogueService.resolveLibelle(dto.getTypeOrganisation()));
        entite.setRegion(dto.getRegion());
        entite.setVille(dto.getVille());
        entite.setStatut(dto.getStatut());
        entite.setNombreMembres(dto.getNombreMembres() != null ? dto.getNombreMembres() : 0);
        entite.setMembresUtilises(dto.getNombreMembres() != null ? dto.getNombreMembres() : 0);
        entite.setAdresse(dto.getAdresse());
        entite.setTelephone(dto.getTelephone());
        entite.setEmail(dto.getEmail());
        entite.setDescription(dto.getDescription());
        entite.setDerniereActivite(null);

        try {
            SouscriptionStatutResponse souscription = souscriptionService.obtenirActive(dto.getId());
            if (souscription != null) {
                entite.setForfaitSouscrit(
                        souscription.getPlanCommercial() != null ? souscription.getPlanCommercial() : "Non défini");
                entite.setMembresQuota(
                        souscription.getQuotaMax() != null ? souscription.getQuotaMax() : 0);
                entite.setMontantMensuel(souscription.getMontantTotal() != null
                        ? String.format("%,.0f FCFA", souscription.getMontantTotal().doubleValue())
                        : "0 FCFA");
                entite.setDateExpirationSouscription(souscription.getDateFin());
                entite.setStatutSouscription(
                        souscription.getStatut() != null ? souscription.getStatut() : "NON_DEFINI");
            } else {
                entite.setForfaitSouscrit("Non défini");
                entite.setMembresQuota(0);
                entite.setMontantMensuel("0 FCFA");
                entite.setDateExpirationSouscription(null);
                entite.setStatutSouscription("NON_DEFINI");
            }
        } catch (Exception e) {
            entite.setForfaitSouscrit("Non défini");
            entite.setMembresQuota(0);
            entite.setMontantMensuel("0 FCFA");
            entite.setDateExpirationSouscription(null);
            entite.setStatutSouscription("NON_DEFINI");
        }

        return entite;
    }

    private void initializeNouvelleEntite() {
        nouvelleEntite = new Entite();
    }

    private void appliquerFiltres() {
        entitesFiltrees = toutesLesEntites.stream()
                .filter(this::appliquerFiltre)
                .collect(Collectors.toList());
    }

    private boolean appliquerFiltre(Entite entite) {
        // Filtre par nom
        if (filtres.getNom() != null && !filtres.getNom().trim().isEmpty()) {
            if (!entite.getNom().toLowerCase().contains(filtres.getNom().toLowerCase())) {
                return false;
            }
        }

        // Filtre par type
        if (filtres.getType() != null && !filtres.getType().trim().isEmpty()) {
            if (!entite.getType().equals(filtres.getType())) {
                return false;
            }
        }

        // Filtre par statut
        if (filtres.getStatut() != null && !filtres.getStatut().trim().isEmpty()) {
            if (!entite.getStatut().equals(filtres.getStatut())) {
                return false;
            }
        }

        // Filtre par région
        if (filtres.getRegion() != null && !filtres.getRegion().trim().isEmpty()) {
            if (!entite.getRegion().equals(filtres.getRegion())) {
                return false;
            }
        }

        // Filtre par forfait
        if (filtres.getForfait() != null && !filtres.getForfait().trim().isEmpty()) {
            if (!entite.getForfaitSouscrit().equals(filtres.getForfait())) {
                return false;
            }
        }

        // Filtre par alerte quota
        if (filtres.getAlerteQuota() != null && !filtres.getAlerteQuota().trim().isEmpty()) {
            if ("OUI".equals(filtres.getAlerteQuota()) && !entite.isQuotaProche()) {
                return false;
            }
            if ("NON".equals(filtres.getAlerteQuota()) && entite.isQuotaProche()) {
                return false;
            }
        }

        // Filtre par alerte expiration
        if (filtres.getAlerteExpiration() != null && !filtres.getAlerteExpiration().trim().isEmpty()) {
            if ("OUI".equals(filtres.getAlerteExpiration()) && !entite.isExpirationProche()) {
                return false;
            }
            if ("NON".equals(filtres.getAlerteExpiration()) && entite.isExpirationProche()) {
                return false;
            }
        }

        // Filtre par statut souscription
        if (filtres.getStatutSouscription() != null && !filtres.getStatutSouscription().trim().isEmpty()) {
            if (!entite.getStatutSouscription().equals(filtres.getStatutSouscription())) {
                return false;
            }
        }

        return true;
    }

    // Actions
    public void rechercher() {
        appliquerFiltres();
    }

    public void reinitialiserFiltres() {
        filtres = new Filtres();
        appliquerFiltres();
    }

    public String voirEntite(Entite entite) {
        return "/pages/secure/organisation/detail.xhtml?id=" + entite.getId() + "&faces-redirect=true";
    }

    public void creerEntite() {
        if (nouvelleEntite == null || nouvelleEntite.getNom() == null || nouvelleEntite.getNom().isBlank()) {
            LOG.warn("Tentative de création d'une entité sans nom");
            return;
        }

        try {
            OrganisationResponse dto = new OrganisationResponse();
            dto.setNom(nouvelleEntite.getNom());
            dto.setTypeOrganisation(nouvelleEntite.getType());
            dto.setRegion(nouvelleEntite.getRegion());
            dto.setAdresse(nouvelleEntite.getAdresse());
            dto.setVille(nouvelleEntite.getVille());
            dto.setTelephone(nouvelleEntite.getTelephone());
            dto.setEmail(nouvelleEntite.getEmail());
            dto.setDescription(nouvelleEntite.getDescription());
            dto.setStatut("ACTIVE");

            OrganisationResponse creee = organisationService.creer(dto);
            LOG.infof("Entité créée avec succès : id=%s, nom=%s", creee.getId(), creee.getNom());

            toutesLesEntites.add(convertToEntite(creee));
            appliquerFiltres();
            initializeNouvelleEntite();

        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors de la création de l'entité");
        }
    }

    // ── Préparation du dialog Modifier ──────────────────────────────────────

    public void preparerModification(Entite entite) {
        this.entiteSelectionne = entite;
        try {
            entiteEnEdition = organisationService.obtenirParId(entite.getId());
        } catch (Exception e) {
            LOG.errorf(e, "Impossible de charger les détails de l'entité %s pour modification", entite.getId());
            entiteEnEdition = new OrganisationResponse();
            entiteEnEdition.setId(entite.getId());
            entiteEnEdition.setNom(entite.getNom());
            entiteEnEdition.setTypeOrganisation(entite.getType());
            entiteEnEdition.setRegion(entite.getRegion());
            entiteEnEdition.setAdresse(entite.getAdresse());
            entiteEnEdition.setVille(entite.getVille());
            entiteEnEdition.setTelephone(entite.getTelephone());
            entiteEnEdition.setEmail(entite.getEmail());
            entiteEnEdition.setStatut(entite.getStatut());
        }
    }

    public void modifierEntite() {
        if (entiteEnEdition == null || entiteEnEdition.getId() == null) return;
        try {
            OrganisationResponse maj = organisationService.modifier(entiteEnEdition.getId(), entiteEnEdition);
            Entite entiteMaj = convertToEntite(maj);
            int idx = -1;
            for (int i = 0; i < toutesLesEntites.size(); i++) {
                if (toutesLesEntites.get(i).getId().equals(maj.getId())) {
                    idx = i;
                    break;
                }
            }
            if (idx >= 0) toutesLesEntites.set(idx, entiteMaj);
            appliquerFiltres();
            errorHandler.showSuccess("Succès", "Entité '" + maj.getNom() + "' modifiée.");
        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors de la modification de l'entité");
            errorHandler.handleException(e, "lors de la modification de l'entité", null);
        }
    }

    // ── Navigation depuis le dialog Actions ─────────────────────────────────

    public String gererMembres() {
        if (entiteSelectionne == null) return null;
        return "/pages/secure/membre/liste.xhtml?organisationId=" + entiteSelectionne.getId() + "&faces-redirect=true";
    }

    public String configurerEntite() {
        if (entiteSelectionne == null) return null;
        return "/pages/secure/organisation/detail.xhtml?id=" + entiteSelectionne.getId() + "&faces-redirect=true";
    }

    public String voirRapports() {
        if (entiteSelectionne == null) return null;
        return "/pages/admin/rapports/statistiques.xhtml?faces-redirect=true";
    }

    // ── Actions de statut (persistées en base) ────────────────────────────────

    public void suspendreEntite() {
        if (entiteSelectionne == null) return;
        try {
            OrganisationResponse maj = organisationService.suspendre(entiteSelectionne.getId());
            mettreAJourStatutEntite(maj);
            errorHandler.showSuccess("Suspendues", "Entité '" + entiteSelectionne.getNom() + "' suspendue.");
        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors de la suspension de l'entité");
            errorHandler.handleException(e, "lors de la suspension de l'entité", null);
        }
    }

    public void reactiverEntite() {
        if (entiteSelectionne == null) return;
        try {
            OrganisationResponse maj = organisationService.activer(entiteSelectionne.getId());
            mettreAJourStatutEntite(maj);
            errorHandler.showSuccess("Réactivée", "Entité '" + entiteSelectionne.getNom() + "' réactivée.");
        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors de la réactivation de l'entité");
            errorHandler.handleException(e, "lors de la réactivation de l'entité", null);
        }
    }

    private void mettreAJourStatutEntite(OrganisationResponse maj) {
        for (Entite e : toutesLesEntites) {
            if (e.getId().equals(maj.getId())) {
                e.setStatut(maj.getStatut());
                break;
            }
        }
        appliquerFiltres();
    }

    public void supprimerEntite() {
        if (entiteSelectionne == null) return;
        try {
            organisationService.supprimer(entiteSelectionne.getId());
            toutesLesEntites.removeIf(e -> e.getId().equals(entiteSelectionne.getId()));
            appliquerFiltres();
            errorHandler.showSuccess("Supprimée", "Entité supprimée avec succès.");
            entiteSelectionne = null;
        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors de la suppression de l'entité");
            errorHandler.handleException(e, "lors de la suppression de l'entité", null);
        }
    }

    public void exporterEntites() {
        LOG.infof("Export de %d entités", entitesFiltrees.size());
    }

    // Getters et Setters
    public List<Entite> getToutesLesEntites() {
        return toutesLesEntites;
    }

    public void setToutesLesEntites(List<Entite> toutesLesEntites) {
        this.toutesLesEntites = toutesLesEntites;
    }

    public List<Entite> getEntitesFiltrees() {
        return entitesFiltrees;
    }

    public void setEntitesFiltrees(List<Entite> entitesFiltrees) {
        this.entitesFiltrees = entitesFiltrees;
    }

    public List<Entite> getEntitesSelectionnees() {
        return entitesSelectionnees;
    }

    public void setEntitesSelectionnees(List<Entite> entitesSelectionnees) {
        this.entitesSelectionnees = entitesSelectionnees;
    }

    public Entite getEntiteSelectionne() {
        return entiteSelectionne;
    }

    public void setEntiteSelectionne(Entite entiteSelectionne) {
        this.entiteSelectionne = entiteSelectionne;
    }

    public OrganisationResponse getEntiteEnEdition() { return entiteEnEdition; }
    public void setEntiteEnEdition(OrganisationResponse entiteEnEdition) { this.entiteEnEdition = entiteEnEdition; }

    public Entite getNouvelleEntite() {
        return nouvelleEntite;
    }

    public void setNouvelleEntite(Entite nouvelleEntite) {
        this.nouvelleEntite = nouvelleEntite;
    }

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

    private void initializeRevenusStats() {
        try {
            Map<String, Object> stats = cotisationService.obtenirStatistiques();
            if (stats != null) {
                Object montantTotal = stats.get("montantTotal");
                if (montantTotal instanceof Number) {
                    statistiques.setRevenus(String.format("%,.0f FCFA", ((Number) montantTotal).doubleValue()));
                } else {
                    statistiques.setRevenus("0 FCFA");
                }
            } else {
                statistiques.setRevenus("0 FCFA");
            }
        } catch (Exception e) {
            LOG.debugf("Impossible de charger les stats cotisations: %s", e.getMessage());
            statistiques.setRevenus("0 FCFA");
        }
    }

    private void initializeSouscriptionStats(List<OrganisationSummaryResponse> associations) {
        try {
            int expirantes = 0;
            int totalSouscriptions = 0;
            int souscriptionsActives = 0;
            String forfaitLePlusPopulaire = "N/A";
            Map<String, Integer> forfaitCount = new java.util.HashMap<>();

            for (OrganisationSummaryResponse assoc : associations) {
                try {
                    SouscriptionStatutResponse souscription = souscriptionService.obtenirActive(assoc.getId());
                    if (souscription != null) {
                        totalSouscriptions++;
                        if ("ACTIVE".equals(souscription.getStatut())) {
                            souscriptionsActives++;
                        }
                        if (souscription.getDateFin() != null
                                && souscription.getDateFin().isAfter(LocalDate.now())
                                && souscription.getDateFin().isBefore(LocalDate.now().plusDays(30))) {
                            expirantes++;
                        }
                        String forfait = souscription.getPlanCommercial() != null ? souscription.getPlanCommercial()
                                : "Inconnu";
                        forfaitCount.merge(forfait, 1, Integer::sum);
                    }
                } catch (Exception ignored) {
                    // Organisation sans souscription active
                }
            }

            statistiques.setSouscriptionsExpirantes(expirantes);
            if (!forfaitCount.isEmpty()) {
                forfaitLePlusPopulaire = forfaitCount.entrySet().stream()
                        .max(Map.Entry.comparingByValue())
                        .map(Map.Entry::getKey)
                        .orElse("N/A");
            }
            statistiques.setFormulairePopulaire(forfaitLePlusPopulaire);
            statistiques.setTauxRenouvellement(totalSouscriptions > 0
                    ? (float) souscriptionsActives / totalSouscriptions * 100
                    : 0.0f);
        } catch (Exception e) {
            LOG.debugf("Impossible de charger les stats souscriptions: %s", e.getMessage());
        }
    }

    // Méthodes utilitaires pour les souscriptions
    private void calculerStatistiquesSouscriptions() {
        if (toutesLesEntites == null || statistiques == null) {
            return; // Sécurité si appelé avant initialisation complète
        }

        int expirantes = 0;
        int quotaAtteint = 0;

        for (Entite entite : toutesLesEntites) {
            if (entite.isExpirationProche()) {
                expirantes++;
            }
            if (entite.isQuotaAtteint()) {
                quotaAtteint++;
            }
        }

        statistiques.setSouscriptionsExpirantes(expirantes);
        statistiques.setEntitesQuotaAtteint(quotaAtteint);
    }

    public void renouvelerSouscription() {
        if (entiteSelectionne != null) {
            entiteSelectionne.setDateExpirationSouscription(LocalDate.now().plusMonths(12));
            entiteSelectionne.setStatutSouscription("ACTIVE");
            LOG.infof("Souscription renouvelée pour: %s", entiteSelectionne.getNom());
            appliquerFiltres();
        }
    }

    public void upgraderForfait() {
        if (entiteSelectionne != null) {
            String forfaitActuel = entiteSelectionne.getForfaitSouscrit();
            switch (forfaitActuel) {
                case "Starter":
                    entiteSelectionne.setForfaitSouscrit("Standard");
                    entiteSelectionne.setMembresQuota(200);
                    entiteSelectionne.setMontantMensuel("3 000 FCFA");
                    break;
                case "Standard":
                    entiteSelectionne.setForfaitSouscrit("Premium");
                    entiteSelectionne.setMembresQuota(500);
                    entiteSelectionne.setMontantMensuel("4 000 FCFA");
                    break;
                case "Premium":
                    entiteSelectionne.setForfaitSouscrit("Cristal");
                    entiteSelectionne.setMembresQuota(2000);
                    entiteSelectionne.setMontantMensuel("5 000 FCFA");
                    break;
            }
            LOG.infof("Forfait upgradé pour: %s", entiteSelectionne.getNom());
            appliquerFiltres();
        }
    }

    public void gererQuotas() {
        LOG.info("Gestion des quotas pour toutes les entités");
    }

    public void envoyerRelancesSouscriptions() {
        int compteur = 0;
        for (Entite entite : toutesLesEntites) {
            if (entite.isExpirationProche()) {
                LOG.infof("Relance envoyée à: %s", entite.getNom());
                compteur++;
            }
        }
        LOG.infof("%d relances de souscription envoyées", compteur);
    }

    // Actions groupées
    public void renouvelerSouscriptionsGroupees() {
        int compteur = 0;
        for (Entite entite : entitesSelectionnees) {
            entite.setDateExpirationSouscription(LocalDate.now().plusMonths(12));
            entite.setStatutSouscription("ACTIVE");
            compteur++;
        }
        LOG.infof("%d souscriptions renouvelées en masse", compteur);
        entitesSelectionnees.clear();
        appliquerFiltres();
    }

    public void suspendreEntitesGroupees() {
        int compteur = 0;
        for (Entite entite : entitesSelectionnees) {
            entite.setStatut("SUSPENDUE");
            compteur++;
        }
        LOG.infof("%d entités suspendues en masse", compteur);
        entitesSelectionnees.clear();
        appliquerFiltres();
    }

    public void reactiverEntitesGroupees() {
        int compteur = 0;
        for (Entite entite : entitesSelectionnees) {
            entite.setStatut("ACTIVE");
            compteur++;
        }
        LOG.infof("%d entités réactivées en masse", compteur);
        entitesSelectionnees.clear();
        appliquerFiltres();
    }

    public void proposerUpgradeGroupees() {
        int compteur = 0;
        for (Entite entite : entitesSelectionnees) {
            if (entite.isQuotaProche()) {
                // Simulation d'envoi de proposition d'upgrade
                LOG.infof("Proposition d'upgrade envoyée à: %s", entite.getNom());
                compteur++;
            }
        }
        LOG.infof("%d propositions d'upgrade envoyées", compteur);
    }

    // Classes internes
    public static class Entite {
        private UUID id;
        private String nom;
        private String codeEntite;
        private String type;
        private String typeLibelle;
        private String region;
        private String statut;
        private int nombreMembres;
        private String adresse;
        private String ville; // Ajouté: champ manquant
        private String telephone;
        private String email;
        private String description;
        private LocalDateTime derniereActivite;
        private Administrateur administrateur;

        // Informations de souscription
        private String forfaitSouscrit = "Standard";
        private int membresQuota = 200;
        private int membresUtilises;
        private LocalDate dateExpirationSouscription;
        private String statutSouscription = "ACTIVE";
        private String montantMensuel = "3 000 FCFA";

        // 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 getCodeEntite() {
            return codeEntite;
        }

        public void setCodeEntite(String codeEntite) {
            this.codeEntite = codeEntite;
        }

        public String getType() {
            return type;
        }

        public void setType(String type) {
            this.type = type;
        }

        public String getRegion() {
            return region;
        }

        public void setRegion(String region) {
            this.region = region;
        }

        public String getStatut() {
            return statut;
        }

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

        public int getNombreMembres() {
            return nombreMembres;
        }

        public void setNombreMembres(int nombreMembres) {
            this.nombreMembres = nombreMembres;
        }

        public String getAdresse() {
            return adresse;
        }

        public void setAdresse(String adresse) {
            this.adresse = adresse;
        }

        public String getVille() {
            return ville;
        }

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

        public String getTelephone() {
            return telephone;
        }

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

        public String getEmail() {
            return email;
        }

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

        public String getDescription() {
            return description;
        }

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

        public LocalDateTime getDerniereActivite() {
            return derniereActivite;
        }

        public void setDerniereActivite(LocalDateTime derniereActivite) {
            this.derniereActivite = derniereActivite;
        }

        public Administrateur getAdministrateur() {
            return administrateur;
        }

        public void setAdministrateur(Administrateur administrateur) {
            this.administrateur = administrateur;
        }

        public String getTypeLibelle() { return typeLibelle != null ? typeLibelle : type; }
        public void setTypeLibelle(String typeLibelle) { this.typeLibelle = typeLibelle; }

        // Propriétés dérivées

        public String getTypeSeverity() {
            return switch (type) {
                case "ASSOCIATION" -> "info";
                case "CLUB" -> "success";
                case "GROUPE" -> "warning";
                case "GROUPE_JEUNES" -> "primary";
                case "BRANCHE" -> "secondary";
                default -> "secondary";
            };
        }

        public String getTypeIcon() {
            return switch (type) {
                case "ASSOCIATION" -> "pi-users";
                case "CLUB" -> "pi-home";
                case "GROUPE" -> "pi-sitemap";
                case "GROUPE_JEUNES" -> "pi-star";
                case "BRANCHE" -> "pi-share-alt";
                default -> "pi-building";
            };
        }

        public String getStatutSeverity() {
            return switch (statut) {
                case "ACTIVE" -> "success";
                case "INACTIVE" -> "warning";
                case "SUSPENDUE" -> "danger";
                default -> "secondary";
            };
        }

        public String getStatutIcon() {
            return switch (statut) {
                case "ACTIVE" -> "pi-check";
                case "INACTIVE" -> "pi-pause";
                case "SUSPENDUE" -> "pi-ban";
                default -> "pi-circle";
            };
        }

        public String getDerniereActiviteFormatee() {
            if (derniereActivite == null)
                return "N/A";
            return derniereActivite.format(DateTimeFormatter.ofPattern("dd/MM/yyyy"));
        }

        public String getDerniereActiviteRelative() {
            if (derniereActivite == null)
                return "";
            long jours = ChronoUnit.DAYS.between(derniereActivite.toLocalDate(), LocalDate.now());
            if (jours == 0)
                return "Aujourd'hui";
            if (jours == 1)
                return "Hier";
            if (jours < 7)
                return "Il y a " + jours + " jours";
            if (jours < 30)
                return "Il y a " + (jours / 7) + " semaine" + (jours / 7 > 1 ? "s" : "");
            return "Il y a " + (jours / 30) + " mois";
        }

        // Getters et setters pour les informations de souscription
        public String getForfaitSouscrit() {
            return forfaitSouscrit;
        }

        public void setForfaitSouscrit(String forfaitSouscrit) {
            this.forfaitSouscrit = forfaitSouscrit;
        }

        public int getMembresQuota() {
            return membresQuota;
        }

        public void setMembresQuota(int membresQuota) {
            this.membresQuota = membresQuota;
        }

        public int getMembresUtilises() {
            return membresUtilises;
        }

        public void setMembresUtilises(int membresUtilises) {
            this.membresUtilises = membresUtilises;
        }

        public LocalDate getDateExpirationSouscription() {
            return dateExpirationSouscription;
        }

        public void setDateExpirationSouscription(LocalDate dateExpirationSouscription) {
            this.dateExpirationSouscription = dateExpirationSouscription;
        }

        public String getStatutSouscription() {
            return statutSouscription;
        }

        public void setStatutSouscription(String statutSouscription) {
            this.statutSouscription = statutSouscription;
        }

        public String getMontantMensuel() {
            return montantMensuel;
        }

        public void setMontantMensuel(String montantMensuel) {
            this.montantMensuel = montantMensuel;
        }

        // Méthodes utilitaires pour les souscriptions
        public boolean isQuotaProche() {
            return getMembresUtilises() >= (getMembresQuota() * 0.85);
        }

        public boolean isQuotaAtteint() {
            return getMembresUtilises() >= getMembresQuota();
        }

        public boolean isExpirationProche() {
            if (dateExpirationSouscription == null)
                return false;
            return ChronoUnit.DAYS.between(LocalDate.now(), dateExpirationSouscription) <= 30;
        }

        public int getPourcentageUtilisationQuota() {
            if (membresQuota == 0)
                return 0;
            return (membresUtilises * 100) / membresQuota;
        }

        public String getForfaitCouleur() {
            return switch (forfaitSouscrit) {
                case "Starter" -> "primary";
                case "Standard" -> "success";
                case "Premium" -> "warning";
                case "Cristal" -> "info";
                default -> "secondary";
            };
        }

        public String getForfaitIcone() {
            return switch (forfaitSouscrit) {
                case "Starter" -> "pi-star";
                case "Standard" -> "pi-users";
                case "Premium" -> "pi-crown";
                case "Cristal" -> "pi-diamond";
                default -> "pi-circle";
            };
        }

        public long getJoursAvantExpiration() {
            if (dateExpirationSouscription == null)
                return 0;
            return ChronoUnit.DAYS.between(LocalDate.now(), dateExpirationSouscription);
        }
    }

    public static class Administrateur {
        private String nomComplet;
        private String email;

        // Getters et setters
        public String getNomComplet() {
            return nomComplet;
        }

        public void setNomComplet(String nomComplet) {
            this.nomComplet = nomComplet;
        }

        public String getEmail() {
            return email;
        }

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

    public static class Filtres {
        private String nom;
        private String type;
        private String statut;
        private String region;
        private String forfait;
        private String alerteQuota;
        private String alerteExpiration;
        private String statutSouscription;

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

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

        public String getType() {
            return type;
        }

        public void setType(String type) {
            this.type = type;
        }

        public String getStatut() {
            return statut;
        }

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

        public String getRegion() {
            return region;
        }

        public void setRegion(String region) {
            this.region = region;
        }

        public String getForfait() {
            return forfait;
        }

        public void setForfait(String forfait) {
            this.forfait = forfait;
        }

        public String getAlerteQuota() {
            return alerteQuota;
        }

        public void setAlerteQuota(String alerteQuota) {
            this.alerteQuota = alerteQuota;
        }

        public String getAlerteExpiration() {
            return alerteExpiration;
        }

        public void setAlerteExpiration(String alerteExpiration) {
            this.alerteExpiration = alerteExpiration;
        }

        public String getStatutSouscription() {
            return statutSouscription;
        }

        public void setStatutSouscription(String statutSouscription) {
            this.statutSouscription = statutSouscription;
        }
    }

    public static class Statistiques {
        private int totalEntites;
        private int entitesActives;
        private int totalMembres;
        private String revenus;
        private int souscriptionsExpirantes;
        private int entitesQuotaAtteint;
        private String formulairePopulaire;
        private float tauxRenouvellement;
        private int moyenneMembresParEntite;

        // Getters et setters
        public int getTotalEntites() {
            return totalEntites;
        }

        public void setTotalEntites(int totalEntites) {
            this.totalEntites = totalEntites;
        }

        public int getEntitesActives() {
            return entitesActives;
        }

        public void setEntitesActives(int entitesActives) {
            this.entitesActives = entitesActives;
        }

        public int getTotalMembres() {
            return totalMembres;
        }

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

        public String getRevenus() {
            return revenus;
        }

        public void setRevenus(String revenus) {
            this.revenus = revenus;
        }

        public int getSouscriptionsExpirantes() {
            return souscriptionsExpirantes;
        }

        public void setSouscriptionsExpirantes(int souscriptionsExpirantes) {
            this.souscriptionsExpirantes = souscriptionsExpirantes;
        }

        public int getEntitesQuotaAtteint() {
            return entitesQuotaAtteint;
        }

        public void setEntitesQuotaAtteint(int entitesQuotaAtteint) {
            this.entitesQuotaAtteint = entitesQuotaAtteint;
        }

        public String getFormulairePopulaire() {
            return formulairePopulaire;
        }

        public void setFormulairePopulaire(String formulairePopulaire) {
            this.formulairePopulaire = formulairePopulaire;
        }

        public float getTauxRenouvellement() {
            return tauxRenouvellement;
        }

        public void setTauxRenouvellement(float tauxRenouvellement) {
            this.tauxRenouvellement = tauxRenouvellement;
        }

        public int getMoyenneMembresParEntite() {
            return moyenneMembresParEntite;
        }

        public void setMoyenneMembresParEntite(int moyenneMembresParEntite) {
            this.moyenneMembresParEntite = moyenneMembresParEntite;
        }

        public String getTauxRenouvellementFormat() {
            return String.format("%.1f%%", tauxRenouvellement);
        }
    }
}
