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.util.ArrayList;
import java.util.List;

/**
 * Entidade que representa uma conta de caixa ou bancária do Tesouro.
 * Gerencia disponibilidades e saldos.
 */
@Entity
@Table(name = "cash_account", indexes = {
        @Index(name = "idx_cash_account_code", columnList = "code"),
        @Index(name = "idx_cash_account_type", columnList = "type"),
        @Index(name = "idx_cash_account_active", columnList = "is_active")
})
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder
public class CashAccount extends BaseEntity {

    @Column(nullable = false, unique = true, length = 50)
    private String code; // Ex: "CAIXA-001", "BANCO-BCEAO-001"

    @Column(nullable = false, length = 200)
    private String name; // Ex: "Caixa Principal", "Conta BCEAO - Tesouro"

    @Column(nullable = false, length = 20)
    private String type; // CASH, BANK_ACCOUNT

    @Column(name = "bank_id")
    private java.util.UUID bankId; // Se tipo = BANK_ACCOUNT

    @Column(name = "parent_id")
    private java.util.UUID parentId; // Conta Pai (Hierarquia CUT)

    @Column(name = "category", length = 20)
    private String category; // TRANSIT, CENTRAL_CUT, SUB_ACCOUNT

    @Column(name = "account_number", length = 50)
    private String accountNumber;

    @Column(name = "branch_code", length = 20)
    private String branchCode;

    @Column(nullable = false, length = 3)
    @Builder.Default
    private String currency = "XOF";

    @Column(name = "org_unit_id", nullable = true)
    private java.util.UUID orgUnitId; // Vínculo com Unidade Orgânica (Ministério/Direção)

    @Column(name = "is_active", nullable = false)
    @Builder.Default
    private Boolean isActive = true;

    @Column(name = "current_balance", nullable = false, precision = 19, scale = 2)
    @Builder.Default
    private BigDecimal currentBalance = BigDecimal.ZERO;

    @Column(name = "available_balance", nullable = false, precision = 19, scale = 2)
    @Builder.Default
    private BigDecimal availableBalance = BigDecimal.ZERO; // Saldo disponível (após compromissos)

    @OneToMany(mappedBy = "cashAccount", cascade = CascadeType.ALL, orphanRemoval = true)
    @Builder.Default
    private List<TreasuryEntry> treasuryEntries = new ArrayList<>();

    @OneToMany(mappedBy = "cashAccount", cascade = CascadeType.ALL, orphanRemoval = true)
    @Builder.Default
    private List<CashFlow> cashFlows = new ArrayList<>();
}
