package dev.lions.unionflow.server.entity;

import jakarta.persistence.*;
import jakarta.validation.constraints.*;
import java.time.LocalDateTime;
import java.util.UUID;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

/**
 * Entité Action d'Approbateur
 *
 * Représente l'action (approve/reject) d'un approbateur sur une demande d'approbation.
 *
 * @author UnionFlow Team
 * @version 1.0
 * @since 2026-03-13
 */
@Entity
@Table(name = "approver_actions", indexes = {
    @Index(name = "idx_approver_action_approval", columnList = "approval_id"),
    @Index(name = "idx_approver_action_approver", columnList = "approver_id"),
    @Index(name = "idx_approver_action_decision", columnList = "decision"),
    @Index(name = "idx_approver_action_decided_at", columnList = "decided_at")
})
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@EqualsAndHashCode(callSuper = true)
public class ApproverAction extends BaseEntity {

    /** Approbation parente */
    @NotNull
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "approval_id", nullable = false)
    private TransactionApproval approval;

    /** ID de l'approbateur (membre) */
    @NotNull
    @Column(name = "approver_id", nullable = false)
    private UUID approverId;

    /** Nom complet de l'approbateur (cache) */
    @NotBlank
    @Column(name = "approver_name", nullable = false, length = 200)
    private String approverName;

    /** Rôle de l'approbateur au moment de l'action */
    @NotBlank
    @Column(name = "approver_role", nullable = false, length = 50)
    private String approverRole;

    /** Décision (PENDING, APPROVED, REJECTED) */
    @NotBlank
    @Pattern(regexp = "^(PENDING|APPROVED|REJECTED)$")
    @Builder.Default
    @Column(name = "decision", nullable = false, length = 10)
    private String decision = "PENDING";

    /** Commentaire optionnel */
    @Size(max = 1000)
    @Column(name = "comment", length = 1000)
    private String comment;

    /** Date de la décision */
    @Column(name = "decided_at")
    private LocalDateTime decidedAt;

    @PrePersist
    protected void onCreate() {
        super.onCreate();
        if (decision == null) {
            decision = "PENDING";
        }
    }

    /** Méthode métier pour approuver avec commentaire */
    public void approve(String comment) {
        this.decision = "APPROVED";
        this.comment = comment;
        this.decidedAt = LocalDateTime.now();
    }

    /** Méthode métier pour rejeter avec raison */
    public void reject(String reason) {
        this.decision = "REJECTED";
        this.comment = reason;
        this.decidedAt = LocalDateTime.now();
    }
}
