package dev.lions.unionflow.client.view;

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

/**
 * Bean JSF pour la gestion des favoris
 * 
 * @author UnionFlow Team
 * @version 1.0
 */
@Named("favorisBean")
@ViewScoped
public class FavorisBean implements Serializable {
    
    private static final long serialVersionUID = 1L;
    private static final Logger LOG = Logger.getLogger(FavorisBean.class);
    
    @Inject
    @RestClient
    private FavorisService favorisService;
    
    @Inject
    private UserSession userSession;
    
    @Inject
    ErrorHandlerService errorHandler;
    
    @Inject
    RetryService retryService;
    
    // Données
    private List<FavoriResponse> pagesFavorites = new ArrayList<>();
    private List<FavoriResponse> documentsFavoris = new ArrayList<>();
    private List<FavoriResponse> contactsFavoris = new ArrayList<>();
    private List<FavoriResponse> raccourcis = new ArrayList<>();
    
    // Statistiques
    private int totalFavoris = 0;
    private int totalPages = 0;
    private int totalDocuments = 0;
    private int totalContacts = 0;
    
    // Utilisateur actuel (récupéré depuis la session)
    private UUID utilisateurId;
    
    @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");
        }
        chargerFavoris();
    }
    
    public void chargerFavoris() {
        try {
            if (utilisateurId != null) {
                List<FavoriResponse> favoris = retryService.executeWithRetrySupplier(
                    () -> favorisService.listerFavoris(utilisateurId),
                    "chargement des favoris"
                );
                
                // Séparer par type
                pagesFavorites = new ArrayList<>();
                documentsFavoris = new ArrayList<>();
                contactsFavoris = new ArrayList<>();
                raccourcis = new ArrayList<>();
                
                for (FavoriResponse favori : favoris) {
                    switch (favori.getTypeFavori()) {
                        case "PAGE":
                            pagesFavorites.add(favori);
                            break;
                        case "DOCUMENT":
                            documentsFavoris.add(favori);
                            break;
                        case "CONTACT":
                            contactsFavoris.add(favori);
                            break;
                        case "RACCOURCI":
                            raccourcis.add(favori);
                            break;
                    }
                }
                
                chargerStatistiques();
            }
        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors du chargement des favoris");
            errorHandler.handleException(e, "lors du chargement des favoris", null);
        }
    }
    
    public void chargerStatistiques() {
        try {
            if (utilisateurId != null) {
                Map<String, Object> stats = retryService.executeWithRetrySupplier(
                    () -> favorisService.obtenirStatistiques(utilisateurId),
                    "chargement des statistiques de favoris"
                );
                totalFavoris = ((Number) stats.getOrDefault("totalFavoris", 0)).intValue();
                totalPages = ((Number) stats.getOrDefault("totalPages", 0)).intValue();
                totalDocuments = ((Number) stats.getOrDefault("totalDocuments", 0)).intValue();
                totalContacts = ((Number) stats.getOrDefault("totalContacts", 0)).intValue();
            }
        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors du chargement des statistiques");
        }
    }
    
    public void retirerPageFavorite(UUID id) {
        try {
            retryService.executeWithRetrySupplier(
                () -> {
                    favorisService.supprimerFavori(id);
                    return null;
                },
                "suppression d'un favori"
            );
            chargerFavoris();
        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors de la suppression du favori");
            errorHandler.handleException(e, "lors de la suppression d'un favori", null);
        }
    }
    
    public void retirerDocumentFavorite(UUID id) {
        retirerPageFavorite(id);
    }
    
    public void retirerContactFavorite(UUID id) {
        retirerPageFavorite(id);
    }
    
    public void supprimerRaccourci(UUID id) {
        retirerPageFavorite(id);
    }
    
    /**
     * Supprime tous les favoris de l'utilisateur (pages, documents, contacts, raccourcis).
     */
    public void nettoyerTousFavoris() {
        try {
            List<UUID> idsASupprimer = new ArrayList<>();
            for (FavoriResponse f : pagesFavorites) {
                if (f.getId() != null) idsASupprimer.add(f.getId());
            }
            for (FavoriResponse f : documentsFavoris) {
                if (f.getId() != null) idsASupprimer.add(f.getId());
            }
            for (FavoriResponse f : contactsFavoris) {
                if (f.getId() != null) idsASupprimer.add(f.getId());
            }
            for (FavoriResponse f : raccourcis) {
                if (f.getId() != null) idsASupprimer.add(f.getId());
            }
            for (UUID id : idsASupprimer) {
                retryService.executeWithRetrySupplier(
                    () -> {
                        favorisService.supprimerFavori(id);
                        return null;
                    },
                    "suppression d'un favori"
                );
            }
            if (!idsASupprimer.isEmpty()) {
                LOG.infof("Suppression en masse: %d favoris supprimés", idsASupprimer.size());
                errorHandler.showSuccess("Favoris", "Tous les favoris ont été supprimés");
            }
            chargerFavoris();
        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors du nettoyage des favoris");
            errorHandler.handleException(e, "lors du nettoyage des favoris", null);
        }
    }
    
    // Getters et Setters
    public List<FavoriResponse> getPagesFavorites() { return pagesFavorites; }
    public void setPagesFavorites(List<FavoriResponse> pagesFavorites) { this.pagesFavorites = pagesFavorites; }
    
    public List<FavoriResponse> getDocumentsFavoris() { return documentsFavoris; }
    public void setDocumentsFavoris(List<FavoriResponse> documentsFavoris) { this.documentsFavoris = documentsFavoris; }
    
    public List<FavoriResponse> getContactsFavoris() { return contactsFavoris; }
    public void setContactsFavoris(List<FavoriResponse> contactsFavoris) { this.contactsFavoris = contactsFavoris; }
    
    public List<FavoriResponse> getRaccourcis() { return raccourcis; }
    public void setRaccourcis(List<FavoriResponse> raccourcis) { this.raccourcis = raccourcis; }
    
    public int getTotalFavoris() { return totalFavoris; }
    public void setTotalFavoris(int totalFavoris) { this.totalFavoris = totalFavoris; }
    
    public int getTotalPages() { return totalPages; }
    public void setTotalPages(int totalPages) { this.totalPages = totalPages; }
    
    public int getTotalDocuments() { return totalDocuments; }
    public void setTotalDocuments(int totalDocuments) { this.totalDocuments = totalDocuments; }
    
    public int getTotalContacts() { return totalContacts; }
    public void setTotalContacts(int totalContacts) { this.totalContacts = totalContacts; }
}
