package dev.lions.unionflow.server.api.dto.finance.response;

import dev.lions.unionflow.server.api.dto.base.BaseResponse;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.UUID;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

/**
 * Réponse contenant les données d'une adhésion.
 *
 * @author UnionFlow Team
 * @version 1.0
 */
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class AdhesionResponse extends BaseResponse {

    private String numeroReference;
    private UUID membreId;
    private String numeroMembre;
    private String nomMembre;
    private String emailMembre;
    private UUID organisationId;
    private String nomOrganisation;
    private LocalDate dateDemande;
    private BigDecimal fraisAdhesion;
    private BigDecimal montantPaye;
    private String codeDevise;
    private String statut;
    private LocalDate dateApprobation;
    private LocalDateTime datePaiement;
    private String methodePaiement;
    private String referencePaiement;
    private String motifRejet;
    private String observations;
    private String approuvePar;
    private LocalDate dateValidation;

    // Méthodes utilitaires héritées de l'ancien DTO
    public boolean isPayeeIntegralement() {
        return montantPaye != null && fraisAdhesion != null && montantPaye.compareTo(fraisAdhesion) >= 0;
    }

    public boolean isEnAttentePaiement() {
        return "APPROUVEE".equals(statut) && !isPayeeIntegralement();
    }

    public BigDecimal getMontantRestant() {
        if (fraisAdhesion == null)
            return BigDecimal.ZERO;
        if (montantPaye == null)
            return fraisAdhesion;
        BigDecimal restant = fraisAdhesion.subtract(montantPaye);
        return restant.compareTo(BigDecimal.ZERO) > 0 ? restant : BigDecimal.ZERO;
    }

    public int getPourcentagePaiement() {
        if (fraisAdhesion == null || fraisAdhesion.compareTo(BigDecimal.ZERO) == 0)
            return 0;
        if (montantPaye == null)
            return 0;
        return montantPaye.multiply(BigDecimal.valueOf(100)).divide(fraisAdhesion, 0, java.math.RoundingMode.HALF_UP)
                .intValue();
    }

    public long getJoursDepuisDemande() {
        if (dateDemande == null)
            return 0;
        return ChronoUnit.DAYS.between(dateDemande, LocalDate.now());
    }

    public String getStatutLibelle() {
        if (statut == null)
            return "Non défini";
        return switch (statut) {
            case "EN_ATTENTE" -> "En attente";
            case "APPROUVEE" -> "Approuvée";
            case "REJETEE" -> "Rejetée";
            case "ANNULEE" -> "Annulée";
            case "EN_PAIEMENT" -> "En paiement";
            case "PAYEE" -> "Payée";
            default -> statut;
        };
    }

    public String getStatutSeverity() {
        if (statut == null)
            return "secondary";
        return switch (statut) {
            case "APPROUVEE", "PAYEE" -> "success";
            case "EN_ATTENTE", "EN_PAIEMENT" -> "warning";
            case "REJETEE" -> "danger";
            case "ANNULEE" -> "secondary";
            default -> "secondary";
        };
    }

    public String getStatutIcon() {
        if (statut == null)
            return "pi-circle";
        return switch (statut) {
            case "APPROUVEE", "PAYEE" -> "pi-check";
            case "EN_ATTENTE" -> "pi-clock";
            case "EN_PAIEMENT" -> "pi-credit-card";
            case "REJETEE" -> "pi-times";
            case "ANNULEE" -> "pi-ban";
            default -> "pi-circle";
        };
    }

    public String getMethodePaiementLibelle() {
        if (methodePaiement == null)
            return "Non défini";
        return switch (methodePaiement) {
            case "ESPECES" -> "Espèces";
            case "VIREMENT" -> "Virement bancaire";
            case "CHEQUE" -> "Chèque";
            case "WAVE_MONEY" -> "Wave Money";
            case "ORANGE_MONEY" -> "Orange Money";
            case "FREE_MONEY" -> "Free Money";
            case "CARTE_BANCAIRE" -> "Carte bancaire";
            default -> methodePaiement;
        };
    }

    public String getDateDemandeFormatee() {
        if (dateDemande == null)
            return "";
        return dateDemande.format(DateTimeFormatter.ofPattern("dd/MM/yyyy"));
    }

    public String getDateApprobationFormatee() {
        if (dateApprobation == null)
            return "";
        return dateApprobation.format(DateTimeFormatter.ofPattern("dd/MM/yyyy"));
    }

    public String getDatePaiementFormatee() {
        if (datePaiement == null)
            return "";
        return datePaiement.format(DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm"));
    }

    public String getFraisAdhesionFormatte() {
        if (fraisAdhesion == null)
            return "0 FCFA";
        return String.format("%,.0f FCFA", fraisAdhesion.doubleValue());
    }

    public String getMontantPayeFormatte() {
        if (montantPaye == null)
            return "0 FCFA";
        return String.format("%,.0f FCFA", montantPaye.doubleValue());
    }

    public String getMontantRestantFormatte() {
        return String.format("%,.0f FCFA", getMontantRestant().doubleValue());
    }
}
