package dev.lions.unionflow.client.view;

import dev.lions.unionflow.client.constants.ViewPaths;
import dev.lions.unionflow.server.api.dto.cotisation.response.CotisationResponse;
import dev.lions.unionflow.client.api.dto.MembreDashboardResponse;
import dev.lions.unionflow.client.service.CotisationService;
import dev.lions.unionflow.client.service.MembreDashboardRestClient;
import dev.lions.unionflow.client.service.ErrorHandlerService;
import dev.lions.unionflow.client.service.RetryService;
import org.eclipse.microprofile.rest.client.inject.RestClient;
import org.primefaces.PrimeFaces;
import jakarta.annotation.PostConstruct;
import jakarta.faces.view.ViewScoped;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import org.jboss.logging.Logger;

import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Bean de gestion du dashboard personnel pour les membres actifs (MEMBRE_ACTIF).
 */
@Named("dashboardMembreBean")
@ViewScoped
public class DashboardMembreBean implements Serializable {

    private static final long serialVersionUID = 1L;
    private static final Logger LOG = Logger.getLogger(DashboardMembreBean.class);

    @Inject
    ErrorHandlerService errorHandler;

    @Inject
    RetryService retryService;

    @Inject
    @RestClient
    MembreDashboardRestClient dashboardClient;

    @Inject
    @RestClient
    CotisationService cotisationService;

    // Informations personnelles
    private String prenomMembre;
    private String nomMembre;
    private LocalDate dateInscription;

    // KPI cotisations
    private String mesCotisationsPaiement = "0";
    private String statutCotisations = "Non disponible";
    private Integer tauxCotisationsPerso = null;

    // KPI épargne
    private String monSoldeEpargne = "0";
    private String evolutionEpargne = "+0%";
    private String evolutionEpargneNombre = "0";
    private Integer objectifEpargne = null;

    // KPI événements
    private Integer mesEvenementsInscrits = 0;
    private Integer evenementsAVenir = 0;
    private Integer tauxParticipationPerso = null;

    // KPI aides
    private Integer mesDemandesAide = 0;
    private Integer aidesEnCours = 0;
    private Integer tauxAidesApprouvees = null;

    // Listes réelles
    private List<CotisationResponse> mesCotisations = new ArrayList<>();
    private List<CotisationResponse> mesCotisationsEnAttente = new ArrayList<>();

    // Dialog paiement (même pattern que CotisationsGestionBean)
    private CotisationResponse cotisationAPayer;
    private BigDecimal montantPaiement;
    private String modePaiement = "ESPECES";
    private LocalDate datePaiement;
    private String referencePaiement;

    @PostConstruct
    public void init() {
        LOG.info("Initialisation du dashboard personnel membre");
        chargerDonneesPersonnelles();
    }

    private void chargerDonneesPersonnelles() {
        try {
            MembreDashboardResponse data = dashboardClient.getMonDashboard();
            if (data != null) {
                this.prenomMembre = data.getPrenom();
                this.nomMembre = data.getNom();
                this.dateInscription = data.getDateInscription();
                this.mesCotisationsPaiement = formatMontant(data.getMesCotisationsPaiement());
                this.statutCotisations = data.getStatutCotisations() != null ? data.getStatutCotisations() : "Non disponible";
                this.tauxCotisationsPerso = data.getTauxCotisationsPerso();
                this.monSoldeEpargne = formatMontant(data.getMonSoldeEpargne());
                this.evolutionEpargneNombre = formatMontant(data.getEvolutionEpargneNombre());
                this.evolutionEpargne = data.getEvolutionEpargne() != null ? data.getEvolutionEpargne() : "+0%";
                this.objectifEpargne = data.getObjectifEpargne();
                this.mesEvenementsInscrits = data.getMesEvenementsInscrits() != null ? data.getMesEvenementsInscrits() : 0;
                this.evenementsAVenir = data.getEvenementsAVenir() != null ? data.getEvenementsAVenir() : 0;
                this.tauxParticipationPerso = data.getTauxParticipationPerso();
                this.mesDemandesAide = data.getMesDemandesAide() != null ? data.getMesDemandesAide() : 0;
                this.aidesEnCours = data.getAidesEnCours() != null ? data.getAidesEnCours() : 0;
                this.tauxAidesApprouvees = data.getTauxAidesApprouvees();
            }
        } catch (Exception e) {
            LOG.error("Erreur chargement KPI dashboard", e);
            errorHandler.handleException(e, "lors du chargement de votre dashboard", null);
        }

        try {
            List<CotisationResponse> cotisations = cotisationService.getMesCotisations(0, 20);
            this.mesCotisations = cotisations != null ? cotisations : new ArrayList<>();
        } catch (Exception e) {
            LOG.error("Erreur chargement historique cotisations", e);
            this.mesCotisations = new ArrayList<>();
        }

        try {
            List<CotisationResponse> enAttente = cotisationService.getMesCotisationsEnAttente();
            this.mesCotisationsEnAttente = enAttente != null ? enAttente : new ArrayList<>();
        } catch (Exception e) {
            LOG.error("Erreur chargement cotisations en attente", e);
            this.mesCotisationsEnAttente = new ArrayList<>();
        }
    }

    // ═══════════════════════════════════════════════════════════════════════
    // Paiement (dialog — même pattern que CotisationsGestionBean)
    // ═══════════════════════════════════════════════════════════════════════

    public void ouvrirDialogPaiement(CotisationResponse cotisation) {
        if (cotisation == null) return;
        this.cotisationAPayer = cotisation;
        this.montantPaiement = cotisation.getMontantDu();
        this.modePaiement = "ESPECES";
        this.datePaiement = LocalDate.now();
        this.referencePaiement = "";
        PrimeFaces.current().executeScript("PF('dlgPaiementMembre').show();");
    }

    public void confirmerPaiement() {
        if (cotisationAPayer == null) return;
        try {
            Map<String, Object> data = new HashMap<>();
            data.put("montantPaye", montantPaiement != null ? montantPaiement : cotisationAPayer.getMontantDu());
            data.put("datePaiement", datePaiement != null ? datePaiement.toString() : LocalDate.now().toString());
            data.put("modePaiement", modePaiement != null ? modePaiement : "ESPECES");
            data.put("reference", referencePaiement != null ? referencePaiement : "");

            retryService.executeWithRetrySupplier(
                () -> cotisationService.payer(cotisationAPayer.getId(), data),
                "paiement cotisation");

            chargerDonneesPersonnelles();
            PrimeFaces.current().executeScript("PF('dlgPaiementMembre').hide();");
            errorHandler.showSuccess("Succès", "Paiement enregistré avec succès");
            cotisationAPayer = null;
        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors du paiement");
            errorHandler.handleException(e, "lors du paiement", null);
        }
    }

    // ═══════════════════════════════════════════════════════════════════════
    // Navigation
    // ═══════════════════════════════════════════════════════════════════════

    public String allerAuxCotisations() {
        return ViewPaths.MEMBRE_PAIEMENT_COTISATIONS + ".xhtml" + ViewPaths.REDIRECT_SUFFIX;
    }

    public String inscrireEvenement() {
        return ViewPaths.EVENEMENT_CALENDRIER + ".xhtml" + ViewPaths.REDIRECT_SUFFIX;
    }

    public String demanderAide() {
        return ViewPaths.AIDE_DEMANDE + ".xhtml" + ViewPaths.REDIRECT_SUFFIX;
    }

    public String allerAMonProfil() {
        return ViewPaths.MEMBRE_PROFIL + ".xhtml" + ViewPaths.REDIRECT_SUFFIX;
    }

    public String allerAuxEvenements() {
        return ViewPaths.EVENEMENT_CALENDRIER + ".xhtml" + ViewPaths.REDIRECT_SUFFIX;
    }

    // ═══════════════════════════════════════════════════════════════════════
    // Helpers
    // ═══════════════════════════════════════════════════════════════════════

    private String formatMontant(BigDecimal montant) {
        if (montant == null) return "0";
        return String.format("%,d", montant.longValue()).replace(',', ' ');
    }

    // ═══════════════════════════════════════════════════════════════════════
    // Getters / Setters
    // ═══════════════════════════════════════════════════════════════════════

    public String getPrenomMembre() { return prenomMembre; }
    public String getNomMembre() { return nomMembre; }
    public LocalDate getDateInscription() { return dateInscription; }
    public String getMesCotisationsPaiement() { return mesCotisationsPaiement; }
    public String getStatutCotisations() { return statutCotisations; }
    public Integer getTauxCotisationsPerso() { return tauxCotisationsPerso; }
    public String getMonSoldeEpargne() { return monSoldeEpargne; }
    public String getEvolutionEpargne() { return evolutionEpargne; }
    public String getEvolutionEpargneNombre() { return evolutionEpargneNombre; }
    public Integer getObjectifEpargne() { return objectifEpargne; }
    public Integer getMesEvenementsInscrits() { return mesEvenementsInscrits; }
    public Integer getEvenementsAVenir() { return evenementsAVenir; }
    public Integer getTauxParticipationPerso() { return tauxParticipationPerso; }
    public Integer getMesDemandesAide() { return mesDemandesAide; }
    public Integer getAidesEnCours() { return aidesEnCours; }
    public Integer getTauxAidesApprouvees() { return tauxAidesApprouvees; }
    public List<CotisationResponse> getMesCotisations() { return mesCotisations; }
    public List<CotisationResponse> getMesCotisationsEnAttente() { return mesCotisationsEnAttente; }

    public CotisationResponse getCotisationAPayer() { return cotisationAPayer; }
    public void setCotisationAPayer(CotisationResponse c) { this.cotisationAPayer = c; }
    public BigDecimal getMontantPaiement() { return montantPaiement; }
    public void setMontantPaiement(BigDecimal v) { this.montantPaiement = v; }
    public String getModePaiement() { return modePaiement; }
    public void setModePaiement(String v) { this.modePaiement = v; }
    public LocalDate getDatePaiement() { return datePaiement; }
    public void setDatePaiement(LocalDate v) { this.datePaiement = v; }
    public String getReferencePaiement() { return referencePaiement; }
    public void setReferencePaiement(String v) { this.referencePaiement = v; }
}
