package dev.lions.unionflow.client.view;

import dev.lions.unionflow.client.service.ErrorHandlerService;
import dev.lions.unionflow.client.view.RapportsBean.HistoriqueRapport;
import jakarta.faces.view.ViewScoped;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import jakarta.annotation.PostConstruct;
import org.jboss.logging.Logger;
import java.io.Serializable;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.UUID;

/**
 * Bean pour la page de détails d'un rapport (WOU/DRY)
 * 
 * @author UnionFlow Team
 * @version 1.0
 */
@Named("rapportDetailsBean")
@ViewScoped
public class RapportDetailsBean implements Serializable {
    
    private static final long serialVersionUID = 1L;
    private static final Logger LOG = Logger.getLogger(RapportDetailsBean.class);
    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("dd/MM/yyyy");
    
    // Constantes de navigation outcomes (WOU/DRY - réutilisables)
    private static final String OUTCOME_RAPPORTS = "rapportMembresPage";
    
    @Inject
    private RapportsBean rapportsBean;
    
    @Inject
    ErrorHandlerService errorHandler;
    
    private UUID rapportId;
    private HistoriqueRapport rapport;
    
    @PostConstruct
    public void init() {
        // Récupérer l'ID du rapport depuis le paramètre de requête
        String idParam = jakarta.faces.context.FacesContext.getCurrentInstance()
            .getExternalContext()
            .getRequestParameterMap()
            .get("id");
        
        if (idParam != null && !idParam.isEmpty()) {
            try {
                rapportId = UUID.fromString(idParam);
                chargerRapport();
            } catch (IllegalArgumentException e) {
                LOG.errorf(e, "ID de rapport invalide: %s", idParam);
                errorHandler.showWarning("Erreur", "ID de rapport invalide");
            }
        } else {
            // Si pas d'ID, utiliser le rapport sélectionné depuis RapportsBean (WOU/DRY)
            if (rapportsBean != null && rapportsBean.getRapportSelectionne() != null) {
                rapport = rapportsBean.getRapportSelectionne();
                rapportId = rapport.getId();
            } else {
                LOG.warn("Aucun rapport sélectionné et aucun ID fourni");
                errorHandler.showWarning("Attention", "Aucun rapport à afficher");
            }
        }
    }
    
    private void chargerRapport() {
        if (rapportsBean == null) {
            LOG.error("RapportsBean non injecté");
            return;
        }
        
        // Chercher le rapport dans la liste de RapportsBean (WOU/DRY - réutilise les données)
        if (rapportsBean.getHistoriqueRapports() != null) {
            rapport = rapportsBean.getHistoriqueRapports().stream()
                .filter(r -> r.getId().equals(rapportId))
                .findFirst()
                .orElse(null);
        }
        
        if (rapport == null) {
            LOG.warnf("Rapport non trouvé avec l'ID: %s", rapportId);
            errorHandler.showWarning("Erreur", "Rapport non trouvé");
        }
    }
    
    public String retourner() {
        // Utilisation de navigation outcome au lieu de chemin direct (WOU/DRY)
        return OUTCOME_RAPPORTS + "?faces-redirect=true";
    }
    
    public void telechargerRapport() {
        if (rapport != null) {
            try {
                // Vérifier que le rapport est disponible
                if (!"GENERE".equals(rapport.getStatut())) {
                    errorHandler.showWarning("Attention",
                        "Le rapport n'est pas encore disponible au téléchargement.");
                    return;
                }

                LOG.infof("Téléchargement du rapport: %s (ID: %s)", 
                    rapport.getTypeLibelle(), rapport.getId());

                // Le téléchargement sera géré par le XHTML avec p:fileDownload ou un lien direct
                // vers le endpoint REST qui génère le fichier
                errorHandler.showInfo("Téléchargement",
                    "Le téléchargement du rapport '" + rapport.getTypeLibelle() + "' va commencer.");

            } catch (Exception e) {
                LOG.errorf(e, "Erreur lors du téléchargement du rapport");
                errorHandler.handleException(e, "lors du téléchargement d'un rapport", null);
            }
        }
    }
    
    public void regenererRapport() {
        if (rapport != null) {
            try {
                LOG.infof("Régénération du rapport: %s (ID: %s)", 
                    rapport.getTypeLibelle(), rapport.getId());

                // Mettre à jour le statut du rapport localement
                rapport.setStatut("EN_GENERATION");
                rapport.setDateGeneration(LocalDate.now());

                // Rafraîchir les données depuis RapportsBean (WOU/DRY)
                if (rapportsBean != null) {
                    rapportsBean.actualiser();
                    // Recharger le rapport mis à jour
                    chargerRapport();
                }

                errorHandler.showInfo("Régénération",
                    "Le rapport '" + rapport.getTypeLibelle() + "' est en cours de régénération. "
                    + "Vous serez notifié une fois la génération terminée.");

            } catch (Exception e) {
                LOG.errorf(e, "Erreur lors de la régénération du rapport");
                errorHandler.handleException(e, "lors de la régénération d'un rapport", null);
            }
        }
    }
    
    // Getters et Setters
    public UUID getRapportId() { return rapportId; }
    public void setRapportId(UUID rapportId) { this.rapportId = rapportId; }
    
    public HistoriqueRapport getRapport() { return rapport; }
    public void setRapport(HistoriqueRapport rapport) { this.rapport = rapport; }
    
    // Méthodes utilitaires pour l'affichage
    public String getDateGenerationFormatee() {
        if (rapport != null && rapport.getDateGeneration() != null) {
            return rapport.getDateGeneration().format(DATE_FORMATTER);
        }
        return "";
    }
    
    public boolean isRapportDisponible() {
        return rapport != null && "GENERE".equals(rapport.getStatut());
    }
}

