using CashLineERP.Domain.IslamicFinance.Disbursements;
using CashLineERP.SharedKernel.IslamicFinance;

namespace CashLineERP.Api.Tests;

public sealed class IslamicFinanceMurabahaDisbursementDomainQaTests
{
    [Fact]
    public void Murabaha_Disbursement_Supports_Submit_Approve_Execute_And_Close_Lifecycle()
    {
        var disbursement = new IslamicFinanceMurabahaDisbursement(
            disbursementNumber: "IFD-000001",
            murabahaCaseId: 11,
            customerPartyId: 1,
            partnerLenderId: 2,
            supplierPartyId: 3,
            fundingSourceMode: IslamicFinanceFundingSourceMode.Partner,
            targetType: IslamicFinanceDisbursementTargetType.SupplierPayment,
            transactionCurrencyCode: "EGP",
            instructedAmount: 100000m,
            plannedExecutionDate: new DateOnly(2026, 4, 6));

        disbursement.Submit(actorUserId: 10, workflowInstanceId: 41);
        Assert.Equal(IslamicFinanceWorkflowCatalog.Submitted, disbursement.StatusCode);

        disbursement.Approve(actorUserId: 11);
        Assert.Equal(IslamicFinanceWorkflowCatalog.Approved, disbursement.StatusCode);

        var executedAtUtc = new DateTime(2026, 4, 6, 9, 0, 0, DateTimeKind.Utc);
        disbursement.Execute(actorUserId: 12, executionReferenceNumber: "PAY-00001", executedAtUtc: executedAtUtc);
        Assert.Equal(IslamicFinanceWorkflowCatalog.Active, disbursement.StatusCode);
        Assert.Equal(100000m, disbursement.ExecutedAmount);
        Assert.True(disbursement.Execution.IsExecuted);

        disbursement.Close(actorUserId: 12);
        Assert.Equal(IslamicFinanceWorkflowCatalog.Closed, disbursement.StatusCode);
        Assert.Equal(0m, disbursement.Amount.OutstandingAmount);
    }

    [Fact]
    public void Murabaha_Disbursement_Rejects_Self_Approval_And_NonPartner_Mode()
    {
        var disbursement = new IslamicFinanceMurabahaDisbursement(
            disbursementNumber: "IFD-000002",
            murabahaCaseId: 12,
            customerPartyId: 1,
            partnerLenderId: 2,
            supplierPartyId: 3,
            fundingSourceMode: IslamicFinanceFundingSourceMode.Partner,
            targetType: IslamicFinanceDisbursementTargetType.SupplierPayment,
            transactionCurrencyCode: "EGP",
            instructedAmount: 50000m,
            plannedExecutionDate: new DateOnly(2026, 4, 7));

        disbursement.Submit(actorUserId: 15);
        Assert.Throws<InvalidOperationException>(() => disbursement.Approve(actorUserId: 15));

        Assert.Throws<InvalidOperationException>(() => new IslamicFinanceMurabahaDisbursement(
            disbursementNumber: "IFD-000003",
            murabahaCaseId: 13,
            customerPartyId: 1,
            partnerLenderId: 2,
            supplierPartyId: 3,
            fundingSourceMode: IslamicFinanceFundingSourceMode.CashLine,
            targetType: IslamicFinanceDisbursementTargetType.SupplierPayment,
            transactionCurrencyCode: "EGP",
            instructedAmount: 50000m,
            plannedExecutionDate: new DateOnly(2026, 4, 7)));
    }
}
