using CashLineERP.Domain.Common;

namespace CashLineERP.Domain.Finance;

public sealed class CashAccount : Entity
{
    public long Id { get; private set; }

    public string AccountCode { get; private set; } = string.Empty;

    public string AccountName { get; private set; } = string.Empty;

    public string AccountType { get; private set; } = string.Empty;

    public string CurrencyCode { get; private set; } = "EGP";

    public long? BranchId { get; private set; }

    public bool IsActive { get; private set; } = true;

    public decimal OpeningBalanceAmount { get; private set; }

    public decimal CurrentBalanceAmount { get; private set; }

    public CashAccount(
        string accountCode,
        string accountName,
        string accountType,
        string currencyCode,
        long? branchId,
        decimal openingBalanceAmount)
    {
        if (openingBalanceAmount < 0m)
        {
            throw new InvalidOperationException("Cash account opening balance cannot be negative.");
        }

        AccountCode = accountCode;
        AccountName = accountName;
        AccountType = accountType;
        CurrencyCode = currencyCode;
        BranchId = branchId;
        OpeningBalanceAmount = openingBalanceAmount;
        CurrentBalanceAmount = openingBalanceAmount;
    }

    private CashAccount()
    {
    }

    public void ApplyOutgoingTransfer(decimal amountAmount, long actorUserId)
    {
        if (!IsActive)
        {
            throw new InvalidOperationException("Inactive cash account cannot be used in treasury transfer posting.");
        }

        if (amountAmount <= 0m)
        {
            throw new InvalidOperationException("Treasury transfer amount must be greater than zero.");
        }

        if (CurrentBalanceAmount < amountAmount)
        {
            throw new InvalidOperationException($"Cash account {AccountCode} does not have sufficient balance for treasury transfer posting.");
        }

        CurrentBalanceAmount -= amountAmount;
        Touch(actorUserId);
    }

    public void ApplyIncomingTransfer(decimal amountAmount, long actorUserId)
    {
        if (!IsActive)
        {
            throw new InvalidOperationException("Inactive cash account cannot be used in treasury transfer posting.");
        }

        if (amountAmount <= 0m)
        {
            throw new InvalidOperationException("Treasury transfer amount must be greater than zero.");
        }

        CurrentBalanceAmount += amountAmount;
        Touch(actorUserId);
    }
}
