using CashLineERP.Domain.Common;
using CashLineERP.SharedKernel.IslamicFinance;

namespace CashLineERP.Domain.IslamicFinance.Murabaha;

public sealed class IslamicFinanceProfitSchedule : Entity
{
    public long Id { get; private set; }
    public long MurabahaCaseId { get; private set; }
    public int InstallmentNumber { get; private set; }
    public DateOnly DueDate { get; private set; }
    public decimal PrincipalAmount { get; private set; }
    public decimal ProfitAmount { get; private set; }
    public decimal InstallmentAmount { get; private set; }
    public decimal OutstandingBalanceAmount { get; private set; }
    public string StatusCode { get; private set; } = IslamicFinanceWorkflowCatalog.Active;

    public IslamicFinanceProfitSchedule(
        long murabahaCaseId,
        int installmentNumber,
        DateOnly dueDate,
        decimal principalAmount,
        decimal profitAmount,
        decimal outstandingBalanceAmount,
        string statusCode = IslamicFinanceWorkflowCatalog.Active)
    {
        if (murabahaCaseId <= 0)
        {
            throw new InvalidOperationException("Islamic Finance profit schedule requires a valid Murabaha case identifier.");
        }

        if (installmentNumber <= 0)
        {
            throw new InvalidOperationException("Islamic Finance profit schedule installment number must be positive.");
        }

        if (principalAmount < 0m || profitAmount < 0m)
        {
            throw new InvalidOperationException("Islamic Finance profit schedule principal and profit amounts must be non-negative.");
        }

        if (principalAmount == 0m && profitAmount == 0m)
        {
            throw new InvalidOperationException("Islamic Finance profit schedule installment must carry a principal or profit amount.");
        }

        if (outstandingBalanceAmount < 0m)
        {
            throw new InvalidOperationException("Islamic Finance profit schedule outstanding balance cannot be negative.");
        }

        MurabahaCaseId = murabahaCaseId;
        InstallmentNumber = installmentNumber;
        DueDate = dueDate;
        PrincipalAmount = principalAmount;
        ProfitAmount = profitAmount;
        InstallmentAmount = principalAmount + profitAmount;
        OutstandingBalanceAmount = outstandingBalanceAmount;
        StatusCode = IslamicFinanceWorkflowCatalog.NormalizeStatusCode(statusCode);
    }

    private IslamicFinanceProfitSchedule()
    {
    }

    public void SuspendForRegeneration(long actorUserId)
    {
        if (string.Equals(StatusCode, IslamicFinanceWorkflowCatalog.Suspended, StringComparison.OrdinalIgnoreCase))
        {
            return;
        }

        StatusCode = IslamicFinanceWorkflowCatalog.Suspended;
        Touch(actorUserId);
    }
}
