using CashLineERP.Application.IslamicFinance.Facilities;
using CashLineERP.Application.IslamicFinance.PartnerLenders;
using CashLineERP.Application.IslamicFinance.ProductProfiles;
using CashLineERP.Contracts.IslamicFinance;
using CashLineERP.Infrastructure.Persistence.Repositories.IslamicFinance;

namespace CashLineERP.Api.Tests;

public sealed class IslamicFinanceProductAndFacilityServiceQaTests
{
    [Fact]
    public void Product_Profile_Can_Be_Created_Submitted_Approved_Activated_And_Filtered()
    {
        using var dbContext = QaDbContextFactory.CreateContext();

        var service = new IslamicFinanceProductService(new IslamicFinanceProductRepository(dbContext));

        var created = service.CreateProductProfile(new CreateIslamicFinanceProductProfileRequest
        {
            ProductType = "MURABAHA",
            ProductCode = "MUR-SVC-001",
            ProductName = "Murabaha Service Test",
            RequiresShariahReview = true,
            AllowsPartnerFunding = true,
            AllowsCashLineFunding = false
        });

        Assert.Equal("DRAFT", created.StatusCode);

        service.SubmitProductProfile(created.Id, 3);
        service.ApproveProductProfile(created.Id, 4);
        var activated = service.ActivateProductProfile(created.Id, 4);

        Assert.True(activated.IsActive);
        Assert.Equal("ACTIVE", activated.StatusCode);

        var murabahaProfiles = service.GetProductProfiles(activeOnly: true, productType: "MURABAHA");
        Assert.Single(murabahaProfiles);
    }

    [Fact]
    public void Facility_Can_Be_Created_Submitted_Approved_Activated_And_Read_Back()
    {
        using var dbContext = QaDbContextFactory.CreateContext();

        var partnerService = new IslamicFinancePartnerService(new IslamicFinancePartnerRepository(dbContext));
        var productService = new IslamicFinanceProductService(new IslamicFinanceProductRepository(dbContext));
        var facilityService = new IslamicFinanceFacilityService(new IslamicFinanceFacilityRepository(dbContext));

        var partner = CreateActivePartner(partnerService);
        var product = CreateActiveProduct(productService);

        var created = facilityService.CreateFacility(new CreateIslamicFinanceFacilityRequest
        {
            PartnerLenderId = partner.Id,
            CustomerPartyId = 1,
            ProductProfileId = product.Id,
            FacilityNumber = "FAC-SVC-001",
            CurrencyCode = "EGP",
            ApprovedLimitAmount = 500000m,
            UtilizedAmount = 50000m
        });

        Assert.Equal("DRAFT", created.StatusCode);
        Assert.Equal(450000m, created.AvailableAmount);

        facilityService.SubmitFacility(created.Id, 3);
        facilityService.ApproveFacility(created.Id, 4);
        var activated = facilityService.ActivateFacility(created.Id, 4);

        Assert.True(activated.IsActive);
        Assert.Equal("ACTIVE", activated.StatusCode);

        var detail = facilityService.GetFacility(created.Id);
        Assert.NotNull(detail);
        Assert.Equal(created.Id, detail!.Id);

        var filtered = facilityService.GetFacilities(activeOnly: true, customerPartyId: 1, partnerLenderId: partner.Id);
        Assert.Single(filtered);
    }

    private static IslamicFinancePartnerLenderResponse CreateActivePartner(IslamicFinancePartnerService service)
    {
        var created = service.CreatePartnerLender(new CreateIslamicFinancePartnerLenderRequest
        {
            PartnerLenderPartyId = 1,
            DefaultCurrencyCode = "EGP",
            SupportsMurabaha = true,
            SupportsReceivablesFinance = false,
            SupportsTawarruq = false
        });

        service.SubmitPartnerLender(created.Id, 3);
        service.ApprovePartnerLender(created.Id, 4);
        return service.ActivatePartnerLender(created.Id, 4);
    }

    private static IslamicFinanceProductProfileResponse CreateActiveProduct(IslamicFinanceProductService service)
    {
        var created = service.CreateProductProfile(new CreateIslamicFinanceProductProfileRequest
        {
            ProductType = "MURABAHA",
            ProductCode = "MUR-FAC-001",
            ProductName = "Murabaha Facility Product",
            RequiresShariahReview = true,
            AllowsPartnerFunding = true,
            AllowsCashLineFunding = false
        });

        service.SubmitProductProfile(created.Id, 3);
        service.ApproveProductProfile(created.Id, 4);
        return service.ActivateProductProfile(created.Id, 4);
    }
}
