package dev.lions.unionflow.client.view;

import dev.lions.unionflow.client.service.ExportClientService;
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.List;
import java.util.UUID;

/**
 * Bean JSF pour les exports en masse
 * 
 * @author UnionFlow Team
 * @version 1.0
 */
@Named("exportMasseBean")
@ViewScoped
public class ExportMasseBean implements Serializable {
    
    private static final long serialVersionUID = 1L;
    private static final Logger LOG = Logger.getLogger(ExportMasseBean.class);
    
    @Inject
    @RestClient
    private ExportClientService exportService;
    
    @Inject
    ErrorHandlerService errorHandler;
    
    @Inject
    RetryService retryService;
    
    // Paramètres d'export
    private String typeExport = "cotisations"; // cotisations, rapports
    private String formatExport = "CSV"; // CSV, PDF, EXCEL
    private String statutFiltre;
    private UUID organisationIdFiltre;
    
    // Export cotisations
    private List<UUID> cotisationsSelectionnees = new ArrayList<>();
    private String typeCotisation;
    
    // Export rapports
    private int anneeRapport;
    private int moisRapport;
    
    @PostConstruct
    public void init() {
        anneeRapport = java.time.LocalDate.now().getYear();
        moisRapport = java.time.LocalDate.now().getMonthValue();
    }
    
    public void exporterCotisationsCSV() {
        try {
            byte[] csvData;
            if (cotisationsSelectionnees != null && !cotisationsSelectionnees.isEmpty()) {
                csvData = retryService.executeWithRetrySupplier(
                    () -> exportService.exporterCotisationsSelectionneesCSV(cotisationsSelectionnees),
                    "export CSV de cotisations sélectionnées"
                );
            } else {
                csvData = retryService.executeWithRetrySupplier(
                    () -> exportService.exporterCotisationsCSV(statutFiltre, typeCotisation, organisationIdFiltre),
                    "export CSV de cotisations"
                );
            }
            
            // Télécharger le fichier
            telechargerFichier(csvData, "cotisations.csv", "text/csv");
            errorHandler.showSuccess("Succès", "Export CSV généré avec succès");
        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors de l'export CSV");
            errorHandler.handleException(e, "lors de l'export CSV de cotisations", null);
        }
    }
    
    public void genererRecu() {
        if (cotisationsSelectionnees != null && !cotisationsSelectionnees.isEmpty()) {
            try {
                byte[] recuData = retryService.executeWithRetrySupplier(
                    () -> exportService.genererRecu(cotisationsSelectionnees.get(0)),
                    "génération d'un reçu"
                );
                telechargerFichier(recuData, "recu.txt", "text/plain");
                errorHandler.showSuccess("Succès", "Reçu généré avec succès");
            } catch (Exception e) {
                LOG.errorf(e, "Erreur lors de la génération du reçu");
                errorHandler.handleException(e, "lors de la génération d'un reçu", null);
            }
        }
    }
    
    public void genererRecusGroupes() {
        if (cotisationsSelectionnees != null && !cotisationsSelectionnees.isEmpty()) {
            try {
                byte[] recusData = retryService.executeWithRetrySupplier(
                    () -> exportService.genererRecusGroupes(cotisationsSelectionnees),
                    "génération de reçus groupés"
                );
                telechargerFichier(recusData, "recus-groupes.txt", "text/plain");
                errorHandler.showSuccess("Succès", "Reçus groupés générés avec succès");
            } catch (Exception e) {
                LOG.errorf(e, "Erreur lors de la génération des reçus groupés");
                errorHandler.handleException(e, "lors de la génération de reçus groupés", null);
            }
        }
    }
    
    public void genererRapportMensuel() {
        try {
            byte[] rapportData = retryService.executeWithRetrySupplier(
                () -> exportService.genererRapportMensuel(anneeRapport, moisRapport, organisationIdFiltre),
                "génération d'un rapport mensuel"
            );
            String nomFichier = String.format("rapport-%d-%02d.txt", anneeRapport, moisRapport);
            telechargerFichier(rapportData, nomFichier, "text/plain");
            errorHandler.showSuccess("Succès", "Rapport mensuel généré avec succès");
        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors de la génération du rapport mensuel");
            errorHandler.handleException(e, "lors de la génération d'un rapport mensuel", null);
        }
    }
    
    private void telechargerFichier(byte[] data, String nomFichier, String contentType) {
        try {
            jakarta.faces.context.FacesContext facesContext = jakarta.faces.context.FacesContext.getCurrentInstance();
            jakarta.servlet.http.HttpServletResponse response = 
                (jakarta.servlet.http.HttpServletResponse) facesContext.getExternalContext().getResponse();
            
            response.setContentType(contentType);
            response.setHeader("Content-Disposition", "attachment; filename=\"" + nomFichier + "\"");
            response.setContentLength(data.length);
            
            java.io.OutputStream outputStream = response.getOutputStream();
            outputStream.write(data);
            outputStream.flush();
            outputStream.close();
            
            facesContext.responseComplete();
        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors du téléchargement du fichier");
        }
    }
    
    // Getters et Setters
    public String getTypeExport() { return typeExport; }
    public void setTypeExport(String typeExport) { this.typeExport = typeExport; }
    
    public String getFormatExport() { return formatExport; }
    public void setFormatExport(String formatExport) { this.formatExport = formatExport; }
    
    public String getStatutFiltre() { return statutFiltre; }
    public void setStatutFiltre(String statutFiltre) { this.statutFiltre = statutFiltre; }
    
    public UUID getAssociationIdFiltre() { return organisationIdFiltre; }
    public void setAssociationIdFiltre(UUID organisationIdFiltre) { this.organisationIdFiltre = organisationIdFiltre; }
    
    public List<UUID> getCotisationsSelectionnees() { return cotisationsSelectionnees; }
    public void setCotisationsSelectionnees(List<UUID> cotisationsSelectionnees) { this.cotisationsSelectionnees = cotisationsSelectionnees; }
    
    public String getTypeCotisation() { return typeCotisation; }
    public void setTypeCotisation(String typeCotisation) { this.typeCotisation = typeCotisation; }
    
    public int getAnneeRapport() { return anneeRapport; }
    public void setAnneeRapport(int anneeRapport) { this.anneeRapport = anneeRapport; }
    
    public int getMoisRapport() { return moisRapport; }
    public void setMoisRapport(int moisRapport) { this.moisRapport = moisRapport; }
    
}

