package com.astalange.core.entity;

import jakarta.persistence.*;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

@Entity
@Table(name = "licence")
public class Licence {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne(optional = false)
    @JoinColumn(name = "adherent_id", nullable = false)
    private Adherent adherent;

    @ManyToOne(optional = false)
    @JoinColumn(name = "categorie_id", nullable = false)
    private Categorie categorie;

    @ManyToOne(optional = false, fetch = FetchType.LAZY)
    @JoinColumn(name = "saison_id", nullable = false)
    private Saison saison;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "equipe_id")
    private Equipe equipe;

    @Column(nullable = false, length = 50)
    private String etat;

    @Column(name = "numero_licence", length = 50)
    private String numeroLicence;

    @Column(name = "type_demande", length = 50)
    private String typeDemande;

    @Column(name = "type_licence", length = 50)
    private String typeLicence;

    @OneToMany(mappedBy = "licence", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Paiement> paiements = new ArrayList<>();

    @OneToMany(mappedBy = "licence", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Dotation> dotations = new ArrayList<>();

    // Logic for Global Total Price
    @Transient
    public BigDecimal getPrixTotal() {
        if (categorie == null) return BigDecimal.ZERO;
        
        BigDecimal prixTotal = (adherent != null && adherent.isResidentTalange()) 
                                ? categorie.getTarifBase() 
                                : categorie.getTarifExterieur();

        if (prixTotal == null) prixTotal = BigDecimal.ZERO;

        if (dotations != null) {
            for (Dotation dot : dotations) {
                if (dot.getChoisi() && dot.getEquipement() != null) {
                    BigDecimal price = categorie.getEquipementPrix(dot.getEquipement().getId());
                    if (price != null) {
                        prixTotal = prixTotal.add(price);
                    }
                }
            }
        }

        return prixTotal;
    }

    // Logic for Reste A Payer
    @Transient
    public BigDecimal getResteAPayer() {
        BigDecimal prixTotal = getPrixTotal();

        if (paiements == null || paiements.isEmpty()) {
            return prixTotal;
        }

        BigDecimal totalPaye = paiements.stream()
                .map(Paiement::getMontant)
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        BigDecimal reste = prixTotal.subtract(totalPaye);
        return reste.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : reste;
    }

    @Transient
    public BigDecimal getSommePayee() {
        if (paiements == null || paiements.isEmpty()) {
            return BigDecimal.ZERO;
        }
        return paiements.stream()
                .map(Paiement::getMontant)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
    }

    // Getters and Setters

    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }

    public Adherent getAdherent() { return adherent; }
    public void setAdherent(Adherent adherent) { this.adherent = adherent; }

    public Categorie getCategorie() { return categorie; }
    public void setCategorie(Categorie categorie) { this.categorie = categorie; }

    public Saison getSaison() { return saison; }
    public void setSaison(Saison saison) { this.saison = saison; }

    public Equipe getEquipe() { return equipe; }
    public void setEquipe(Equipe equipe) { this.equipe = equipe; }

    public String getEtat() { return etat; }
    public void setEtat(String etat) { this.etat = etat; }

    public String getNumeroLicence() { return numeroLicence; }
    public void setNumeroLicence(String numeroLicence) { this.numeroLicence = numeroLicence; }

    public String getTypeDemande() { return typeDemande; }
    public void setTypeDemande(String typeDemande) { this.typeDemande = typeDemande; }

    public String getTypeLicence() { return typeLicence; }
    public void setTypeLicence(String typeLicence) { this.typeLicence = typeLicence; }

    public List<Paiement> getPaiements() { return paiements; }
    public void setPaiements(List<Paiement> paiements) { this.paiements = paiements; }

    public List<Dotation> getDotations() { return dotations; }
    public void setDotations(List<Dotation> dotations) { this.dotations = dotations; }

    public void addPaiement(Paiement paiement) {
        paiements.add(paiement);
        paiement.setLicence(this);
    }
    
    public void removePaiement(Paiement paiement) {
        paiements.remove(paiement);
        paiement.setLicence(null);
    }

    public void addDotation(Dotation dotation) {
        dotations.add(dotation);
        dotation.setLicence(this);
    }

    public void removeDotation(Dotation dotation) {
        dotations.remove(dotation);
        dotation.setLicence(null);
    }
}
