package dev.lions.unionflow.server.entity;

import jakarta.persistence.*;
import jakarta.validation.constraints.*;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.UUID;
import lombok.*;

/**
 * Liaison polymorphique entre un versement et son objet cible.
 *
 * <p>Remplace les 4 tables dupliquées (paiements_cotisations, paiements_adhesions,
 * paiements_evenements, paiements_aides) par une table unique utilisant le pattern
 * {@code (typeObjetCible, objetCibleId)}.
 *
 * <p>Table DB : {@code paiements_objets} (nom hérité, conservé pour compatibilité Flyway).
 *
 * @author UnionFlow Team
 * @version 4.0
 * @since 2026-04-13
 */
@Entity
@Table(name = "paiements_objets", indexes = {
    @Index(name = "idx_po_paiement", columnList = "paiement_id"),
    @Index(name = "idx_po_objet",    columnList = "type_objet_cible, objet_cible_id"),
    @Index(name = "idx_po_type",     columnList = "type_objet_cible")
}, uniqueConstraints = {
    @UniqueConstraint(name = "uk_paiement_objet", columnNames = {
        "paiement_id", "type_objet_cible", "objet_cible_id"
    })
})
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@EqualsAndHashCode(callSuper = true)
public class VersementObjet extends BaseEntity {

    /** Versement parent. */
    @NotNull
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "paiement_id", nullable = false)
    private Versement versement;

    /**
     * Type de l'objet cible (domaine {@code OBJET_PAIEMENT}).
     * Valeurs : COTISATION | ADHESION | EVENEMENT | AIDE.
     */
    @NotBlank
    @Size(max = 50)
    @Column(name = "type_objet_cible", nullable = false, length = 50)
    private String typeObjetCible;

    /** UUID de l'objet cible (cotisation, adhésion, inscription, aide). */
    @NotNull
    @Column(name = "objet_cible_id", nullable = false)
    private UUID objetCibleId;

    /** Montant affecté à cet objet cible. */
    @NotNull
    @DecimalMin(value = "0.0", message = "Le montant doit être positif")
    @Digits(integer = 12, fraction = 2)
    @Column(name = "montant_applique", nullable = false, precision = 14, scale = 2)
    private BigDecimal montantApplique;

    @Column(name = "date_application")
    private LocalDateTime dateApplication;

    @Size(max = 500)
    @Column(name = "commentaire", length = 500)
    private String commentaire;

    @Override
    @PrePersist
    protected void onCreate() {
        super.onCreate();
        if (dateApplication == null) {
            dateApplication = LocalDateTime.now();
        }
    }
}
