package dev.lions.unionflow.client.view;

import dev.lions.unionflow.server.api.dto.solidarite.request.CreateDemandeAideRequest;
import dev.lions.unionflow.server.api.dto.solidarite.response.DemandeAideResponse;
import dev.lions.unionflow.server.api.dto.solidarite.LocalisationDTO;
import dev.lions.unionflow.server.api.enums.solidarite.PrioriteAide;
import dev.lions.unionflow.server.api.enums.solidarite.StatutAide;
import dev.lions.unionflow.server.api.enums.solidarite.TypeAide;
import dev.lions.unionflow.client.service.DemandeAideService;
import dev.lions.unionflow.client.service.ErrorHandlerService;
import dev.lions.unionflow.client.service.RetryService;
import jakarta.enterprise.context.SessionScoped;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import jakarta.annotation.PostConstruct;
import org.eclipse.microprofile.rest.client.inject.RestClient;
import org.jboss.logging.Logger;
import java.io.Serializable;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
import java.math.BigDecimal;

@Named("demandesAideBean")
@SessionScoped
public class DemandesAideBean implements Serializable {
    
    private static final long serialVersionUID = 1L;
    private static final Logger LOG = Logger.getLogger(DemandesAideBean.class);
    
    // Constantes de navigation outcomes (WOU/DRY - réutilisables)
    private static final String OUTCOME_DEMANDES_HISTORIQUE = "demandesHistoriquePage";
    
    @Inject
    @RestClient
    private DemandeAideService demandeAideService;

    @Inject
    ErrorHandlerService errorHandler;

    @Inject
    RetryService retryService;

    @Inject
    UserSession userSession;
    
    private List<DemandeAide> toutesLesDemandes;
    private List<DemandeAide> demandesFiltrees;
    private List<DemandeAide> demandesSelectionnees;
    private List<DemandeAide> demandesPrioritaires;
    private List<EtapeWorkflow> etapesWorkflow;
    private DemandeAide demandeSelectionnee;
    private NouvelleDemande nouvelleDemande;
    private Filtres filtres;
    private StatistiquesDemandes statistiques;

    // Propriétés pour le dialogue de détails
    private boolean dialogDetailsVisible;
    
    @PostConstruct
    public void init() {
        initializeFiltres();
        initializeStatistiques();
        initializeDemandes();
        initializeNouvelleDemande();
        initializeDemandesPrioritaires();
        initializeEtapesWorkflow();
        appliquerFiltres();
    }
    
    private void initializeFiltres() {
        filtres = new Filtres();
        demandesSelectionnees = new ArrayList<>();
    }
    
    private void initializeStatistiques() {
        statistiques = new StatistiquesDemandes();
        try {
            List<DemandeAideResponse> demandesDTO = retryService.executeWithRetrySupplier(
                () -> demandeAideService.listerToutes(0, 1000),
                "chargement des statistiques des demandes d'aide"
            );
            statistiques.setTotalDemandes(demandesDTO.size());
            long enAttente = demandesDTO.stream().filter(d -> StatutAide.EN_ATTENTE.equals(d.getStatut())).count();
            statistiques.setDemandesEnAttente((int) enAttente);
            long approuvees = demandesDTO.stream().filter(d -> StatutAide.APPROUVEE.equals(d.getStatut())).count();
            statistiques.setDemandesApprouvees((int) approuvees);
            long rejetees = demandesDTO.stream().filter(d -> StatutAide.REJETEE.equals(d.getStatut())).count();
            statistiques.setDemandesRejetees((int) rejetees);
            BigDecimal montantTotal = demandesDTO.stream()
                .filter(d -> d.getMontantApprouve() != null)
                .map(DemandeAideResponse::getMontantApprouve)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
            statistiques.setMontantTotalAide(montantTotal.toString() + " FCFA");
        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors du calcul des statistiques");
            errorHandler.handleException(e, "lors du calcul des statistiques", null);
            statistiques.setTotalDemandes(0);
            statistiques.setDemandesEnAttente(0);
            statistiques.setDemandesApprouvees(0);
            statistiques.setDemandesRejetees(0);
            statistiques.setMontantTotalAide("0 FCFA");
        }
    }
    
    private void initializeEtapesWorkflow() {
        etapesWorkflow = new ArrayList<>();

        try {
            // Charger toutes les demandes depuis le backend pour calculer les étapes
            List<DemandeAideResponse> demandesDTO = demandeAideService.listerToutes(0, 1000);

            // Calculer le nombre de demandes par statut depuis les données réelles
            long enAttenteCount = demandesDTO.stream().filter(d -> StatutAide.EN_ATTENTE.equals(d.getStatut())).count();
            long enEvaluationCount = demandesDTO.stream().filter(d -> StatutAide.EN_COURS_EVALUATION.equals(d.getStatut())).count();
            long enVisiteCount = 0; // StatutAide n'a probablement pas EN_VISITE
            long enDecisionCount = demandesDTO.stream().filter(d -> StatutAide.APPROUVEE.equals(d.getStatut())).count();
            long enVersementCount = demandesDTO.stream().filter(d -> StatutAide.EN_COURS_VERSEMENT.equals(d.getStatut())).count();
            long enSuiviCount = demandesDTO.stream().filter(d -> StatutAide.EN_SUIVI.equals(d.getStatut())).count();

            // Créer les étapes workflow avec les nombres réels
            EtapeWorkflow enAttente = new EtapeWorkflow();
            enAttente.setLibelle("En Attente");
            enAttente.setIcon("pi-clock");
            enAttente.setCouleur("orange-500");
            enAttente.setNombre((int) enAttenteCount);
            etapesWorkflow.add(enAttente);

            EtapeWorkflow evaluation = new EtapeWorkflow();
            evaluation.setLibelle("Évaluation");
            evaluation.setIcon("pi-search");
            evaluation.setCouleur("blue-500");
            evaluation.setNombre((int) enEvaluationCount);
            etapesWorkflow.add(evaluation);

            EtapeWorkflow visite = new EtapeWorkflow();
            visite.setLibelle("Visite");
            visite.setIcon("pi-home");
            visite.setCouleur("purple-500");
            visite.setNombre((int) enVisiteCount);
            etapesWorkflow.add(visite);

            EtapeWorkflow decision = new EtapeWorkflow();
            decision.setLibelle("Décision");
            decision.setIcon("pi-check-circle");
            decision.setCouleur("yellow-500");
            decision.setNombre((int) enDecisionCount);
            etapesWorkflow.add(decision);

            EtapeWorkflow versement = new EtapeWorkflow();
            versement.setLibelle("Versement");
            versement.setIcon("pi-dollar");
            versement.setCouleur("green-500");
            versement.setNombre((int) enVersementCount);
            etapesWorkflow.add(versement);

            EtapeWorkflow suivi = new EtapeWorkflow();
            suivi.setLibelle("Suivi");
            suivi.setIcon("pi-chart-line");
            suivi.setCouleur("indigo-500");
            suivi.setNombre((int) enSuiviCount);
            etapesWorkflow.add(suivi);

            LOG.info("Étapes workflow initialisées depuis les données backend");

        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors de l'initialisation des étapes workflow");
            errorHandler.handleException(e, "lors de l'initialisation des étapes workflow", null);
            etapesWorkflow = new ArrayList<>();
        }
    }
    
    private void initializeDemandes() {
        toutesLesDemandes = new ArrayList<>();
        
        try {
            List<DemandeAideResponse> demandesDTO = retryService.executeWithRetrySupplier(
                () -> demandeAideService.listerToutes(0, 1000),
                "chargement des demandes d'aide"
            );
            for (DemandeAideResponse dto : demandesDTO) {
                DemandeAide demande = convertToDemandeAide(dto);
                toutesLesDemandes.add(demande);
            }
        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors du chargement des demandes d'aide");
            errorHandler.handleException(e, "lors du chargement des demandes d'aide", null);
        }
    }
    
    private DemandeAide convertToDemandeAide(DemandeAideResponse dto) {
        DemandeAide demande = new DemandeAide();
        demande.setId(dto.getId());
        demande.setDemandeur(dto.getNomDemandeur()); // Corrigé: getNomDemandeur
        // Note: DemandeAideResponse n'a pas de champs telephone ni email directs
        demande.setTelephone(null);
        demande.setEmail(null);
        demande.setType(dto.getTypeAide() != null ? dto.getTypeAide().name() : null); // Corrigé: getTypeAide (enum)
        demande.setStatut(dto.getStatut() != null ? dto.getStatut().name() : null); // Corrigé: getStatut (enum)
        demande.setUrgence(dto.getPriorite() != null ? dto.getPriorite().name() : null); // Corrigé: getPriorite
        demande.setLocalisation(dto.getLocalisation() != null ? dto.getLocalisation().toString() : null); // Corrigé: LocalisationDTO → String
        demande.setMotif(dto.getMotifRejet() != null ? dto.getMotifRejet() : dto.getTitre()); // Corrigé: getMotifRejet
        demande.setDescription(dto.getDescription());
        demande.setMontantDemande(dto.getMontantDemande());
        demande.setMontantApprouve(dto.getMontantApprouve()); // Corrigé: getMontantApprouve
        demande.setDateDemande(dto.getDateSoumission() != null ? dto.getDateSoumission().toLocalDate() : null); // Corrigé: getDateSoumission
        demande.setDateLimite(dto.getDateLimite());
        demande.setResponsableTraitement(dto.getEvaluateurNom() != null ? dto.getEvaluateurNom() : dto.getApprovateurNom()); // Corrigé
        return demande;
    }
    
    private void initializeDemandesPrioritaires() {
        try {
            List<DemandeAideResponse> demandesDTO = retryService.executeWithRetrySupplier(
                () -> demandeAideService.rechercher("EN_ATTENTE", null, "CRITIQUE", 0, 6),
                "chargement des demandes prioritaires"
            );
            demandesPrioritaires = demandesDTO.stream()
                .map(this::convertToDemandeAide)
                .filter(d -> !d.getStatut().equals("TERMINEE") && !d.getStatut().equals("REJETEE"))
                .limit(6)
                .collect(Collectors.toList());
        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors du chargement des demandes prioritaires");
            errorHandler.handleException(e, "lors du chargement des demandes prioritaires", null);
            demandesPrioritaires = new ArrayList<>();
        }
    }
    
    private void initializeNouvelleDemande() {
        nouvelleDemande = new NouvelleDemande();
        nouvelleDemande.setUrgence("NORMALE");
        nouvelleDemande.setDateLimite(LocalDate.now().plusWeeks(2));
    }
    
    private void appliquerFiltres() {
        demandesFiltrees = toutesLesDemandes.stream()
                .filter(this::appliquerFiltre)
                .collect(Collectors.toList());
    }
    
    private boolean appliquerFiltre(DemandeAide demande) {
        if (filtres.getDemandeur() != null && !filtres.getDemandeur().trim().isEmpty()) {
            if (!demande.getDemandeur().toLowerCase().contains(filtres.getDemandeur().toLowerCase())) {
                return false;
            }
        }
        
        if (filtres.getType() != null && !filtres.getType().trim().isEmpty()) {
            if (!demande.getType().equals(filtres.getType())) {
                return false;
            }
        }
        
        if (filtres.getStatut() != null && !filtres.getStatut().trim().isEmpty()) {
            if (!demande.getStatut().equals(filtres.getStatut())) {
                return false;
            }
        }
        
        if (filtres.getUrgence() != null && !filtres.getUrgence().trim().isEmpty()) {
            if (!demande.getUrgence().equals(filtres.getUrgence())) {
                return false;
            }
        }
        
        if (filtres.getLocalisation() != null && !filtres.getLocalisation().trim().isEmpty()) {
            if (!demande.getLocalisation().toLowerCase().contains(filtres.getLocalisation().toLowerCase())) {
                return false;
            }
        }
        
        if (filtres.getDateDebut() != null) {
            if (demande.getDateDemande().isBefore(filtres.getDateDebut())) {
                return false;
            }
        }
        
        if (filtres.getDateFin() != null) {
            if (demande.getDateDemande().isAfter(filtres.getDateFin())) {
                return false;
            }
        }
        
        return true;
    }
    
    // Actions
    public void rechercher() {
        appliquerFiltres();
    }
    
    public void reinitialiserFiltres() {
        filtres = new Filtres();
        appliquerFiltres();
    }
    
    public void creerDemande() {
        // Validation des champs requis
        List<String> errors = new ArrayList<>();
        if (nouvelleDemande.getDemandeur() == null || nouvelleDemande.getDemandeur().trim().isEmpty()) {
            errors.add("Le nom du demandeur est requis");
        }
        if (nouvelleDemande.getTelephone() == null || nouvelleDemande.getTelephone().trim().isEmpty()) {
            errors.add("Le téléphone est requis");
        }
        if (nouvelleDemande.getType() == null || nouvelleDemande.getType().trim().isEmpty()) {
            errors.add("Le type d'aide est requis");
        }
        if (nouvelleDemande.getLocalisation() == null || nouvelleDemande.getLocalisation().trim().isEmpty()) {
            errors.add("La localisation est requise");
        }
        if (nouvelleDemande.getMontantDemande() == null || nouvelleDemande.getMontantDemande().compareTo(BigDecimal.ZERO) <= 0) {
            errors.add("Le montant demandé doit être supérieur à zéro");
        }
        if (nouvelleDemande.getMotif() == null || nouvelleDemande.getMotif().trim().isEmpty()) {
            errors.add("Le motif est requis");
        }
        if (nouvelleDemande.getDescription() == null || nouvelleDemande.getDescription().trim().isEmpty()) {
            errors.add("La description est requise");
        }
        
        if (!errors.isEmpty()) {
            errorHandler.handleValidationErrors(errors, "validation de la demande d'aide");
            return;
        }
        
        try {
            // Mapper LocalisationDTO depuis String (simplifié)
            LocalisationDTO localisationDTO = nouvelleDemande.getLocalisation() != null ?
                    LocalisationDTO.builder()
                        .adresseComplete(nouvelleDemande.getLocalisation())
                        .build() : null;

            // Créer la requête pour le backend
            CreateDemandeAideRequest request = CreateDemandeAideRequest.builder()
                    .typeAide(parseTypeAide(nouvelleDemande.getType()))
                    .titre(nouvelleDemande.getMotif() != null ? nouvelleDemande.getMotif() : "Demande d'aide")
                    .description(nouvelleDemande.getDescription())
                    .montantDemande(nouvelleDemande.getMontantDemande())
                    .devise("XOF")
                    .membreDemandeurId(userSession.getCurrentUser() != null ? userSession.getCurrentUser().getId() : null)
                    .associationId(userSession.getEntite() != null ? userSession.getEntite().getId() : null)
                    .priorite(parsePrioriteAide(nouvelleDemande.getUrgence()))
                    .localisation(localisationDTO)
                    .dateLimite(nouvelleDemande.getDateLimite())
                    .build();

            // Créer la demande via le backend avec retry
            DemandeAideResponse demandeCreee = retryService.executeWithRetrySupplier(
                () -> demandeAideService.creer(request),
                "création d'une demande d'aide"
            );
            
            // Recharger les données depuis le backend
            initializeDemandes();
            appliquerFiltres();
            initializeDemandesPrioritaires();
            initializeStatistiques();
            
            // Réinitialiser le formulaire
            initializeNouvelleDemande();
            
            LOG.infof("Nouvelle demande d'aide créée pour: %s (ID: %s)", 
                nouvelleDemande.getDemandeur(), demandeCreee.getId());
            errorHandler.showSuccess("Succès", "Demande d'aide créée avec succès");
        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors de la création de la demande d'aide");
            errorHandler.handleException(e, "lors de la création d'une demande d'aide", null);
        }
    }
    
    /**
     * Approuve une demande d'aide via le backend (DRY/WOU - réutilise DemandeAideService)
     */
    public void approuverDemande() {
        if (demandeSelectionnee == null || demandeSelectionnee.getId() == null) {
            errorHandler.showWarning("Attention", "Aucune demande sélectionnée");
            return;
        }
        
        try {
            // Appeler le backend pour approuver (DRY/WOU - utilise DemandeAideService)
            DemandeAideResponse demandeApprouvee = retryService.executeWithRetrySupplier(
                () -> demandeAideService.approuver(demandeSelectionnee.getId()),
                "approbation d'une demande d'aide"
            );
            
            // Mettre à jour l'état local
            demandeSelectionnee.setStatut("APPROUVEE");
            if (demandeApprouvee.getMontantApprouve() != null) {
                demandeSelectionnee.setMontantApprouve(demandeApprouvee.getMontantApprouve());
            } else if (demandeSelectionnee.getMontantApprouve() == null) {
                demandeSelectionnee.setMontantApprouve(demandeSelectionnee.getMontantDemande().multiply(new BigDecimal("0.8")));
            }
            
            // Recharger les données depuis le backend
            initializeDemandes();
            appliquerFiltres();
            initializeDemandesPrioritaires();
            initializeStatistiques();
            
            LOG.infof("Demande approuvée pour: %s", demandeSelectionnee.getDemandeur());
            errorHandler.showSuccess("Succès", "Demande approuvée avec succès");
        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors de l'approbation de la demande");
            errorHandler.handleException(e, "lors de l'approbation d'une demande d'aide", null);
        }
    }
    
    /**
     * Rejette une demande d'aide via le backend (DRY/WOU - réutilise DemandeAideService)
     */
    public void rejeterDemande() {
        if (demandeSelectionnee == null || demandeSelectionnee.getId() == null) {
            errorHandler.showWarning("Attention", "Aucune demande sélectionnée");
            return;
        }
        
        try {
            // Appeler le backend pour rejeter (DRY/WOU - utilise DemandeAideService)
            retryService.executeWithRetrySupplier(
                () -> {
                    demandeAideService.rejeter(demandeSelectionnee.getId());
                    return null;
                },
                "rejet d'une demande d'aide"
            );
            
            // Mettre à jour l'état local
            demandeSelectionnee.setStatut("REJETEE");
            
            // Recharger les données depuis le backend
            initializeDemandes();
            appliquerFiltres();
            initializeDemandesPrioritaires();
            initializeStatistiques();
            
            LOG.infof("Demande rejetée pour: %s", demandeSelectionnee.getDemandeur());
            errorHandler.showSuccess("Succès", "Demande rejetée");
        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors du rejet de la demande");
            errorHandler.handleException(e, "lors du rejet d'une demande d'aide", null);
        }
    }
    
    public String voirHistorique() {
        // Utilisation de navigation outcome au lieu de chemin direct (WOU/DRY)
        return OUTCOME_DEMANDES_HISTORIQUE + "?id=" + demandeSelectionnee.getId() + "&faces-redirect=true";
    }
    
    public void envoyerNotification() {
        LOG.infof("Notification envoyée pour la demande de: %s", demandeSelectionnee.getDemandeur());
    }
    
    // Méthodes pour la page de traitement (WOU/DRY - réutilisables)
    public void approuver(DemandeAide demande) {
        demandeSelectionnee = demande;
        approuverDemande();
    }
    
    public void rejeter(DemandeAide demande) {
        demandeSelectionnee = demande;
        rejeterDemande();
    }
    
    public void voirDetails(DemandeAide demande) {
        demandeSelectionnee = demande;
        dialogDetailsVisible = true;
        LOG.infof("Affichage des détails de la demande: %s", demande.getId());
    }

    public void fermerDialogDetails() {
        dialogDetailsVisible = false;
        demandeSelectionnee = null;
    }
    
    public void actualiser() {
        initializeDemandes();
        initializeStatistiques();
        appliquerFiltres();
        LOG.info("Données actualisées");
        errorHandler.showSuccess("Actualisation", "Données actualisées");
    }
    
    public void dupliquerDemande() {
        if (demandeSelectionnee != null) {
            DemandeAide copie = new DemandeAide();
            copie.setId(UUID.randomUUID());
            copie.setDemandeur(demandeSelectionnee.getDemandeur());
            copie.setTelephone(demandeSelectionnee.getTelephone());
            copie.setEmail(demandeSelectionnee.getEmail());
            copie.setType(demandeSelectionnee.getType());
            copie.setLocalisation(demandeSelectionnee.getLocalisation());
            copie.setMontantDemande(demandeSelectionnee.getMontantDemande());
            copie.setUrgence(demandeSelectionnee.getUrgence());
            copie.setMotif(demandeSelectionnee.getMotif() + " (Copie)");
            copie.setDescription(demandeSelectionnee.getDescription());
            copie.setStatut("EN_ATTENTE");
            copie.setDateDemande(LocalDate.now());
            
            toutesLesDemandes.add(copie);
            appliquerFiltres();
            LOG.infof("Demande dupliquée pour: %s", copie.getDemandeur());
        }
    }
    
    public void exporterDemandes() {
        LOG.infof("Export de %d demandes d'aide", demandesFiltrees.size());
    }
    
    // Méthodes pour les graphiques (WOU/DRY) - Retirées car PrimeFaces ne supporte plus les charts
    // Utiliser une bibliothèque JavaScript externe (Chart.js, ApexCharts, etc.) dans le XHTML
    public Object getChartModelType() {
        // Les graphiques sont gérés directement dans le XHTML avec des bibliothèques JavaScript
        // Retourne les données pour un éventuel graphique client-side
        return null;
    }

    public Object getChartModelStatut() {
        // Les graphiques sont gérés directement dans le XHTML avec des bibliothèques JavaScript
        // Retourne les données pour un éventuel graphique client-side
        return null;
    }
    
    // Getters et Setters
    public List<DemandeAide> getToutesLesDemandes() { return toutesLesDemandes; }
    public void setToutesLesDemandes(List<DemandeAide> toutesLesDemandes) { this.toutesLesDemandes = toutesLesDemandes; }
    
    public List<DemandeAide> getDemandesFiltrees() { return demandesFiltrees; }
    public void setDemandesFiltrees(List<DemandeAide> demandesFiltrees) { this.demandesFiltrees = demandesFiltrees; }
    
    public List<DemandeAide> getDemandesSelectionnees() { return demandesSelectionnees; }
    public void setDemandesSelectionnees(List<DemandeAide> demandesSelectionnees) { this.demandesSelectionnees = demandesSelectionnees; }
    
    public List<DemandeAide> getDemandesPrioritaires() { return demandesPrioritaires; }
    public void setDemandesPrioritaires(List<DemandeAide> demandesPrioritaires) { this.demandesPrioritaires = demandesPrioritaires; }
    
    public List<EtapeWorkflow> getEtapesWorkflow() { return etapesWorkflow; }
    public void setEtapesWorkflow(List<EtapeWorkflow> etapesWorkflow) { this.etapesWorkflow = etapesWorkflow; }
    
    public DemandeAide getDemandeSelectionnee() { return demandeSelectionnee; }
    public void setDemandeSelectionnee(DemandeAide demandeSelectionnee) { this.demandeSelectionnee = demandeSelectionnee; }
    
    public NouvelleDemande getNouvelleDemande() { return nouvelleDemande; }
    public void setNouvelleDemande(NouvelleDemande nouvelleDemande) { this.nouvelleDemande = nouvelleDemande; }
    
    public Filtres getFiltres() { return filtres; }
    public void setFiltres(Filtres filtres) { this.filtres = filtres; }
    
    public StatistiquesDemandes getStatistiques() { return statistiques; }
    public void setStatistiques(StatistiquesDemandes statistiques) { this.statistiques = statistiques; }

    public boolean isDialogDetailsVisible() { return dialogDetailsVisible; }
    public void setDialogDetailsVisible(boolean dialogDetailsVisible) { this.dialogDetailsVisible = dialogDetailsVisible; }
    
    // Classes internes
    public static class DemandeAide {
        private UUID id;
        private String demandeur;
        private String telephone;
        private String email;
        private String type;
        private String statut;
        private String urgence;
        private String localisation;
        private String motif;
        private String description;
        private BigDecimal montantDemande;
        private BigDecimal montantAccorde;
        private LocalDate dateDemande;
        private LocalDate dateLimite;
        private String responsableTraitement;
        
        // Getters et setters
        public UUID getId() { return id; }
        public void setId(UUID id) { this.id = id; }
        
        public String getDemandeur() { return demandeur; }
        public void setDemandeur(String demandeur) { this.demandeur = demandeur; }
        
        public String getTelephone() { return telephone; }
        public void setTelephone(String telephone) { this.telephone = telephone; }
        
        public String getEmail() { return email; }
        public void setEmail(String email) { this.email = email; }
        
        public String getType() { return type; }
        public void setType(String type) { this.type = type; }
        
        public String getStatut() { return statut; }
        public void setStatut(String statut) { this.statut = statut; }
        
        public String getUrgence() { return urgence; }
        public void setUrgence(String urgence) { this.urgence = urgence; }
        
        public String getLocalisation() { return localisation; }
        public void setLocalisation(String localisation) { this.localisation = localisation; }
        
        public String getMotif() { return motif; }
        public void setMotif(String motif) { this.motif = motif; }
        
        public String getDescription() { return description; }
        public void setDescription(String description) { this.description = description; }
        
        public BigDecimal getMontantDemande() { return montantDemande; }
        public void setMontantDemande(BigDecimal montantDemande) { this.montantDemande = montantDemande; }
        
        public BigDecimal getMontantApprouve() { return montantAccorde; }
        public void setMontantApprouve(BigDecimal montantAccorde) { this.montantAccorde = montantAccorde; }
        
        public LocalDate getDateDemande() { return dateDemande; }
        public void setDateDemande(LocalDate dateDemande) { this.dateDemande = dateDemande; }
        
        public LocalDate getDateLimite() { return dateLimite; }
        public void setDateLimite(LocalDate dateLimite) { this.dateLimite = dateLimite; }
        
        public String getResponsableTraitement() { return responsableTraitement; }
        public void setResponsableTraitement(String responsableTraitement) { this.responsableTraitement = responsableTraitement; }
        
        // Propriétés dérivées
        public String getTypeLibelle() {
            return switch (type) {
                case "AIDE_MEDICALE" -> "Aide Médicale";
                case "AIDE_ALIMENTAIRE" -> "Aide Alimentaire";
                case "AIDE_EDUCATIVE" -> "Aide Éducative";
                case "AIDE_LOGEMENT" -> "Aide Logement";
                case "AIDE_URGENCE" -> "Aide d'Urgence";
                default -> type;
            };
        }
        
        public String getTypeSeverity() {
            return switch (type) {
                case "AIDE_MEDICALE" -> "danger";
                case "AIDE_ALIMENTAIRE" -> "warning";
                case "AIDE_EDUCATIVE" -> "info";
                case "AIDE_LOGEMENT" -> "secondary";
                case "AIDE_URGENCE" -> "primary";
                default -> "primary";
            };
        }
        
        public String getTypeIcon() {
            return switch (type) {
                case "AIDE_MEDICALE" -> "pi-heart";
                case "AIDE_ALIMENTAIRE" -> "pi-shopping-cart";
                case "AIDE_EDUCATIVE" -> "pi-book";
                case "AIDE_LOGEMENT" -> "pi-home";
                case "AIDE_URGENCE" -> "pi-exclamation-triangle";
                default -> "pi-question";
            };
        }
        
        public String getStatutLibelle() {
            return switch (statut) {
                case "EN_ATTENTE" -> "En Attente";
                case "EN_EVALUATION" -> "En Évaluation";
                case "APPROUVEE" -> "Approuvée";
                case "REJETEE" -> "Rejetée";
                case "EN_COURS" -> "En Cours";
                case "TERMINEE" -> "Terminée";
                default -> statut;
            };
        }
        
        public String getStatutSeverity() {
            return switch (statut) {
                case "EN_ATTENTE" -> "warning";
                case "EN_EVALUATION" -> "info";
                case "APPROUVEE" -> "success";
                case "REJETEE" -> "danger";
                case "EN_COURS" -> "primary";
                case "TERMINEE" -> "secondary";
                default -> "secondary";
            };
        }
        
        public String getStatutIcon() {
            return switch (statut) {
                case "EN_ATTENTE" -> "pi-clock";
                case "EN_EVALUATION" -> "pi-search";
                case "APPROUVEE" -> "pi-check";
                case "REJETEE" -> "pi-times";
                case "EN_COURS" -> "pi-play";
                case "TERMINEE" -> "pi-check-circle";
                default -> "pi-circle";
            };
        }
        
        public String getUrgenceSeverity() {
            return switch (urgence) {
                case "FAIBLE" -> "secondary";
                case "NORMALE" -> "info";
                case "ELEVEE" -> "warning";
                case "CRITIQUE" -> "danger";
                default -> "primary";
            };
        }
        
        public String getDateDemandeFormatee() {
            if (dateDemande == null) return "";
            return dateDemande.format(DateTimeFormatter.ofPattern("dd/MM/yyyy"));
        }
        
        public String getMontantDemandeFormatte() {
            if (montantDemande == null) return "";
            return String.format("%,.0f FCFA", montantDemande);
        }
        
        public String getMontantApprouveFormatte() {
            if (montantAccorde == null) return "";
            return String.format("%,.0f FCFA", montantAccorde);
        }
        
        public long getJoursDepuisDemande() {
            if (dateDemande == null) return 0;
            return ChronoUnit.DAYS.between(dateDemande, LocalDate.now());
        }
    }
    
    // Helper methods pour parser les enums depuis Strings
    private TypeAide parseTypeAide(String type) {
        if (type == null) return TypeAide.AIDE_FINANCIERE_URGENTE;
        try {
            return TypeAide.valueOf(type.toUpperCase());
        } catch (Exception e) {
            return TypeAide.AIDE_FINANCIERE_URGENTE;
        }
    }

    private PrioriteAide parsePrioriteAide(String urgence) {
        if (urgence == null) return PrioriteAide.NORMALE;
        try {
            return PrioriteAide.valueOf(urgence.toUpperCase());
        } catch (Exception e) {
            return PrioriteAide.NORMALE;
        }
    }

    public static class NouvelleDemande {
        private String demandeur;
        private String telephone;
        private String email;
        private String type;
        private String localisation;
        private BigDecimal montantDemande;
        private String urgence;
        private LocalDate dateLimite;
        private String motif;
        private String description;
        
        // Getters et setters
        public String getDemandeur() { return demandeur; }
        public void setDemandeur(String demandeur) { this.demandeur = demandeur; }
        
        public String getTelephone() { return telephone; }
        public void setTelephone(String telephone) { this.telephone = telephone; }
        
        public String getEmail() { return email; }
        public void setEmail(String email) { this.email = email; }
        
        public String getType() { return type; }
        public void setType(String type) { this.type = type; }
        
        public String getLocalisation() { return localisation; }
        public void setLocalisation(String localisation) { this.localisation = localisation; }
        
        public BigDecimal getMontantDemande() { return montantDemande; }
        public void setMontantDemande(BigDecimal montantDemande) { this.montantDemande = montantDemande; }
        
        public String getUrgence() { return urgence; }
        public void setUrgence(String urgence) { this.urgence = urgence; }
        
        public LocalDate getDateLimite() { return dateLimite; }
        public void setDateLimite(LocalDate dateLimite) { this.dateLimite = dateLimite; }
        
        public String getMotif() { return motif; }
        public void setMotif(String motif) { this.motif = motif; }
        
        public String getDescription() { return description; }
        public void setDescription(String description) { this.description = description; }
    }
    
    public static class Filtres {
        private String demandeur;
        private String type;
        private String statut;
        private String urgence;
        private String localisation;
        private LocalDate dateDebut;
        private LocalDate dateFin;
        
        // Getters et setters
        public String getDemandeur() { return demandeur; }
        public void setDemandeur(String demandeur) { this.demandeur = demandeur; }
        
        public String getType() { return type; }
        public void setType(String type) { this.type = type; }
        
        public String getStatut() { return statut; }
        public void setStatut(String statut) { this.statut = statut; }
        
        public String getUrgence() { return urgence; }
        public void setUrgence(String urgence) { this.urgence = urgence; }
        
        public String getLocalisation() { return localisation; }
        public void setLocalisation(String localisation) { this.localisation = localisation; }
        
        public LocalDate getDateDebut() { return dateDebut; }
        public void setDateDebut(LocalDate dateDebut) { this.dateDebut = dateDebut; }
        
        public LocalDate getDateFin() { return dateFin; }
        public void setDateFin(LocalDate dateFin) { this.dateFin = dateFin; }
    }
    
    public static class StatistiquesDemandes {
        private int totalDemandes;
        private int demandesEnAttente;
        private int demandesApprouvees;
        private int demandesRejetees;
        private String montantTotalAide;
        
        // Getters et setters
        public int getTotalDemandes() { return totalDemandes; }
        public void setTotalDemandes(int totalDemandes) { this.totalDemandes = totalDemandes; }
        
        public int getDemandesEnAttente() { return demandesEnAttente; }
        public void setDemandesEnAttente(int demandesEnAttente) { this.demandesEnAttente = demandesEnAttente; }
        
        public int getDemandesApprouvees() { return demandesApprouvees; }
        public void setDemandesApprouvees(int demandesApprouvees) { this.demandesApprouvees = demandesApprouvees; }
        
        public int getDemandesRejetees() { return demandesRejetees; }
        public void setDemandesRejetees(int demandesRejetees) { this.demandesRejetees = demandesRejetees; }
        
        public String getMontantTotalAide() { return montantTotalAide; }
        public void setMontantTotalAide(String montantTotalAide) { this.montantTotalAide = montantTotalAide; }
    }
    
    public static class EtapeWorkflow {
        private String libelle;
        private String icon;
        private String couleur;
        private int nombre;
        
        // Getters et setters
        public String getLibelle() { return libelle; }
        public void setLibelle(String libelle) { this.libelle = libelle; }
        
        public String getIcon() { return icon; }
        public void setIcon(String icon) { this.icon = icon; }
        
        public String getCouleur() { return couleur; }
        public void setCouleur(String couleur) { this.couleur = couleur; }
        
        public int getNombre() { return nombre; }
        public void setNombre(int nombre) { this.nombre = nombre; }
    }
}
