package dev.lions.unionflow.client.view;

import dev.lions.unionflow.client.dto.AssociationDTO;
import dev.lions.unionflow.client.service.AssociationService;
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.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.logging.Logger;

@Named("superAdminBean")
@SessionScoped
public class SuperAdminBean implements Serializable {
    
    private static final long serialVersionUID = 1L;
    private static final Logger LOGGER = Logger.getLogger(SuperAdminBean.class.getName());
    
    // Constantes de navigation outcomes (WOU/DRY - réutilisables)
    private static final String OUTCOME_ENTITE_NOUVELLE = "entiteNouvellePage";
    private static final String OUTCOME_ENTITE_GESTION = "entiteGestionPage";
    private static final String OUTCOME_SUPER_ADMIN_RAPPORTS = "superAdminRapportsPage";
    private static final String OUTCOME_SUPER_ADMIN_CONFIGURATION = "superAdminConfigurationPage";
    private static final String OUTCOME_SUPER_ADMIN_ALERTES = "superAdminAlertesPage";
    private static final String OUTCOME_SUPER_ADMIN_ACTIVITE = "superAdminActivitePage";
    
    @Inject
    @RestClient
    private AssociationService associationService;
    
    private String nomComplet;
    private String derniereConnexion;
    private int totalEntites;
    private int totalAdministrateurs;
    private int totalMembres;
    private String revenusGlobaux;
    private int alertesCount;
    private String croissanceEntites;
    private int activiteJournaliere;
    
    // Pourcentages de croissance calculés
    private String croissanceMembres = "0";
    private String croissanceRevenus = "0";
    private int nouvellesEntites = 0;
    private int utilisateursActifs = 0;
    
    // Pourcentages pour les progress bars (jauges)
    private int pourcentageMembres = 0;
    private int pourcentageOrganisations = 0;
    private int pourcentageRevenus = 0;
    private int pourcentageActivite = 0;
    
    // Métriques de souscription
    private int totalSouscriptions;
    private int souscriptionsActives;
    private int souscriptionsExpirantSous30Jours;
    private float tauxConversion;
    
    // Revenus par forfait
    private BigDecimal revenusStarter = BigDecimal.ZERO;
    private BigDecimal revenusStandard = BigDecimal.ZERO;
    private BigDecimal revenusPremmium = BigDecimal.ZERO;
    private BigDecimal revenusCristal = BigDecimal.ZERO;
    
    // Métriques système
    private float disponibiliteSysteme;
    private int tempsReponsMoyen;
    private int ticketsSupportOuverts;
    private float satisfactionClient;
    
    private List<Alerte> alertesRecentes;
    private List<Entite> topEntites;
    private List<TypeEntite> repartitionTypes;
    private List<Activite> activitesRecentes;
    private List<EvolutionMois> evolutionEntites;
    private RevenusData revenus;
    private String periodeEvolution = "12M";
    
    @PostConstruct
    public void init() {
        initializeUserInfo();
        initializeKPIs();
        initializeAlertes();
        initializeEntites();
        initializeRepartitionTypes();
        initializeActivites();
        initializeEvolution();
        initializeRevenus();
    }
    
    private void initializeUserInfo() {
        // TODO: Récupérer depuis le contexte de sécurité (Keycloak)
        nomComplet = "Administrateur Système";
        derniereConnexion = LocalDateTime.now().format(DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm"));
    }
    
    private void initializeKPIs() {
        try {
            List<AssociationDTO> associations = associationService.listerToutes(0, 1000);
            totalEntites = associations.size();
            totalAdministrateurs = associations.size(); // TODO: Calculer depuis les utilisateurs
            int totalMembresCalc = associations.stream()
                .mapToInt(a -> a.getNombreMembres() != null ? a.getNombreMembres() : 0)
                .sum();
            totalMembres = totalMembresCalc;
            revenusGlobaux = "0 FCFA"; // TODO: Calculer depuis les souscriptions/paiements réels
            alertesCount = 0; // TODO: Calculer depuis les alertes réelles
            
            // Calculer la croissance des entités (comparaison avec le mois précédent)
            // Pour l'instant, on ne peut pas calculer sans historique, donc 0
            croissanceEntites = "0";
            nouvellesEntites = 0; // TODO: Calculer depuis l'historique
            
            // Calculer la croissance des membres (comparaison avec le mois précédent)
            // Pour l'instant, on ne peut pas calculer sans historique, donc 0
            croissanceMembres = "0"; // TODO: Calculer depuis l'historique des membres
            
            croissanceRevenus = "0"; // TODO: Calculer depuis l'historique des revenus
            activiteJournaliere = 0; // TODO: Calculer depuis les logs d'activité
            utilisateursActifs = 0; // TODO: Calculer depuis les sessions actives
            
            // Calculer les pourcentages pour les progress bars (jauges)
            calculerPourcentagesJauges();
            
            // Initialiser les métriques de souscription
            totalSouscriptions = 0; // TODO: Calculer depuis les souscriptions réelles
            souscriptionsActives = 0; // TODO: Calculer depuis les souscriptions actives
            souscriptionsExpirantSous30Jours = 0; // TODO: Calculer depuis les souscriptions expirantes
            tauxConversion = 0.0f; // TODO: Calculer depuis les statistiques de conversion
            
            // Revenus par forfait - TODO: Calculer depuis les souscriptions/paiements réels
            revenusStarter = BigDecimal.ZERO;
            revenusStandard = BigDecimal.ZERO;
            revenusPremmium = BigDecimal.ZERO;
            revenusCristal = BigDecimal.ZERO;
            
            // Métriques système - TODO: Récupérer depuis un service de monitoring
            disponibiliteSysteme = 0.0f;
            tempsReponsMoyen = 0; // ms
            ticketsSupportOuverts = 0; // TODO: Calculer depuis les tickets support réels
            satisfactionClient = 0.0f; // /5 - TODO: Calculer depuis les évaluations réelles
        } catch (Exception e) {
            LOGGER.severe("Erreur lors du calcul des KPIs: " + e.getMessage());
            totalEntites = 0;
            totalAdministrateurs = 0;
            totalMembres = 0;
            revenusGlobaux = "0 FCFA";
        }
    }
    
    private void initializeAlertes() {
        // Initialiser avec une liste vide - les alertes seront chargées depuis le backend quand le service sera disponible
        alertesRecentes = new ArrayList<>();
    }
    
    private void initializeEntites() {
        topEntites = new ArrayList<>();
        try {
            List<AssociationDTO> associations = associationService.listerToutes(0, 1000);
            topEntites = associations.stream()
                .sorted((a1, a2) -> {
                    int m1 = a1.getNombreMembres() != null ? a1.getNombreMembres() : 0;
                    int m2 = a2.getNombreMembres() != null ? a2.getNombreMembres() : 0;
                    return Integer.compare(m2, m1);
                })
                .limit(5)
                .map(a -> {
                    Entite entite = new Entite();
                    entite.setId(a.getId());
                    entite.setNom(a.getNom());
                    entite.setTypeEntite(a.getTypeAssociation());
                    entite.setNombreMembres(a.getNombreMembres() != null ? a.getNombreMembres() : 0);
                    return entite;
                })
                .collect(java.util.stream.Collectors.toList());
        } catch (Exception e) {
            LOGGER.severe("Erreur lors du chargement des top entités: " + e.getMessage());
        }
    }
    
    private void initializeRepartitionTypes() {
        // Initialiser avec une liste vide - la répartition sera calculée depuis les données réelles quand disponible
        repartitionTypes = new ArrayList<>();
        try {
            // TODO: Calculer la répartition depuis les données réelles des organisations
            // List<AssociationDTO> associations = associationService.listerToutes(0, 1000);
            // Grouper par type et calculer les pourcentages
        } catch (Exception e) {
            LOGGER.warning("Impossible de calculer la répartition des types: " + e.getMessage());
        }
    }
    
    private void initializeActivites() {
        // Initialiser avec une liste vide - les activités seront chargées depuis le backend quand le service sera disponible
        activitesRecentes = new ArrayList<>();
        // TODO: Charger depuis un service d'audit/logs quand disponible
    }
    
    private void initializeEvolution() {
        // Initialiser avec une liste vide - l'évolution sera calculée depuis les données réelles quand disponible
        evolutionEntites = new ArrayList<>();
        // TODO: Calculer l'évolution mensuelle depuis les données historiques des organisations
    }
    
    private void initializeRevenus() {
        // Initialiser avec des valeurs par défaut - les revenus seront calculés depuis les paiements réels quand disponible
        revenus = new RevenusData();
        revenus.setMensuel("0 FCFA");
        revenus.setAnnuel("0 FCFA");
        revenus.setCroissance("0");
        revenus.setMoyenne("0 FCFA");
        revenus.setCroissanceMensuelle("0");
        revenus.setObjectifAnnuel("0 FCFA");
        revenus.setDerniereMAJ(LocalDate.now().format(DateTimeFormatter.ofPattern("dd/MM/yyyy")));
        revenus.setEvolution(new ArrayList<>());
        // TODO: Calculer depuis les paiements/souscriptions réels quand le service sera disponible
    }
    
    // Actions (WOU/DRY - utilisation de navigation outcomes)
    public String creerEntite() {
        return OUTCOME_ENTITE_NOUVELLE + "?faces-redirect=true";
    }
    
    public String gererEntites() {
        return OUTCOME_ENTITE_GESTION + "?faces-redirect=true";
    }
    
    public String genererRapport() {
        return OUTCOME_SUPER_ADMIN_RAPPORTS + "?faces-redirect=true";
    }
    
    public String configurer() {
        return OUTCOME_SUPER_ADMIN_CONFIGURATION + "?faces-redirect=true";
    }
    
    public void voirAlerte(Alerte alerte) {
        LOGGER.info("Voir alerte: " + alerte.getTitre());
    }
    
    public String voirToutesAlertes() {
        return OUTCOME_SUPER_ADMIN_ALERTES + "?faces-redirect=true";
    }
    
    public String voirTouteActivite() {
        return OUTCOME_SUPER_ADMIN_ACTIVITE + "?faces-redirect=true";
    }
    
    public void exporterRapportFinancier() {
        LOGGER.info("Export du rapport financier généré");
    }
    
    // Getters et Setters
    public String getNomComplet() { return nomComplet; }
    public void setNomComplet(String nomComplet) { this.nomComplet = nomComplet; }
    
    public String getDerniereConnexion() { return derniereConnexion; }
    public void setDerniereConnexion(String derniereConnexion) { this.derniereConnexion = derniereConnexion; }
    
    public int getTotalEntites() { return totalEntites; }
    public void setTotalEntites(int totalEntites) { this.totalEntites = totalEntites; }
    
    public int getTotalAdministrateurs() { return totalAdministrateurs; }
    public void setTotalAdministrateurs(int totalAdministrateurs) { this.totalAdministrateurs = totalAdministrateurs; }
    
    public int getTotalMembres() { return totalMembres; }
    public void setTotalMembres(int totalMembres) { this.totalMembres = totalMembres; }
    
    public String getRevenusGlobaux() { return revenusGlobaux; }
    public void setRevenusGlobaux(String revenusGlobaux) { this.revenusGlobaux = revenusGlobaux; }
    
    public int getAlertesCount() { return alertesCount; }
    public void setAlertesCount(int alertesCount) { this.alertesCount = alertesCount; }
    
    public String getCroissanceEntites() { return croissanceEntites; }
    public void setCroissanceEntites(String croissanceEntites) { this.croissanceEntites = croissanceEntites; }
    
    public int getActiviteJournaliere() { return activiteJournaliere; }
    public void setActiviteJournaliere(int activiteJournaliere) { this.activiteJournaliere = activiteJournaliere; }
    
    // Getters pour les nouvelles métriques
    public int getTotalSouscriptions() { return totalSouscriptions; }
    public void setTotalSouscriptions(int totalSouscriptions) { this.totalSouscriptions = totalSouscriptions; }
    
    public int getSouscriptionsActives() { return souscriptionsActives; }
    public void setSouscriptionsActives(int souscriptionsActives) { this.souscriptionsActives = souscriptionsActives; }
    
    public int getSouscriptionsExpirantSous30Jours() { return souscriptionsExpirantSous30Jours; }
    public void setSouscriptionsExpirantSous30Jours(int souscriptionsExpirantSous30Jours) { this.souscriptionsExpirantSous30Jours = souscriptionsExpirantSous30Jours; }
    
    public float getTauxConversion() { return tauxConversion; }
    public void setTauxConversion(float tauxConversion) { this.tauxConversion = tauxConversion; }
    
    public BigDecimal getRevenusStarter() { return revenusStarter; }
    public void setRevenusStarter(BigDecimal revenusStarter) { this.revenusStarter = revenusStarter; }
    
    public BigDecimal getRevenusStandard() { return revenusStandard; }
    public void setRevenusStandard(BigDecimal revenusStandard) { this.revenusStandard = revenusStandard; }
    
    public BigDecimal getRevenusPremmium() { return revenusPremmium; }
    public void setRevenusPremmium(BigDecimal revenusPremmium) { this.revenusPremmium = revenusPremmium; }
    
    public BigDecimal getRevenusCristal() { return revenusCristal; }
    public void setRevenusCristal(BigDecimal revenusCristal) { this.revenusCristal = revenusCristal; }
    
    public float getDisponibiliteSysteme() { return disponibiliteSysteme; }
    public void setDisponibiliteSysteme(float disponibiliteSysteme) { this.disponibiliteSysteme = disponibiliteSysteme; }
    
    public int getTempsReponsMoyen() { return tempsReponsMoyen; }
    public void setTempsReponsMoyen(int tempsReponsMoyen) { this.tempsReponsMoyen = tempsReponsMoyen; }
    
    public int getTicketsSupportOuverts() { return ticketsSupportOuverts; }
    public void setTicketsSupportOuverts(int ticketsSupportOuverts) { this.ticketsSupportOuverts = ticketsSupportOuverts; }
    
    public float getSatisfactionClient() { return satisfactionClient; }
    public void setSatisfactionClient(float satisfactionClient) { this.satisfactionClient = satisfactionClient; }
    
    // Méthodes utilitaires
    public String getRevenusStarterFormat() {
        return String.format("%,.0f FCFA", revenusStarter);
    }
    
    public String getRevenusStandardFormat() {
        return String.format("%,.0f FCFA", revenusStandard);
    }
    
    public String getRevenusPremmiumFormat() {
        return String.format("%,.0f FCFA", revenusPremmium);
    }
    
    public String getRevenusCristalFormat() {
        return String.format("%,.0f FCFA", revenusCristal);
    }
    
    public String getTauxConversionFormat() {
        return String.format("%.1f%%", tauxConversion);
    }
    
    public String getDisponibiliteSystemeFormat() {
        return String.format("%.1f%%", disponibiliteSysteme);
    }
    
    public String getSatisfactionClientFormat() {
        return String.format("%.1f/5", satisfactionClient);
    }
    
    public List<Alerte> getAlertesRecentes() { return alertesRecentes; }
    public void setAlertesRecentes(List<Alerte> alertesRecentes) { this.alertesRecentes = alertesRecentes; }
    
    public List<Entite> getTopEntites() { return topEntites; }
    public void setTopEntites(List<Entite> topEntites) { this.topEntites = topEntites; }
    
    public List<TypeEntite> getRepartitionTypes() { return repartitionTypes; }
    public void setRepartitionTypes(List<TypeEntite> repartitionTypes) { this.repartitionTypes = repartitionTypes; }
    
    public List<Activite> getActivitesRecentes() { return activitesRecentes; }
    public void setActivitesRecentes(List<Activite> activitesRecentes) { this.activitesRecentes = activitesRecentes; }
    
    public List<EvolutionMois> getEvolutionEntites() { return evolutionEntites; }
    public void setEvolutionEntites(List<EvolutionMois> evolutionEntites) { this.evolutionEntites = evolutionEntites; }
    
    public RevenusData getRevenus() { return revenus; }
    public void setRevenus(RevenusData revenus) { this.revenus = revenus; }
    
    public String getPeriodeEvolution() { return periodeEvolution; }
    public void setPeriodeEvolution(String periodeEvolution) { this.periodeEvolution = periodeEvolution; }
    
    // Getters pour les nouvelles propriétés
    public String getCroissanceMembres() { return croissanceMembres; }
    public void setCroissanceMembres(String croissanceMembres) { this.croissanceMembres = croissanceMembres; }
    
    public String getCroissanceRevenus() { return croissanceRevenus; }
    public void setCroissanceRevenus(String croissanceRevenus) { this.croissanceRevenus = croissanceRevenus; }
    
    public int getNouvellesEntites() { return nouvellesEntites; }
    public void setNouvellesEntites(int nouvellesEntites) { this.nouvellesEntites = nouvellesEntites; }
    
    public int getUtilisateursActifs() { return utilisateursActifs; }
    public void setUtilisateursActifs(int utilisateursActifs) { this.utilisateursActifs = utilisateursActifs; }
    
    // Classes internes
    public static class Alerte {
        private UUID id;
        private String titre;
        private String entite;
        private String date;
        private String icone;
        private String couleur;
        
        // Getters et setters
        public UUID getId() { return id; }
        public void setId(UUID id) { this.id = id; }
        
        public String getTitre() { return titre; }
        public void setTitre(String titre) { this.titre = titre; }
        
        public String getEntite() { return entite; }
        public void setEntite(String entite) { this.entite = entite; }
        
        public String getDate() { return date; }
        public void setDate(String date) { this.date = date; }
        
        public String getIcone() { return icone; }
        public void setIcone(String icone) { this.icone = icone; }
        
        public String getCouleur() { return couleur; }
        public void setCouleur(String couleur) { this.couleur = couleur; }
    }
    
    public static class Entite {
        private UUID id;
        private String nom;
        private String typeEntite;
        private int nombreMembres;
        
        // 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 getTypeEntite() { return typeEntite; }
        public void setTypeEntite(String typeEntite) { this.typeEntite = typeEntite; }
        
        public int getNombreMembres() { return nombreMembres; }
        public void setNombreMembres(int nombreMembres) { this.nombreMembres = nombreMembres; }
    }
    
    public static class TypeEntite {
        private String nom;
        private String description;
        private int nombre;
        private int pourcentage;
        private String icone;
        private String couleurBg;
        private String couleurTexte;
        
        // Getters et setters
        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 getNombre() { return nombre; }
        public void setNombre(int nombre) { this.nombre = nombre; }
        
        public int getPourcentage() { return pourcentage; }
        public void setPourcentage(int pourcentage) { this.pourcentage = pourcentage; }
        
        public String getIcone() { return icone; }
        public void setIcone(String icone) { this.icone = icone; }
        
        public String getCouleurBg() { return couleurBg; }
        public void setCouleurBg(String couleurBg) { this.couleurBg = couleurBg; }
        
        public String getCouleurTexte() { return couleurTexte; }
        public void setCouleurTexte(String couleurTexte) { this.couleurTexte = couleurTexte; }
    }
    
    public static class Activite {
        private UUID id;
        private String description;
        private String entite;
        private String date;
        private String icone;
        private String utilisateur;
        private String details;
        
        // Getters et setters
        public UUID getId() { return id; }
        public void setId(UUID id) { this.id = id; }
        
        public String getDescription() { return description; }
        public void setDescription(String description) { this.description = description; }
        
        public String getEntite() { return entite; }
        public void setEntite(String entite) { this.entite = entite; }
        
        public String getDate() { return date; }
        public void setDate(String date) { this.date = date; }
        
        public String getIcone() { return icone; }
        public void setIcone(String icone) { this.icone = icone; }
        
        public String getUtilisateur() { return utilisateur; }
        public void setUtilisateur(String utilisateur) { this.utilisateur = utilisateur; }
        
        public String getDetails() { return details; }
        public void setDetails(String details) { this.details = details; }
    }
    
    public static class EvolutionMois {
        private String periode;
        private int valeur;
        private int hauteur;
        
        // Getters et setters
        public String getPeriode() { return periode; }
        public void setPeriode(String periode) { this.periode = periode; }
        
        public int getValeur() { return valeur; }
        public void setValeur(int valeur) { this.valeur = valeur; }
        
        public int getHauteur() { return hauteur; }
        public void setHauteur(int hauteur) { this.hauteur = hauteur; }
    }
    
    public static class RevenusData {
        private String mensuel;
        private String annuel;
        private String croissance;
        private String moyenne;
        private String croissanceMensuelle;
        private String objectifAnnuel;
        private String derniereMAJ;
        private List<MoisRevenu> evolution = new ArrayList<>();
        
        // Getters et setters
        public String getMensuel() { return mensuel; }
        public void setMensuel(String mensuel) { this.mensuel = mensuel; }
        
        public String getAnnuel() { return annuel; }
        public void setAnnuel(String annuel) { this.annuel = annuel; }
        
        public String getCroissance() { return croissance; }
        public void setCroissance(String croissance) { this.croissance = croissance; }
        
        public String getMoyenne() { return moyenne; }
        public void setMoyenne(String moyenne) { this.moyenne = moyenne; }
        
        public String getCroissanceMensuelle() { return croissanceMensuelle; }
        public void setCroissanceMensuelle(String croissanceMensuelle) { this.croissanceMensuelle = croissanceMensuelle; }
        
        public String getObjectifAnnuel() { return objectifAnnuel; }
        public void setObjectifAnnuel(String objectifAnnuel) { this.objectifAnnuel = objectifAnnuel; }
        
        public String getDerniereMAJ() { return derniereMAJ; }
        public void setDerniereMAJ(String derniereMAJ) { this.derniereMAJ = derniereMAJ; }
        
        public List<MoisRevenu> getEvolution() { return evolution; }
        public void setEvolution(List<MoisRevenu> evolution) { this.evolution = evolution; }
    }
    
    public static class MoisRevenu {
        private String nom;
        private int hauteur;
        private String valeur;
        
        // Getters et setters
        public String getNom() { return nom; }
        public void setNom(String nom) { this.nom = nom; }
        
        public int getHauteur() { return hauteur; }
        public void setHauteur(int hauteur) { this.hauteur = hauteur; }
        
        public String getValeur() { return valeur; }
        public void setValeur(String valeur) { this.valeur = valeur; }
    }
}