package dev.lions.unionflow.client.view;

import dev.lions.unionflow.client.dto.MembreDTO;
import dev.lions.unionflow.client.service.MembreService;
import dev.lions.unionflow.client.service.AssociationService;
import jakarta.enterprise.context.SessionScoped;
import jakarta.inject.Named;
import jakarta.inject.Inject;
import jakarta.annotation.PostConstruct;
import jakarta.faces.context.FacesContext;
import jakarta.faces.application.FacesMessage;
import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.microprofile.rest.client.inject.RestClient;
import java.io.IOException;
import java.io.Serializable;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.logging.Logger;

@Named("membreListeBean")
@SessionScoped
public class MembreListeBean implements Serializable {
    
    private static final long serialVersionUID = 1L;
    private static final Logger LOGGER = Logger.getLogger(MembreListeBean.class.getName());
    
    @Inject
    @RestClient
    MembreService membreService;
    
    @Inject
    @RestClient
    AssociationService associationService;
    
    // Statistiques générales
    private int totalMembres;
    private int membresActifs;
    private int cotisationsAJour;
    private int nouveauxMembres;
    private int membresInactifs;
    
    // Filtres
    private String searchFilter = "";
    private String statutFilter = "";
    private String typeFilter = "";
    private String cotisationFilter = "";
    private String entiteFilter = "";
    
    // Filtres avancés
    private Integer ageMin;
    private Integer ageMax;
    private String genreFilter = "";
    private String villeFilter = "";
    private LocalDate dateAdhesionDebut;
    private LocalDate dateAdhesionFin;
    private String professionFilter = "";
    private Boolean desEnfants;
    
    // Messages groupés
    private String sujetMessage;
    private String contenuMessage;
    private List<String> canauxMessage = new ArrayList<>();
    
    // Import/Export
    private boolean mettreAJourExistants = false;
    private String formatExport = "EXCEL";
    private List<String> colonnesExport = new ArrayList<>();
    private boolean exporterSelection = false;
    
    // Données
    private List<MembreDTO> membres = new ArrayList<>();
    private List<MembreDTO> selectedMembres = new ArrayList<>();
    private List<MembreDTO> membresFiltres = new ArrayList<>();
    private List<Entite> entitesDisponibles = new ArrayList<>();
    
    @PostConstruct
    public void init() {
        try {
            chargerMembres();
            chargerStatistiques();
            chargerEntites();
        } catch (Exception e) {
            LOGGER.severe("Erreur lors de l'initialisation: " + e.getMessage());
            // Pas de données mockées - initialiser à zéro
            this.totalMembres = 0;
            this.membresActifs = 0;
            this.cotisationsAJour = 0;
            this.nouveauxMembres = 0;
            this.membresInactifs = 0;
        }
    }
    
    private void chargerMembres() {
        try {
            // Récupération de tous les membres via le service REST
            membres = membreService.listerTous();
            membresFiltres = new ArrayList<>(membres);
            
            LOGGER.info("Chargement de " + membres.size() + " membres depuis le serveur");
            
        } catch (Exception e) {
            LOGGER.severe("Impossible de charger les membres depuis le serveur: " + e.getMessage());
            // Pas de données mockées - laisser la liste vide
            membres = new ArrayList<>();
            membresFiltres = new ArrayList<>();
        }
    }
    
    private void chargerStatistiques() {
        try {
            // Récupération des statistiques via le service REST
            MembreService.StatistiquesMembreDTO stats = membreService.obtenirStatistiques();
            
            this.totalMembres = stats.getTotalMembres() != null ? stats.getTotalMembres().intValue() : 0;
            this.membresActifs = stats.getMembresActifs() != null ? stats.getMembresActifs().intValue() : 0;
            this.membresInactifs = stats.getMembresInactifs() != null ? stats.getMembresInactifs().intValue() : 0;
            this.nouveauxMembres = stats.getNouveauxMembres30Jours() != null ? stats.getNouveauxMembres30Jours().intValue() : 0;
            
            // Calcul approximatif des cotisations à jour (à implémenter côté serveur)
            this.cotisationsAJour = (int) (this.membresActifs * 0.85);
            
        } catch (Exception e) {
            LOGGER.severe("Impossible de charger les statistiques: " + e.getMessage());
            // Pas de données mockées - laisser les valeurs à zéro
        }
    }
    
    private void chargerEntites() {
        entitesDisponibles = new ArrayList<>();
        try {
            List<dev.lions.unionflow.client.dto.AssociationDTO> associations = associationService.listerToutes(0, 1000);
            for (dev.lions.unionflow.client.dto.AssociationDTO assoc : associations) {
                Entite entite = new Entite();
                entite.setId(assoc.getId());
                entite.setNom(assoc.getNom());
                entitesDisponibles.add(entite);
            }
            LOGGER.info("Chargement de " + entitesDisponibles.size() + " entités disponibles");
        } catch (Exception e) {
            LOGGER.severe("Erreur lors du chargement des entités: " + e.getMessage());
        }
    }
    
    // Actions de recherche et filtrage
    public void rechercher() {
        try {
            List<MembreDTO> resultats = membreService.rechercher(
                searchFilter.isEmpty() ? null : searchFilter,  // nom
                null,  // prenom
                null,  // email
                null,  // telephone
                statutFilter.isEmpty() ? null : statutFilter,
                null,  // associationId
                0,     // page
                100    // size
            );
            
            membresFiltres = resultats;
            LOGGER.info("Recherche effectuée: " + membresFiltres.size() + " résultats");
            
        } catch (Exception e) {
            LOGGER.severe("Erreur lors de la recherche: " + e.getMessage());
            // En cas d'erreur, laisser la liste vide plutôt que des données mockées
            membresFiltres = new ArrayList<>();
        }
    }
    
    public void reinitialiserFiltres() {
        searchFilter = "";
        statutFilter = "";
        typeFilter = "";
        cotisationFilter = "";
        entiteFilter = "";
        ageMin = null;
        ageMax = null;
        genreFilter = "";
        villeFilter = "";
        dateAdhesionDebut = null;
        dateAdhesionFin = null;
        professionFilter = "";
        desEnfants = null;
        
        membresFiltres = new ArrayList<>(membres);
    }
    
    public void actualiser() {
        chargerMembres();
        chargerStatistiques();
        chargerEntites();
    }
    
    public String modifierMembre(MembreDTO membre) {
        return "/pages/secure/membre/modifier?id=" + membre.getId() + "&faces-redirect=true";
    }
    
    // Propriétés pour la page de modification
    private UUID membreSelectionneId;
    private MembreDTO membreSelectionne;
    
    public UUID getMembreSelectionneId() {
        return membreSelectionneId;
    }
    
    public void setMembreSelectionneId(UUID membreSelectionneId) {
        this.membreSelectionneId = membreSelectionneId;
    }
    
    public MembreDTO getMembreSelectionne() {
        return membreSelectionne;
    }
    
    public void setMembreSelectionne(MembreDTO membreSelectionne) {
        this.membreSelectionne = membreSelectionne;
    }
    
    public void chargerMembreSelectionne() {
        if (membreSelectionneId != null) {
            try {
                membreSelectionne = membreService.obtenirParId(membreSelectionneId);
                LOGGER.info("Membre chargé pour modification: " + membreSelectionne.getNomComplet());
            } catch (Exception e) {
                LOGGER.severe("Erreur lors du chargement du membre: " + e.getMessage());
                FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erreur", 
                        "Impossible de charger le membre: " + e.getMessage()));
            }
        }
    }
    
    public String modifierMembreSelectionne() {
        try {
            membreService.modifier(membreSelectionne.getId(), membreSelectionne);
            LOGGER.info("Membre modifié: " + membreSelectionne.getNomComplet());
            FacesContext.getCurrentInstance().addMessage(null,
                new FacesMessage(FacesMessage.SEVERITY_INFO, "Succès", 
                    "Le membre a été modifié avec succès"));
            return "/pages/secure/membre/liste?faces-redirect=true";
        } catch (Exception e) {
            LOGGER.severe("Erreur lors de la modification: " + e.getMessage());
            FacesContext.getCurrentInstance().addMessage(null,
                new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erreur", 
                    "Impossible de modifier le membre: " + e.getMessage()));
            return null;
        }
    }
    
    // Méthode pour obtenir la liste des organisations pour le dropdown
    public List<jakarta.faces.model.SelectItem> getOrganisationsSelectItems() {
        // TODO: Implémenter la récupération des organisations
        // Pour l'instant, retourner une liste vide
        return new java.util.ArrayList<>();
    }
    
    public String gererCotisations(MembreDTO membre) {
        return "/pages/secure/cotisations?membreId=" + membre.getId() + "&faces-redirect=true";
    }
    
    public void appliquerFiltresAvances() {
        // Appliquer les filtres avancés
        LOGGER.info("Application des filtres avancés");
    }
    
    // Import/Export
    public void importerMembres() {
        // Logique d'import des membres
        LOGGER.info("Import des membres");
    }
    
    public void telechargerModele() {
        // Télécharger modèle d'import
        LOGGER.info("Téléchargement du modèle");
    }
    
    // Actions avec DTOs
    public String voirProfil(MembreDTO membre) {
        return "/pages/secure/membre/profil?id=" + membre.getId() + "&faces-redirect=true";
    }
    
    public void activerMembre(MembreDTO membre) {
        try {
            membreService.activer(membre.getId());
            membre.setStatut("ACTIF");
            LOGGER.info("Membre activé: " + membre.getNomComplet());
        } catch (Exception e) {
            LOGGER.severe("Erreur lors de l'activation: " + e.getMessage());
        }
    }
    
    public void desactiverMembre(MembreDTO membre) {
        try {
            membreService.desactiver(membre.getId());
            membre.setStatut("INACTIF");
            LOGGER.info("Membre désactivé: " + membre.getNomComplet());
        } catch (Exception e) {
            LOGGER.severe("Erreur lors de la désactivation: " + e.getMessage());
        }
    }
    
    public void exporterMembres() {
        try {
            byte[] excelData = membreService.exporterExcel(formatExport, null, statutFilter.isEmpty() ? null : statutFilter);
            
            // Téléchargement du fichier Excel via JSF
            FacesContext facesContext = FacesContext.getCurrentInstance();
            HttpServletResponse response = (HttpServletResponse) facesContext.getExternalContext().getResponse();
            
            response.reset();
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setHeader("Content-Disposition", "attachment; filename=\"membres_export_" + 
                LocalDate.now() + "." + (formatExport != null ? formatExport.toLowerCase() : "xlsx") + "\"");
            response.setContentLength(excelData.length);
            
            response.getOutputStream().write(excelData);
            response.getOutputStream().flush();
            facesContext.responseComplete();
            
            LOGGER.info("Export Excel généré et téléchargé: " + excelData.length + " bytes");
        } catch (IOException e) {
            LOGGER.severe("Erreur lors du téléchargement de l'export: " + e.getMessage());
        } catch (Exception e) {
            LOGGER.severe("Erreur lors de l'export: " + e.getMessage());
        }
    }
    
    // Getters et Setters
    public int getTotalMembres() { return totalMembres; }
    public void setTotalMembres(int totalMembres) { this.totalMembres = totalMembres; }
    
    public int getMembresActifs() { return membresActifs; }
    public void setMembresActifs(int membresActifs) { this.membresActifs = membresActifs; }
    
    public int getCotisationsAJour() { return cotisationsAJour; }
    public void setCotisationsAJour(int cotisationsAJour) { this.cotisationsAJour = cotisationsAJour; }
    
    public int getNouveauxMembres() { return nouveauxMembres; }
    public void setNouveauxMembres(int nouveauxMembres) { this.nouveauxMembres = nouveauxMembres; }
    
    public int getMembresInactifs() { return membresInactifs; }
    public void setMembresInactifs(int membresInactifs) { this.membresInactifs = membresInactifs; }
    
    public String getSearchFilter() { return searchFilter; }
    public void setSearchFilter(String searchFilter) { this.searchFilter = searchFilter; }
    
    public String getStatutFilter() { return statutFilter; }
    public void setStatutFilter(String statutFilter) { this.statutFilter = statutFilter; }
    
    public String getTypeFilter() { return typeFilter; }
    public void setTypeFilter(String typeFilter) { this.typeFilter = typeFilter; }
    
    public String getCotisationFilter() { return cotisationFilter; }
    public void setCotisationFilter(String cotisationFilter) { this.cotisationFilter = cotisationFilter; }
    
    public String getEntiteFilter() { return entiteFilter; }
    public void setEntiteFilter(String entiteFilter) { this.entiteFilter = entiteFilter; }
    
    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 getGenreFilter() { return genreFilter; }
    public void setGenreFilter(String genreFilter) { this.genreFilter = genreFilter; }
    
    public String getVilleFilter() { return villeFilter; }
    public void setVilleFilter(String villeFilter) { this.villeFilter = villeFilter; }
    
    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 String getProfessionFilter() { return professionFilter; }
    public void setProfessionFilter(String professionFilter) { this.professionFilter = professionFilter; }
    
    public Boolean getDesEnfants() { return desEnfants; }
    public Boolean isDesEnfants() { return desEnfants; }
    public void setDesEnfants(Boolean desEnfants) { this.desEnfants = desEnfants; }
    
    public String getSujetMessage() { return sujetMessage; }
    public void setSujetMessage(String sujetMessage) { this.sujetMessage = sujetMessage; }
    
    public String getContenuMessage() { return contenuMessage; }
    public void setContenuMessage(String contenuMessage) { this.contenuMessage = contenuMessage; }
    
    public List<String> getCanauxMessage() { return canauxMessage; }
    public void setCanauxMessage(List<String> canauxMessage) { this.canauxMessage = canauxMessage; }
    
    public boolean isMettreAJourExistants() { return mettreAJourExistants; }
    public void setMettreAJourExistants(boolean mettreAJourExistants) { this.mettreAJourExistants = mettreAJourExistants; }
    
    public String getFormatExport() { return formatExport; }
    public void setFormatExport(String formatExport) { this.formatExport = formatExport; }
    
    public List<String> getColonnesExport() { return colonnesExport; }
    public void setColonnesExport(List<String> colonnesExport) { this.colonnesExport = colonnesExport; }
    
    public boolean isExporterSelection() { return exporterSelection; }
    public void setExporterSelection(boolean exporterSelection) { this.exporterSelection = exporterSelection; }
    
    public List<MembreDTO> getMembres() { return membresFiltres; }
    public void setMembres(List<MembreDTO> membres) { this.membres = membres; }
    
    public List<MembreDTO> getSelectedMembres() { return selectedMembres; }
    public void setSelectedMembres(List<MembreDTO> selectedMembres) { this.selectedMembres = selectedMembres; }
    
    public List<MembreDTO> getMembresFiltres() { return membresFiltres; }
    public void setMembresFiltres(List<MembreDTO> membresFiltres) { this.membresFiltres = membresFiltres; }
    
    public List<Entite> getEntitesDisponibles() { return entitesDisponibles; }
    public void setEntitesDisponibles(List<Entite> entitesDisponibles) { this.entitesDisponibles = entitesDisponibles; }
    
    // Classe interne pour les entités
    public static class Entite implements Serializable {
        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; }
    }
}