package dev.lions.unionflow.client.view;

import dev.lions.unionflow.client.constants.StatutOrganisationConstants;
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.client.service.OrganisationService;
import jakarta.faces.view.ViewScoped;
import jakarta.inject.Named;
import jakarta.inject.Inject;
import jakarta.annotation.PostConstruct;
import org.eclipse.microprofile.rest.client.inject.RestClient;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.jboss.logging.Logger;

/**
 * Bean JSF pour les statistiques des organisations
 * 
 * @author UnionFlow Team
 * @version 1.0
 */
@Named("organisationStatistiquesBean")
@ViewScoped
public class OrganisationStatistiquesBean implements Serializable {

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

    @Inject
    @RestClient
    private OrganisationService organisationService;

    // Statistiques
    private Map<String, Object> statistiques = new HashMap<>();

    @PostConstruct
    public void init() {
        chargerStatistiques();
    }

    public void chargerStatistiques() {
        try {
            // Appeler le service pour obtenir les vraies statistiques
            OrganisationService.StatistiquesOrganisationDTO stats = organisationService.obtenirStatistiques();

            statistiques = new HashMap<>();
            if (stats != null && stats.getTotalAssociations() != null && stats.getTotalAssociations() > 0) {
                // Utiliser les statistiques du service si disponibles
                statistiques.put("totalOrganisations", stats.getTotalAssociations());
                statistiques.put("organisationsActives",
                        stats.getAssociationsActives() != null ? stats.getAssociationsActives() : 0L);
                statistiques.put("organisationsInactives",
                        stats.getAssociationsInactives() != null ? stats.getAssociationsInactives() : 0L);
                LOG.infof("Statistiques chargées depuis le service: Total=%d, Actives=%d, Inactives=%d",
                        stats.getTotalAssociations(),
                        stats.getAssociationsActives() != null ? stats.getAssociationsActives() : 0L,
                        stats.getAssociationsInactives() != null ? stats.getAssociationsInactives() : 0L);
            } else {
                // Fallback: calculer depuis la liste si le service ne retourne rien ou retourne
                // 0
                LOG.warn("Le service n'a retourné aucune statistique - calcul depuis la liste");
                calculerStatistiquesDepuisListe();
            }
        } catch (Exception e) {
            LOG.warnf(e, "Erreur lors du chargement des statistiques depuis le service");
            LOG.info("Fallback: calcul des statistiques depuis la liste des organisations");
            // Fallback: calculer depuis la liste
            calculerStatistiquesDepuisListe();
        }
    }

    private void calculerStatistiquesDepuisListe() {
        try {
            // Charger toutes les organisations
            PagedResponse<OrganisationSummaryResponse> response = organisationService.listerToutes(0, 1000);
            List<OrganisationSummaryResponse> organisations = (response != null && response.getData() != null) ? response.getData()
                    : new ArrayList<OrganisationSummaryResponse>();

            long total = organisations.size();
            long actives = organisations.stream()
                    .filter(o -> o.getStatut() != null && StatutOrganisationConstants.ACTIVE.equals(o.getStatut()))
                    .count();
            long inactives = total - actives;

            statistiques = new HashMap<>();
            statistiques.put("totalOrganisations", total);
            statistiques.put("organisationsActives", actives);
            statistiques.put("organisationsInactives", inactives);

            LOG.infof("Statistiques calculées depuis la liste: Total=%d, Actives=%d, Inactives=%d", total, actives,
                    inactives);
        } catch (Exception e) {
            LOG.errorf(e, "Impossible de calculer les statistiques depuis la liste");
            statistiques = new HashMap<>();
            statistiques.put("totalOrganisations", 0L);
            statistiques.put("organisationsActives", 0L);
            statistiques.put("organisationsInactives", 0L);
        }
    }

    // Getters et Setters
    public Map<String, Object> getStatistiques() {
        return statistiques;
    }

    public void setStatistiques(Map<String, Object> statistiques) {
        this.statistiques = statistiques;
    }

    public int getTotalOrganisations() {
        return statistiques != null && statistiques.containsKey("totalOrganisations")
                ? ((Number) statistiques.get("totalOrganisations")).intValue()
                : 0;
    }

    public int getOrganisationsActives() {
        return statistiques != null && statistiques.containsKey("organisationsActives")
                ? ((Number) statistiques.get("organisationsActives")).intValue()
                : 0;
    }

    public int getOrganisationsInactives() {
        return statistiques != null && statistiques.containsKey("organisationsInactives")
                ? ((Number) statistiques.get("organisationsInactives")).intValue()
                : 0;
    }
}
