package dev.lions.unionflow.client.view;

import dev.lions.unionflow.client.service.SuggestionService;
import dev.lions.unionflow.server.api.dto.suggestion.request.*;
import dev.lions.unionflow.server.api.dto.suggestion.response.*;
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 org.jboss.logging.Logger;
import dev.lions.unionflow.client.service.ErrorHandlerService;
import dev.lions.unionflow.client.service.RetryService;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * Bean JSF pour la gestion des suggestions
 * 
 * @author UnionFlow Team
 * @version 1.0
 */
@Named("suggestionBean")
@ViewScoped
public class SuggestionBean implements Serializable {
    
    private static final long serialVersionUID = 1L;
    private static final Logger LOG = Logger.getLogger(SuggestionBean.class);
    
    @Inject
    @RestClient
    private SuggestionService suggestionService;
    
    @Inject
    private UserSession userSession;
    
    @Inject
    ErrorHandlerService errorHandler;
    
    @Inject
    RetryService retryService;
    
    // Données
    private List<SuggestionResponse> suggestions = new ArrayList<>();
    private List<SuggestionResponse> suggestionsPopulaires = new ArrayList<>();
    private List<SuggestionResponse> mesSuggestions = new ArrayList<>();
    private SuggestionResponse suggestionSelectionnee;
    private SuggestionResponse nouvelleSuggestion;
    
    // Filtres
    private String statutFiltre;
    private String categorieFiltre;
    private String triFiltre;
    private String recherche;
    
    // Statistiques
    private int totalSuggestions = 0;
    private int suggestionsImplementees = 0;
    private int totalVotes = 0;
    private int contributeursActifs = 0;
    
    // Utilisateur actuel (récupéré depuis la session)
    private UUID utilisateurId;
    
    // Dialog
    private boolean afficherDialogNouvelleSuggestion = false;
    
    @PostConstruct
    public void init() {
        // Récupérer l'utilisateur depuis la session
        if (userSession != null && userSession.getCurrentUser() != null) {
            utilisateurId = userSession.getCurrentUser().getId();
            LOG.infof("Utilisateur récupéré depuis la session: %s", utilisateurId);
        } else {
            LOG.warn("Aucun utilisateur trouvé dans la session");
        }
        nouvelleSuggestion = new SuggestionResponse();
        chargerSuggestions();
        chargerStatistiques();
    }
    
    public void chargerSuggestions() {
        try {
            suggestions = retryService.executeWithRetrySupplier(
                () -> suggestionService.listerSuggestions(),
                "chargement des suggestions"
            );
            // Filtrer les suggestions populaires (top votes)
            suggestionsPopulaires = suggestions.stream()
                .sorted((s1, s2) -> Integer.compare(
                    s2.getNbVotes() != null ? s2.getNbVotes() : 0,
                    s1.getNbVotes() != null ? s1.getNbVotes() : 0))
                .limit(10)
                .collect(java.util.stream.Collectors.toList());
            
            // Filtrer mes suggestions
            if (utilisateurId != null) {
                mesSuggestions = suggestions.stream()
                    .filter(s -> utilisateurId.equals(s.getUtilisateurId()))
                    .collect(java.util.stream.Collectors.toList());
            }
        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors du chargement des suggestions");
            errorHandler.handleException(e, "lors du chargement des suggestions", null);
            suggestions = new ArrayList<>();
            suggestionsPopulaires = new ArrayList<>();
            mesSuggestions = new ArrayList<>();
        }
    }
    
    public void chargerStatistiques() {
        try {
            Map<String, Object> stats = retryService.executeWithRetrySupplier(
                () -> suggestionService.obtenirStatistiques(),
                "chargement des statistiques de suggestions"
            );
            totalSuggestions = ((Number) stats.getOrDefault("totalSuggestions", 0)).intValue();
            suggestionsImplementees = ((Number) stats.getOrDefault("suggestionsImplementees", 0)).intValue();
            totalVotes = ((Number) stats.getOrDefault("totalVotes", 0)).intValue();
            contributeursActifs = ((Number) stats.getOrDefault("contributeursActifs", 0)).intValue();
        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors du chargement des statistiques");
        }
    }
    
    public void creerSuggestion() {
        try {
            if (nouvelleSuggestion != null && utilisateurId != null) {
                nouvelleSuggestion.setUtilisateurId(utilisateurId);
                // Mapper SuggestionResponse vers CreateSuggestionRequest
                CreateSuggestionRequest request = new CreateSuggestionRequest(
                    nouvelleSuggestion.getUtilisateurId(),
                    nouvelleSuggestion.getUtilisateurNom(),
                    nouvelleSuggestion.getTitre(),
                    nouvelleSuggestion.getDescription(),
                    nouvelleSuggestion.getJustification(),
                    nouvelleSuggestion.getCategorie(),
                    nouvelleSuggestion.getPrioriteEstimee(),
                    nouvelleSuggestion.getPiecesJointes()
                );
                SuggestionResponse created = retryService.executeWithRetrySupplier(
                    () -> suggestionService.creerSuggestion(request),
                    "création d'une suggestion"
                );
                suggestions.add(0, created);
                nouvelleSuggestion = new SuggestionResponse();
                afficherDialogNouvelleSuggestion = false;
                chargerStatistiques();
                errorHandler.showSuccess("Succès", "Suggestion créée avec succès");
            }
        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors de la création de la suggestion");
            errorHandler.handleException(e, "lors de la création d'une suggestion", null);
        }
    }
    
    public void voterPourSuggestion(UUID suggestionId) {
        try {
            if (utilisateurId != null) {
                retryService.executeWithRetrySupplier(
                    () -> {
                        suggestionService.voterPourSuggestion(suggestionId, utilisateurId);
                        return null;
                    },
                    "vote pour une suggestion"
                );
                chargerSuggestions();
                errorHandler.showSuccess("Succès", "Vote enregistré avec succès");
            }
        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors du vote");
            errorHandler.handleException(e, "lors du vote pour une suggestion", null);
        }
    }
    
    public void filtrer() {
        chargerSuggestions();
    }
    
    public void ouvrirDialogNouvelleSuggestion() {
        nouvelleSuggestion = new SuggestionResponse();
        afficherDialogNouvelleSuggestion = true;
    }
    
    public void fermerDialogNouvelleSuggestion() {
        afficherDialogNouvelleSuggestion = false;
        nouvelleSuggestion = new SuggestionResponse();
    }
    
    
    // Getters et Setters
    public List<SuggestionResponse> getSuggestions() { return suggestions; }
    public void setSuggestions(List<SuggestionResponse> suggestions) { this.suggestions = suggestions; }
    
    public List<SuggestionResponse> getSuggestionsPopulaires() { return suggestionsPopulaires; }
    public void setSuggestionsPopulaires(List<SuggestionResponse> suggestionsPopulaires) { 
        this.suggestionsPopulaires = suggestionsPopulaires; 
    }
    
    public List<SuggestionResponse> getMesSuggestions() { return mesSuggestions; }
    public void setMesSuggestions(List<SuggestionResponse> mesSuggestions) { 
        this.mesSuggestions = mesSuggestions; 
    }
    
    public SuggestionResponse getSuggestionSelectionnee() { return suggestionSelectionnee; }
    public void setSuggestionSelectionnee(SuggestionResponse suggestionSelectionnee) { 
        this.suggestionSelectionnee = suggestionSelectionnee; 
    }
    
    public SuggestionResponse getNouvelleSuggestion() { return nouvelleSuggestion; }
    public void setNouvelleSuggestion(SuggestionResponse nouvelleSuggestion) { 
        this.nouvelleSuggestion = nouvelleSuggestion; 
    }
    
    public String getStatutFiltre() { return statutFiltre; }
    public void setStatutFiltre(String statutFiltre) { this.statutFiltre = statutFiltre; }
    
    public String getCategorieFiltre() { return categorieFiltre; }
    public void setCategorieFiltre(String categorieFiltre) { this.categorieFiltre = categorieFiltre; }
    
    public String getTriFiltre() { return triFiltre; }
    public void setTriFiltre(String triFiltre) { this.triFiltre = triFiltre; }
    
    public String getRecherche() { return recherche; }
    public void setRecherche(String recherche) { this.recherche = recherche; }
    
    public int getTotalSuggestions() { return totalSuggestions; }
    public void setTotalSuggestions(int totalSuggestions) { this.totalSuggestions = totalSuggestions; }
    
    public int getSuggestionsImplementees() { return suggestionsImplementees; }
    public void setSuggestionsImplementees(int suggestionsImplementees) { 
        this.suggestionsImplementees = suggestionsImplementees; 
    }
    
    public int getTotalVotes() { return totalVotes; }
    public void setTotalVotes(int totalVotes) { this.totalVotes = totalVotes; }
    
    public int getContributeursActifs() { return contributeursActifs; }
    public void setContributeursActifs(int contributeursActifs) { 
        this.contributeursActifs = contributeursActifs; 
    }
    
    public boolean isAfficherDialogNouvelleSuggestion() { return afficherDialogNouvelleSuggestion; }
    public void setAfficherDialogNouvelleSuggestion(boolean afficherDialogNouvelleSuggestion) { 
        this.afficherDialogNouvelleSuggestion = afficherDialogNouvelleSuggestion; 
    }
}

