package br.gov.sigefp.treasury.domain;

import br.gov.sigefp.common.domain.BaseEntity;
import jakarta.persistence.*;
import lombok.*;
import lombok.experimental.SuperBuilder;

import java.math.BigDecimal;
import java.time.LocalDate;

/**
 * Entidade que representa um Plano de Tesouraria (PT).
 * Define tetos de pagamento para períodos específicos (mensais).
 * Conforme Master Plan - Module 2: Preventive Control.
 */
@Entity
@Table(name = "treasury_plan", indexes = {
        @Index(name = "idx_treasury_plan_fiscal_year", columnList = "fiscal_year,reference_month"),
        @Index(name = "idx_treasury_plan_status", columnList = "status"),
        @Index(name = "idx_treasury_plan_period", columnList = "start_date,end_date")
})
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder
public class TreasuryPlan extends BaseEntity {

    @Column(name = "fiscal_year", nullable = false)
    private Integer fiscalYear; // Ex: 2025

    @Column(name = "reference_month", nullable = false)
    private Integer referenceMonth; // 1-12

    @Column(nullable = false, length = 20)
    @Builder.Default
    private String status = "DRAFT"; // DRAFT, APPROVED, CLOSED

    @Column(name = "approved_ceiling", nullable = false, precision = 19, scale = 2)
    private BigDecimal approvedCeiling; // Teto aprovado para o período

    @Column(name = "executed_amount", nullable = false, precision = 19, scale = 2)
    @Builder.Default
    private BigDecimal executedAmount = BigDecimal.ZERO; // Atualizado via listeners

    @Column(name = "start_date", nullable = false)
    private LocalDate startDate; // Data de início do período

    @Column(name = "end_date", nullable = false)
    private LocalDate endDate; // Data de fim do período

    @Column(name = "approved_by")
    private java.util.UUID approvedBy; // Usuário que aprovou o plano

    @Column(name = "approved_at")
    private java.time.LocalDateTime approvedAt;

    /**
     * Calcula o valor disponível (teto - executado).
     */
    public BigDecimal getAvailableAmount() {
        return approvedCeiling.subtract(executedAmount);
    }

    /**
     * Verifica se uma data está dentro do período do plano.
     */
    public boolean isDateWithinPeriod(LocalDate date) {
        return !date.isBefore(startDate) && !date.isAfter(endDate);
    }

    /**
     * Verifica se o plano está aprovado e ativo.
     */
    public boolean isActive() {
        return "APPROVED".equals(status);
    }
}

