package dev.lions.unionflow.server.entity;

import dev.lions.unionflow.server.entity.listener.AuditEntityListener;
import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
import jakarta.persistence.Column;
import jakarta.persistence.EntityListeners;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.MappedSuperclass;
import jakarta.persistence.PrePersist;
import jakarta.persistence.PreUpdate;
import jakarta.persistence.Version;
import java.time.LocalDateTime;
import java.util.UUID;
import lombok.Data;
import lombok.EqualsAndHashCode;

/**
 * Classe de base pour toutes les entités UnionFlow.
 *
 * <p>
 * Étend PanacheEntityBase pour bénéficier du pattern Active Record et résoudre
 * les warnings Hibernate.
 * Fournit les champs communs d'audit et le versioning optimistic.
 *
 * @author UnionFlow Team
 * @version 4.0
 */
@MappedSuperclass
@EntityListeners(AuditEntityListener.class)
@Data
@EqualsAndHashCode(callSuper = false)
public abstract class BaseEntity extends PanacheEntityBase {

    /** Identifiant unique auto-généré. */
    @Id
    @GeneratedValue(strategy = GenerationType.UUID)
    @Column(name = "id", updatable = false, nullable = false)
    private UUID id;

    /**
     * Date de création.
     */
    @Column(name = "date_creation", nullable = false, updatable = false)
    private LocalDateTime dateCreation;

    /**
     * Date de dernière modification.
     */
    @Column(name = "date_modification")
    private LocalDateTime dateModification;

    /**
     * Email de l'utilisateur ayant créé l'entité.
     */
    @Column(name = "cree_par", length = 255)
    private String creePar;

    /**
     * Email du dernier utilisateur ayant modifié l'entité.
     */
    @Column(name = "modifie_par", length = 255)
    private String modifiePar;

    /** Version pour l'optimistic locking JPA. */
    @Version
    @Column(name = "version")
    private Long version;

    /**
     * État actif/inactif pour le soft-delete.
     */
    @Column(name = "actif", nullable = false)
    private Boolean actif;

    @PrePersist
    protected void onCreate() {
        if (this.dateCreation == null) {
            this.dateCreation = LocalDateTime.now();
        }
        if (this.actif == null) {
            this.actif = true;
        }
    }

    @PreUpdate
    protected void onUpdate() {
        this.dateModification = LocalDateTime.now();
    }

    /**
     * Marque l'entité comme modifiée par un utilisateur donné.
     *
     * @param utilisateur email de l'utilisateur
     */
    public void marquerCommeModifie(String utilisateur) {
        this.dateModification = LocalDateTime.now();
        this.modifiePar = utilisateur;
    }
}
