using System.Net;
using System.Net.Http.Json;
using CashLineERP.Contracts.Customers;
using CashLineERP.Contracts.External;
using CashLineERP.Contracts.Finance;
using CashLineERP.Contracts.IslamicFinance;
using CashLineERP.Contracts.Parties;
using CashLineERP.Contracts.Sales;
using CashLineERP.Contracts.Suppliers;

namespace CashLineERP.Api.Tests;

public sealed class ExternalPortalQaTests : IClassFixture<ApiTestFactory>
{
    private readonly HttpClient _client;

    public ExternalPortalQaTests(ApiTestFactory factory)
    {
        _client = factory.CreateClient();
    }

    [Fact]
    public async Task External_Portal_Endpoints_Return_Quotations_Orders_Invoices_Payments_And_Statements()
    {
        await _client.AuthenticateAsFinanceMakerAsync();

        var createPaymentResponse = await _client.PostAsJsonAsync("/api/v1/finance/ap-payments", new CreateAccountsPayablePaymentRequest(
            SupplierId: 1,
            PaymentDate: new DateOnly(2026, 4, 8),
            PaymentMethod: "BANK_TRANSFER",
            CurrencyCode: "EGP",
            AmountAmount: 900m,
            ReferenceNumber: "HTTP-SUP-PORTAL-PAY-001",
            Notes: "External portal HTTP payment",
            Allocations:
            [
                new CreateAccountsPayablePaymentAllocationRequest(1, 900m, new DateOnly(2026, 4, 8))
            ]));
        Assert.True(createPaymentResponse.IsSuccessStatusCode, await createPaymentResponse.Content.ReadAsStringAsync());
        var createdPayment = await createPaymentResponse.Content.ReadFromJsonAsync<AccountsPayablePaymentResponse>();
        Assert.NotNull(createdPayment);

        var submitPaymentResponse = await _client.PostAsync($"/api/v1/finance/ap-payments/{createdPayment!.AccountsPayablePaymentId}/submit", null);
        Assert.True(submitPaymentResponse.IsSuccessStatusCode, await submitPaymentResponse.Content.ReadAsStringAsync());

        await _client.AuthenticateAsFinanceCheckerAsync();

        var approvePaymentResponse = await _client.PostAsync($"/api/v1/finance/ap-payments/{createdPayment.AccountsPayablePaymentId}/approve", null);
        Assert.True(approvePaymentResponse.IsSuccessStatusCode, await approvePaymentResponse.Content.ReadAsStringAsync());

        var postPaymentResponse = await _client.PostAsync($"/api/v1/finance/ap-payments/{createdPayment.AccountsPayablePaymentId}/post", null);
        Assert.True(postPaymentResponse.IsSuccessStatusCode, await postPaymentResponse.Content.ReadAsStringAsync());

        await _client.AuthenticateAsFinanceCheckerAsync();

        var generateSupplierStatementResponse = await _client.PostAsJsonAsync("/api/v1/finance/supplier-statements", new CreateSupplierStatementRequest(
            SupplierId: 1,
            DateFrom: new DateOnly(2026, 4, 1),
            DateTo: new DateOnly(2026, 4, 30),
            CurrencyCode: "EGP"));
        Assert.True(generateSupplierStatementResponse.IsSuccessStatusCode, await generateSupplierStatementResponse.Content.ReadAsStringAsync());
        var generatedSupplierStatement = await generateSupplierStatementResponse.Content.ReadFromJsonAsync<SupplierStatementResponse>();
        Assert.NotNull(generatedSupplierStatement);

        var supplierStatementDeliveryResponse = await _client.PostAsJsonAsync($"/api/v1/finance/supplier-statements/{generatedSupplierStatement!.SupplierStatementId}/delivery-logs", new RecordSupplierStatementDeliveryRequest(
            DeliveredAtUtc: DateTime.UtcNow,
            ChannelCode: "EMAIL",
            RecipientAddress: "supplier@example.com",
            DeliveryStatusCode: "DELIVERED",
            Notes: "External supplier statement delivery"));
        Assert.True(supplierStatementDeliveryResponse.IsSuccessStatusCode, await supplierStatementDeliveryResponse.Content.ReadAsStringAsync());

        await _client.AuthenticateAsSupplierAsync();

        var rfqsResponse = await _client.GetAsync("/api/v1/external/parties/1/rfq-invitations");
        Assert.Equal(HttpStatusCode.OK, rfqsResponse.StatusCode);
        var rfqs = await rfqsResponse.Content.ReadFromJsonAsync<List<ExternalRfqInvitationResponse>>();
        Assert.NotNull(rfqs);
        Assert.Contains(rfqs!, item => item.RfqNumber == "RFQ-000001");

        var rfqDetailResponse = await _client.GetAsync("/api/v1/external/parties/1/rfq-invitations/1");
        Assert.Equal(HttpStatusCode.OK, rfqDetailResponse.StatusCode);
        var rfqDetail = await rfqDetailResponse.Content.ReadFromJsonAsync<ExternalRfqInvitationDetailResponse>();
        Assert.NotNull(rfqDetail);
        Assert.NotEmpty(rfqDetail!.Lines);

        var respondToRfqResponse = await _client.PostAsJsonAsync(
            "/api/v1/external/parties/1/rfq-invitations/1/respond",
            new RespondExternalRfqInvitationRequest("ACCEPTED", null));
        Assert.Equal(HttpStatusCode.OK, respondToRfqResponse.StatusCode);
        var acceptedRfq = await respondToRfqResponse.Content.ReadFromJsonAsync<ExternalRfqInvitationDetailResponse>();
        Assert.NotNull(acceptedRfq);
        Assert.Equal("ACCEPTED", acceptedRfq!.InviteStatusCode);

        var createSupplierProfileResponse = await _client.PostAsJsonAsync("/api/v1/external/parties/1/supplier-profile", new CreateSupplierProfileRequest(
            1,
            null,
            "STRATEGIC_VENDOR",
            "EGP",
            "BANK_TRANSFER",
            30,
            7,
            2000m,
            "Banque Misr",
            "1234567890012345",
            "BMISEGCX",
            "External onboarding request"));
        Assert.Equal(HttpStatusCode.OK, createSupplierProfileResponse.StatusCode);
        var createdSupplierProfile = await createSupplierProfileResponse.Content.ReadFromJsonAsync<SupplierProfileResponse>();
        Assert.NotNull(createdSupplierProfile);
        Assert.Equal(1, createdSupplierProfile!.BusinessPartyId);

        var submitSupplierProfileResponse = await _client.PostAsync("/api/v1/external/parties/1/supplier-profile/submit", null);
        Assert.Equal(HttpStatusCode.OK, submitSupplierProfileResponse.StatusCode);
        var submittedSupplierProfile = await submitSupplierProfileResponse.Content.ReadFromJsonAsync<SupplierProfileResponse>();
        Assert.NotNull(submittedSupplierProfile);
        Assert.Equal("SUBMITTED", submittedSupplierProfile!.StatusCode);

        var supplierProfileResponse = await _client.GetAsync("/api/v1/external/parties/1/supplier-profile");
        Assert.Equal(HttpStatusCode.OK, supplierProfileResponse.StatusCode);
        var supplierProfile = await supplierProfileResponse.Content.ReadFromJsonAsync<SupplierProfileResponse>();
        Assert.NotNull(supplierProfile);
        Assert.Equal(createdSupplierProfile.SupplierProfileCode, supplierProfile!.SupplierProfileCode);

        var createQuotationResponse = await _client.PostAsJsonAsync("/api/v1/external/parties/1/quotations", new CreateExternalSupplierQuotationRequest(
            RequestForQuotationId: 1,
            QuoteDate: new DateOnly(2026, 4, 12),
            ValidUntilDate: new DateOnly(2026, 4, 20),
            CurrencyCode: "EGP",
            FxRate: 1m,
            Notes: "Created from supplier external HTTP QA",
            Lines: rfqDetail.Lines.Select(line => new CreateExternalSupplierQuotationLineRequest(
                RequestForQuotationLineId: line.RfqLineId,
                ItemId: line.ItemId,
                QuotedQuantity: line.RequestedQuantity,
                UnitOfMeasureCode: line.UnitOfMeasureCode,
                UnitPrice: line.TargetUnitPrice ?? 30m,
                DiscountPercent: 0m,
                DiscountAmount: 0m,
                TaxCode: line.TaxCode,
                LeadTimeDays: 5)).ToArray()));
        Assert.Equal(HttpStatusCode.OK, createQuotationResponse.StatusCode);
        var createdSupplierQuotation = await createQuotationResponse.Content.ReadFromJsonAsync<CashLineERP.Contracts.Procurement.SupplierQuotationResponse>();
        Assert.NotNull(createdSupplierQuotation);
        Assert.Equal(1, createdSupplierQuotation!.SupplierId);
        Assert.Equal(rfqDetail.Lines.Count, createdSupplierQuotation.Lines.Count);

        var submitSupplierQuotationResponse = await _client.PostAsync($"/api/v1/external/parties/1/quotations/{createdSupplierQuotation.SupplierQuotationId}/submit", null);
        Assert.Equal(HttpStatusCode.OK, submitSupplierQuotationResponse.StatusCode);
        var submittedSupplierQuotation = await submitSupplierQuotationResponse.Content.ReadFromJsonAsync<CashLineERP.Contracts.Procurement.SupplierQuotationResponse>();
        Assert.NotNull(submittedSupplierQuotation);
        Assert.Equal("SUBMITTED", submittedSupplierQuotation!.StatusCode);

        var quotationDetailResponse = await _client.GetAsync($"/api/v1/external/parties/1/quotations/{createdSupplierQuotation.SupplierQuotationId}");
        Assert.Equal(HttpStatusCode.OK, quotationDetailResponse.StatusCode);
        var quotationDetail = await quotationDetailResponse.Content.ReadFromJsonAsync<CashLineERP.Contracts.Procurement.SupplierQuotationResponse>();
        Assert.NotNull(quotationDetail);
        Assert.Equal(createdSupplierQuotation.SupplierQuotationId, quotationDetail!.SupplierQuotationId);

        var quotationsResponse = await _client.GetAsync("/api/v1/external/parties/1/quotations");
        Assert.Equal(HttpStatusCode.OK, quotationsResponse.StatusCode);
        var quotations = await quotationsResponse.Content.ReadFromJsonAsync<List<ExternalQuotationResponse>>();
        Assert.NotNull(quotations);
        Assert.Contains(quotations!, item => item.QuotationNumber == "QTN-000001");
        Assert.Contains(quotations!, item => item.QuotationNumber == createdSupplierQuotation.QuotationNumber);

        var supplierOrdersResponse = await _client.GetAsync("/api/v1/external/parties/1/orders");
        Assert.Equal(HttpStatusCode.OK, supplierOrdersResponse.StatusCode);
        var supplierOrders = await supplierOrdersResponse.Content.ReadFromJsonAsync<List<ExternalOrderResponse>>();
        Assert.NotNull(supplierOrders);
        Assert.Contains(supplierOrders!, item => item.OrderType == "PURCHASE_ORDER");

        var supplierPurchaseOrdersResponse = await _client.GetAsync("/api/v1/external/parties/1/purchase-orders");
        Assert.Equal(HttpStatusCode.OK, supplierPurchaseOrdersResponse.StatusCode);
        var supplierPurchaseOrders = await supplierPurchaseOrdersResponse.Content.ReadFromJsonAsync<List<ExternalPurchaseOrderResponse>>();
        Assert.NotNull(supplierPurchaseOrders);
        Assert.Contains(supplierPurchaseOrders!, item => item.PurchaseOrderNumber == "PO-000001");

        var raisePurchaseOrderIssueResponse = await _client.PostAsJsonAsync("/api/v1/external/parties/1/purchase-orders/1/raise-issue", new RaiseExternalPurchaseOrderIssueRequest(
            IssueCategoryCode: "DELIVERY",
            IssueNotes: "Supplier requested delivery-date clarification before confirming the purchase order."));
        Assert.Equal(HttpStatusCode.OK, raisePurchaseOrderIssueResponse.StatusCode);
        var raisedPurchaseOrderIssue = await raisePurchaseOrderIssueResponse.Content.ReadFromJsonAsync<ExternalPurchaseOrderResponse>();
        Assert.NotNull(raisedPurchaseOrderIssue);
        Assert.Equal("ISSUE_RAISED", raisedPurchaseOrderIssue!.AcknowledgmentStatusCode);

        var acknowledgePurchaseOrderResponse = await _client.PostAsJsonAsync("/api/v1/external/parties/1/purchase-orders/1/acknowledge", new AcknowledgeExternalPurchaseOrderRequest(
            AcknowledgmentStatusCode: "ACKNOWLEDGED",
            Notes: "Acknowledged from supplier portal HTTP QA"));
        Assert.Equal(HttpStatusCode.OK, acknowledgePurchaseOrderResponse.StatusCode);
        var acknowledgedPurchaseOrder = await acknowledgePurchaseOrderResponse.Content.ReadFromJsonAsync<ExternalPurchaseOrderResponse>();
        Assert.NotNull(acknowledgedPurchaseOrder);
        Assert.Equal("ACKNOWLEDGED", acknowledgedPurchaseOrder!.AcknowledgmentStatusCode);

        var supplierInvoicesResponse = await _client.GetAsync("/api/v1/external/parties/1/invoices");
        Assert.Equal(HttpStatusCode.OK, supplierInvoicesResponse.StatusCode);
        var supplierInvoices = await supplierInvoicesResponse.Content.ReadFromJsonAsync<List<ExternalInvoiceResponse>>();
        Assert.NotNull(supplierInvoices);
        Assert.Contains(supplierInvoices!, item => item.InvoiceNumber == "BILL-000001");

        var supplierPaymentsResponse = await _client.GetAsync("/api/v1/external/parties/1/payments");
        Assert.Equal(HttpStatusCode.OK, supplierPaymentsResponse.StatusCode);
        var supplierPayments = await supplierPaymentsResponse.Content.ReadFromJsonAsync<List<ExternalPaymentResponse>>();
        Assert.NotNull(supplierPayments);
        Assert.Contains(supplierPayments!, item => item.PaymentId == createdPayment.AccountsPayablePaymentId);

        var supplierSummaryResponse = await _client.GetAsync("/api/v1/external/parties/1/reports-statements/summary");
        Assert.Equal(HttpStatusCode.OK, supplierSummaryResponse.StatusCode);
        var supplierSummary = await supplierSummaryResponse.Content.ReadFromJsonAsync<ExternalStatementSummaryResponse>();
        Assert.NotNull(supplierSummary);
        Assert.Equal("SUPPLIER", supplierSummary!.PartyType);
        Assert.True(supplierSummary.PaymentCount >= 1);

        var supplierLinesResponse = await _client.GetAsync("/api/v1/external/parties/1/reports-statements/statement-lines");
        Assert.Equal(HttpStatusCode.OK, supplierLinesResponse.StatusCode);
        var supplierLines = await supplierLinesResponse.Content.ReadFromJsonAsync<List<ExternalStatementLineResponse>>();
        Assert.NotNull(supplierLines);
        Assert.Contains(supplierLines!, item => item.DocumentType == "AP_PAYMENT");

        var supplierStatementDocumentsResponse = await _client.GetAsync("/api/v1/external/parties/1/reports-statements");
        Assert.Equal(HttpStatusCode.OK, supplierStatementDocumentsResponse.StatusCode);
        var supplierStatementDocuments = await supplierStatementDocumentsResponse.Content.ReadFromJsonAsync<List<ExternalStatementDocumentResponse>>();
        Assert.NotNull(supplierStatementDocuments);
        Assert.Contains(supplierStatementDocuments!, item => item.StatementType == "SUPPLIER_STATEMENT");

        var supplierStatementDetailResponse = await _client.GetAsync($"/api/v1/external/parties/1/reports-statements/{generatedSupplierStatement.SupplierStatementId}");
        Assert.Equal(HttpStatusCode.OK, supplierStatementDetailResponse.StatusCode);
        var supplierStatementDetail = await supplierStatementDetailResponse.Content.ReadFromJsonAsync<ExternalStatementDetailResponse>();
        Assert.NotNull(supplierStatementDetail);
        Assert.Equal(generatedSupplierStatement.StatementNumber, supplierStatementDetail!.StatementNumber);
        Assert.NotEmpty(supplierStatementDetail.Lines);
        Assert.Contains(supplierStatementDetail.DeliveryLogs, item => item.ChannelCode == "EMAIL");

        var supplierDeliveryLogsResponse = await _client.GetAsync($"/api/v1/external/parties/1/reports-statements/{generatedSupplierStatement.SupplierStatementId}/delivery-logs");
        Assert.Equal(HttpStatusCode.OK, supplierDeliveryLogsResponse.StatusCode);
        var supplierDeliveryLogs = await supplierDeliveryLogsResponse.Content.ReadFromJsonAsync<List<ExternalStatementDeliveryLogResponse>>();
        Assert.NotNull(supplierDeliveryLogs);
        Assert.Contains(supplierDeliveryLogs!, item => item.ChannelCode == "EMAIL");

        var supplierFinancingCasesResponse = await _client.GetAsync("/api/v1/external/parties/1/financing/murabaha-cases");
        Assert.Equal(HttpStatusCode.OK, supplierFinancingCasesResponse.StatusCode);
        var supplierFinancingCases = await supplierFinancingCasesResponse.Content.ReadFromJsonAsync<List<CashLineERP.Contracts.IslamicFinance.IslamicFinanceMurabahaCaseResponse>>();
        Assert.NotNull(supplierFinancingCases);

        await _client.AuthenticateAsFinanceMakerAsync();

        var createCustomerInvoiceResponse = await _client.PostAsJsonAsync("/api/v1/finance/ar-invoices", new CreateAccountsReceivableInvoiceRequest(
            CustomerId: 2,
            SalesOrderId: 1,
            DispatchOrderId: 1,
            InvoiceType: "TAX",
            InvoiceDate: new DateOnly(2026, 4, 9),
            TaxDate: new DateOnly(2026, 4, 9),
            DueDate: new DateOnly(2026, 4, 25),
            CurrencyCode: "EGP",
            Lines:
            [
                new CreateAccountsReceivableInvoiceLineRequest(1, 1001, 4m, "EA", 32m, "VAT14")
            ]));
        Assert.True(createCustomerInvoiceResponse.IsSuccessStatusCode, await createCustomerInvoiceResponse.Content.ReadAsStringAsync());
        var createdCustomerInvoice = await createCustomerInvoiceResponse.Content.ReadFromJsonAsync<AccountsReceivableInvoiceResponse>();
        Assert.NotNull(createdCustomerInvoice);

        var submitCustomerInvoiceResponse = await _client.PostAsync($"/api/v1/finance/ar-invoices/{createdCustomerInvoice!.AccountsReceivableInvoiceId}/submit", null);
        Assert.True(submitCustomerInvoiceResponse.IsSuccessStatusCode, await submitCustomerInvoiceResponse.Content.ReadAsStringAsync());

        await _client.AuthenticateAsFinanceCheckerAsync();

        var approveCustomerInvoiceResponse = await _client.PostAsync($"/api/v1/finance/ar-invoices/{createdCustomerInvoice.AccountsReceivableInvoiceId}/approve", null);
        Assert.True(approveCustomerInvoiceResponse.IsSuccessStatusCode, await approveCustomerInvoiceResponse.Content.ReadAsStringAsync());

        var postCustomerInvoiceResponse = await _client.PostAsync($"/api/v1/finance/ar-invoices/{createdCustomerInvoice.AccountsReceivableInvoiceId}/post", null);
        Assert.True(postCustomerInvoiceResponse.IsSuccessStatusCode, await postCustomerInvoiceResponse.Content.ReadAsStringAsync());
        var postedCustomerInvoice = await postCustomerInvoiceResponse.Content.ReadFromJsonAsync<AccountsReceivableInvoiceResponse>();
        Assert.NotNull(postedCustomerInvoice);
        var postedCustomerReceiptAmount = decimal.Round(postedCustomerInvoice!.TotalAmount * 0.10m, 2, MidpointRounding.AwayFromZero);

        await _client.AuthenticateAsFinanceMakerAsync();

        var createCustomerReceiptResponse = await _client.PostAsJsonAsync("/api/v1/finance/ar-receipts", new CreateAccountsReceivableReceiptRequest(
            CustomerId: 2,
            ReceiptDate: new DateOnly(2026, 4, 10),
            ReceiptMethod: "BANK_TRANSFER",
            CurrencyCode: "EGP",
            AmountAmount: postedCustomerReceiptAmount,
            ReferenceNumber: "HTTP-CUS-PORTAL-RCPT-001",
            Notes: "Customer portal HTTP receipt",
            Allocations:
            [
                new CreateAccountsReceivableReceiptAllocationRequest(postedCustomerInvoice.AccountsReceivableInvoiceId, postedCustomerReceiptAmount, new DateOnly(2026, 4, 10))
            ]));
        Assert.True(createCustomerReceiptResponse.IsSuccessStatusCode, await createCustomerReceiptResponse.Content.ReadAsStringAsync());
        var createdCustomerReceipt = await createCustomerReceiptResponse.Content.ReadFromJsonAsync<AccountsReceivableReceiptResponse>();
        Assert.NotNull(createdCustomerReceipt);

        var submitCustomerReceiptResponse = await _client.PostAsync($"/api/v1/finance/ar-receipts/{createdCustomerReceipt!.AccountsReceivableReceiptId}/submit", null);
        Assert.True(submitCustomerReceiptResponse.IsSuccessStatusCode, await submitCustomerReceiptResponse.Content.ReadAsStringAsync());

        await _client.AuthenticateAsFinanceCheckerAsync();

        var approveCustomerReceiptResponse = await _client.PostAsync($"/api/v1/finance/ar-receipts/{createdCustomerReceipt.AccountsReceivableReceiptId}/approve", null);
        Assert.True(approveCustomerReceiptResponse.IsSuccessStatusCode, await approveCustomerReceiptResponse.Content.ReadAsStringAsync());

        var postCustomerReceiptResponse = await _client.PostAsync($"/api/v1/finance/ar-receipts/{createdCustomerReceipt.AccountsReceivableReceiptId}/post", null);
        Assert.True(postCustomerReceiptResponse.IsSuccessStatusCode, await postCustomerReceiptResponse.Content.ReadAsStringAsync());
        var postedCustomerReceipt = await postCustomerReceiptResponse.Content.ReadFromJsonAsync<AccountsReceivableReceiptResponse>();
        Assert.NotNull(postedCustomerReceipt);

        await _client.AuthenticateAsFinanceCheckerAsync();

        var generateCustomerStatementResponse = await _client.PostAsJsonAsync("/api/v1/finance/customer-statements", new CreateCustomerStatementRequest(
            CustomerId: 2,
            DateFrom: new DateOnly(2026, 4, 1),
            DateTo: new DateOnly(2026, 4, 30),
            CurrencyCode: "EGP"));
        Assert.True(generateCustomerStatementResponse.IsSuccessStatusCode, await generateCustomerStatementResponse.Content.ReadAsStringAsync());
        var generatedCustomerStatement = await generateCustomerStatementResponse.Content.ReadFromJsonAsync<CustomerStatementResponse>();
        Assert.NotNull(generatedCustomerStatement);

        var customerStatementDeliveryResponse = await _client.PostAsJsonAsync($"/api/v1/finance/customer-statements/{generatedCustomerStatement!.CustomerStatementId}/delivery-logs", new RecordCustomerStatementDeliveryRequest(
            DeliveredAtUtc: DateTime.UtcNow,
            ChannelCode: "EMAIL",
            RecipientAddress: "customer@example.com",
            DeliveryStatusCode: "DELIVERED",
            Notes: "External customer statement delivery"));
        Assert.True(customerStatementDeliveryResponse.IsSuccessStatusCode, await customerStatementDeliveryResponse.Content.ReadAsStringAsync());

        var customerCollectionOutbound = await CreateAndActivateEndpointAsync("HTTP Paymob collection outbound", "PAYMOB", "OUTBOUND", "/checkout");
        var customerCollectionInbound = await CreateAndActivateEndpointAsync("HTTP Paymob collection callback", "PAYMOB", "INBOUND", "/checkout-callback");
        await CreateAndActivateCollectionChannelAsync(customerCollectionOutbound, customerCollectionInbound);

        await _client.AuthenticateAsCustomerAsync();

        var customerOrdersResponse = await _client.GetAsync("/api/v1/external/parties/2/orders");
        Assert.Equal(HttpStatusCode.OK, customerOrdersResponse.StatusCode);
        var customerOrders = await customerOrdersResponse.Content.ReadFromJsonAsync<List<ExternalOrderResponse>>();
        Assert.NotNull(customerOrders);
        Assert.Contains(customerOrders!, item => item.OrderType == "SALES_ORDER");

        var createCustomerOrderResponse = await _client.PostAsJsonAsync("/api/v1/external/parties/2/orders", new CreateExternalCustomerOrderRequest(
            BranchId: 10,
            OrderDate: new DateOnly(2026, 4, 11),
            CurrencyCode: "EGP",
            ExchangeRate: 1m,
            Lines:
            [
                new CreateExternalCustomerOrderLineRequest(1001, 100, 2m, "EA", 31m, "VAT14")
            ]));
        Assert.Equal(HttpStatusCode.OK, createCustomerOrderResponse.StatusCode);
        var createdCustomerOrder = await createCustomerOrderResponse.Content.ReadFromJsonAsync<SalesOrderResponse>();
        Assert.NotNull(createdCustomerOrder);
        Assert.Equal(2, createdCustomerOrder!.CustomerId);

        var submitCustomerOrderResponse = await _client.PostAsync($"/api/v1/external/parties/2/orders/{createdCustomerOrder.SalesOrderId}/submit", null);
        Assert.Equal(HttpStatusCode.OK, submitCustomerOrderResponse.StatusCode);
        var submittedCustomerOrder = await submitCustomerOrderResponse.Content.ReadFromJsonAsync<SalesOrderResponse>();
        Assert.NotNull(submittedCustomerOrder);
        Assert.Equal("SUBMITTED", submittedCustomerOrder!.StatusCode);

        var createCustomerProfileResponse = await _client.PostAsJsonAsync("/api/v1/external/parties/2/customer-profile", new CreateCustomerProfileRequest(
            2,
            null,
            "COMPANY",
            "ENTERPRISE",
            "EGP",
            "DIRECT_SALES",
            "STANDARD",
            "EMAIL",
            "External customer onboarding"));
        Assert.Equal(HttpStatusCode.OK, createCustomerProfileResponse.StatusCode);
        var createdCustomerProfile = await createCustomerProfileResponse.Content.ReadFromJsonAsync<CustomerProfileResponse>();
        Assert.NotNull(createdCustomerProfile);

        var submitCustomerProfileResponse = await _client.PostAsync("/api/v1/external/parties/2/customer-profile/submit", null);
        Assert.Equal(HttpStatusCode.OK, submitCustomerProfileResponse.StatusCode);
        var submittedCustomerProfile = await submitCustomerProfileResponse.Content.ReadFromJsonAsync<CustomerProfileResponse>();
        Assert.NotNull(submittedCustomerProfile);
        Assert.Equal("SUBMITTED", submittedCustomerProfile!.StatusCode);

        var customerProfileResponse = await _client.GetAsync("/api/v1/external/parties/2/customer-profile");
        Assert.Equal(HttpStatusCode.OK, customerProfileResponse.StatusCode);
        var customerProfile = await customerProfileResponse.Content.ReadFromJsonAsync<CustomerProfileResponse>();
        Assert.NotNull(customerProfile);
        Assert.Equal(createdCustomerProfile!.CustomerProfileCode, customerProfile!.CustomerProfileCode);

        var customerInvoicesResponse = await _client.GetAsync("/api/v1/external/parties/2/invoices");
        Assert.Equal(HttpStatusCode.OK, customerInvoicesResponse.StatusCode);
        var customerInvoices = await customerInvoicesResponse.Content.ReadFromJsonAsync<List<ExternalInvoiceResponse>>();
        Assert.NotNull(customerInvoices);
        Assert.Contains(customerInvoices!, item => item.InvoiceNumber == postedCustomerInvoice.InvoiceNumber);

        var customerPaymentsResponse = await _client.GetAsync("/api/v1/external/parties/2/payments");
        Assert.Equal(HttpStatusCode.OK, customerPaymentsResponse.StatusCode);
        var customerPayments = await customerPaymentsResponse.Content.ReadFromJsonAsync<List<ExternalPaymentResponse>>();
        Assert.NotNull(customerPayments);
        Assert.Contains(customerPayments!, item => item.PaymentNumber == postedCustomerReceipt!.ReceiptNumber);

        var createCustomerPaymentResponse = await _client.PostAsJsonAsync("/api/v1/external/parties/2/payments", new CreateExternalCustomerPaymentRequest(
            AccountsReceivableInvoiceId: postedCustomerInvoice.AccountsReceivableInvoiceId,
            IntegrationProviderCode: "PAYMOB",
            CurrencyCode: "EGP",
            AmountAmount: postedCustomerInvoice.TotalAmount - postedCustomerReceipt.AmountAmount,
            PaymentDate: new DateOnly(2026, 4, 10),
            ReferenceNumber: "HTTP-CUS-GW-0001",
            Notes: "Customer gateway payment request from the external HTTP QA path."));
        Assert.Equal(HttpStatusCode.OK, createCustomerPaymentResponse.StatusCode);
        var createdCustomerPayment = await createCustomerPaymentResponse.Content.ReadFromJsonAsync<ExternalPaymentResponse>();
        Assert.NotNull(createdCustomerPayment);
        Assert.Equal("CUSTOMER_PAYMENT_REQUEST", createdCustomerPayment!.PaymentType);
        Assert.Equal("PENDING_CUSTOMER_ACTION", createdCustomerPayment.StatusCode);

        customerPaymentsResponse = await _client.GetAsync("/api/v1/external/parties/2/payments");
        Assert.Equal(HttpStatusCode.OK, customerPaymentsResponse.StatusCode);
        customerPayments = await customerPaymentsResponse.Content.ReadFromJsonAsync<List<ExternalPaymentResponse>>();
        Assert.NotNull(customerPayments);
        Assert.Contains(customerPayments!, item => item.PaymentNumber == createdCustomerPayment.PaymentNumber && item.PaymentType == "CUSTOMER_PAYMENT_REQUEST");

        var customerSummaryResponse = await _client.GetAsync("/api/v1/external/parties/2/reports-statements/summary");
        Assert.Equal(HttpStatusCode.OK, customerSummaryResponse.StatusCode);
        var customerSummary = await customerSummaryResponse.Content.ReadFromJsonAsync<ExternalStatementSummaryResponse>();
        Assert.NotNull(customerSummary);
        Assert.Equal("CUSTOMER", customerSummary!.PartyType);
        Assert.Equal("EGP", customerSummary.CurrencyCode);

        var customerLinesResponse = await _client.GetAsync("/api/v1/external/parties/2/reports-statements/statement-lines");
        Assert.Equal(HttpStatusCode.OK, customerLinesResponse.StatusCode);
        var customerLines = await customerLinesResponse.Content.ReadFromJsonAsync<List<ExternalStatementLineResponse>>();
        Assert.NotNull(customerLines);
        Assert.Contains(customerLines!, item => item.DocumentNumber == postedCustomerInvoice.InvoiceNumber);
        Assert.Contains(customerLines!, item => item.DocumentNumber == postedCustomerReceipt.ReceiptNumber);

        var customerDeliveriesResponse = await _client.GetAsync("/api/v1/external/parties/2/customer-deliveries");
        Assert.Equal(HttpStatusCode.OK, customerDeliveriesResponse.StatusCode);
        var customerDeliveries = await customerDeliveriesResponse.Content.ReadFromJsonAsync<List<ExternalCustomerDeliveryResponse>>();
        Assert.NotNull(customerDeliveries);
        Assert.Contains(customerDeliveries!, item => item.DispatchNumber == "DSP-000001");

        var customerStatusTrackingResponse = await _client.GetAsync("/api/v1/external/parties/2/customer-status-tracking");
        Assert.Equal(HttpStatusCode.OK, customerStatusTrackingResponse.StatusCode);
        var customerStatusTracking = await customerStatusTrackingResponse.Content.ReadFromJsonAsync<ExternalCustomerStatusTrackingResponse>();
        Assert.NotNull(customerStatusTracking);
        Assert.Equal(createdCustomerProfile.CustomerProfileId, customerStatusTracking!.CustomerProfileId);
        Assert.True(customerStatusTracking.OrderCount >= 1);
        Assert.True(customerStatusTracking.DeliveryCount >= 1);

        var customerStatementDocumentsResponse = await _client.GetAsync("/api/v1/external/parties/2/reports-statements");
        Assert.Equal(HttpStatusCode.OK, customerStatementDocumentsResponse.StatusCode);
        var customerStatementDocuments = await customerStatementDocumentsResponse.Content.ReadFromJsonAsync<List<ExternalStatementDocumentResponse>>();
        Assert.NotNull(customerStatementDocuments);
        Assert.Contains(customerStatementDocuments!, item => item.StatementType == "CUSTOMER_STATEMENT");

        var uploadCustomerDocumentResponse = await _client.PostAsJsonAsync("/api/v1/external/parties/2/customer-documents", new RecordBusinessPartyComplianceDocumentRequest(
            "VAT_CERTIFICATE",
            "customer-vat.pdf",
            "managed://customer/customer-vat.pdf",
            "application/pdf",
            2048));
        Assert.Equal(HttpStatusCode.OK, uploadCustomerDocumentResponse.StatusCode);

        var customerDocumentsResponse = await _client.GetAsync("/api/v1/external/parties/2/customer-documents");
        Assert.Equal(HttpStatusCode.OK, customerDocumentsResponse.StatusCode);
        var customerDocuments = await customerDocumentsResponse.Content.ReadFromJsonAsync<List<ExternalCustomerDocumentResponse>>();
        Assert.NotNull(customerDocuments);
        Assert.Contains(customerDocuments!, item => item.DocumentSourceType == "COMPLIANCE_DOCUMENT");
        Assert.Contains(customerDocuments!, item => item.DocumentSourceType == "STATEMENT_DOCUMENT");

        var createCustomerDocumentWorkflowResponse = await _client.PostAsJsonAsync("/api/v1/external/parties/2/document-workflows", new CreateExternalDocumentWorkflowRequest(
            "COMMERCIAL_REGISTER",
            "customer-commercial-register-v1.pdf",
            "managed://customer/customer-commercial-register-v1.pdf",
            "application/pdf",
            4096,
            "Initial commercial-register upload"));
        Assert.Equal(HttpStatusCode.OK, createCustomerDocumentWorkflowResponse.StatusCode);
        var createdCustomerDocumentWorkflow = await createCustomerDocumentWorkflowResponse.Content.ReadFromJsonAsync<ExternalDocumentWorkflowResponse>();
        Assert.NotNull(createdCustomerDocumentWorkflow);
        Assert.Equal("DRAFT", createdCustomerDocumentWorkflow!.StatusCode);

        var submitCustomerDocumentWorkflowResponse = await _client.PostAsync($"/api/v1/external/parties/2/document-workflows/{createdCustomerDocumentWorkflow.WorkflowId}/submit", null);
        Assert.Equal(HttpStatusCode.OK, submitCustomerDocumentWorkflowResponse.StatusCode);

        var createCustomerServiceRequestResponse = await _client.PostAsJsonAsync("/api/v1/external/parties/2/service-requests", new CreateExternalCustomerServiceRequestRequest(
            "INVOICE_QUERY",
            "Need invoice clarification",
            "The customer needs clarification on the posted invoice.",
            "NORMAL",
            "INVOICE",
            "COMMERCIAL_REVIEW",
            "COMMERCIAL",
            "AR_INVOICE",
            createdCustomerInvoice.AccountsReceivableInvoiceId));
        Assert.Equal(HttpStatusCode.OK, createCustomerServiceRequestResponse.StatusCode);
        var createdCustomerServiceRequest = await createCustomerServiceRequestResponse.Content.ReadFromJsonAsync<ExternalCustomerServiceRequestResponse>();
        Assert.NotNull(createdCustomerServiceRequest);
        Assert.Equal("DRAFT", createdCustomerServiceRequest!.StatusCode);

        var submitCustomerServiceRequestResponse = await _client.PostAsync($"/api/v1/external/parties/2/service-requests/{createdCustomerServiceRequest.ServiceRequestId}/submit", null);
        Assert.Equal(HttpStatusCode.OK, submitCustomerServiceRequestResponse.StatusCode);

        var customerStatementDetailResponse = await _client.GetAsync($"/api/v1/external/parties/2/reports-statements/{generatedCustomerStatement.CustomerStatementId}");
        Assert.Equal(HttpStatusCode.OK, customerStatementDetailResponse.StatusCode);
        var customerStatementDetail = await customerStatementDetailResponse.Content.ReadFromJsonAsync<ExternalStatementDetailResponse>();
        Assert.NotNull(customerStatementDetail);
        Assert.Equal(generatedCustomerStatement.StatementNumber, customerStatementDetail!.StatementNumber);
        Assert.NotEmpty(customerStatementDetail.Lines);
        Assert.Contains(customerStatementDetail.DeliveryLogs, item => item.ChannelCode == "EMAIL");

        var customerDeliveryLogsResponse = await _client.GetAsync($"/api/v1/external/parties/2/reports-statements/{generatedCustomerStatement.CustomerStatementId}/delivery-logs");
        Assert.Equal(HttpStatusCode.OK, customerDeliveryLogsResponse.StatusCode);
        var customerDeliveryLogs = await customerDeliveryLogsResponse.Content.ReadFromJsonAsync<List<ExternalStatementDeliveryLogResponse>>();
        Assert.NotNull(customerDeliveryLogs);
        Assert.Contains(customerDeliveryLogs!, item => item.ChannelCode == "EMAIL");

        var customerFinancingRequestsResponse = await _client.GetAsync("/api/v1/external/parties/2/financing/requests");
        Assert.Equal(HttpStatusCode.OK, customerFinancingRequestsResponse.StatusCode);
        var customerFinancingRequests = await customerFinancingRequestsResponse.Content.ReadFromJsonAsync<List<CashLineERP.Contracts.IslamicFinance.IslamicFinanceFinancingRequestResponse>>();
        Assert.NotNull(customerFinancingRequests);

        await _client.AuthenticateAsFinanceMakerAsync();

        var createProductProfileResponse = await _client.PostAsJsonAsync("/api/v1/islamic-finance/product-profiles", new CashLineERP.Contracts.IslamicFinance.CreateIslamicFinanceProductProfileRequest
        {
            ProductType = "MURABAHA",
            ProductCode = "HTTP_PORTAL_MURABAHA",
            ProductName = "HTTP Portal Murabaha",
            RequiresShariahReview = true,
            AllowsPartnerFunding = true,
            AllowsCashLineFunding = false
        });
        Assert.Equal(HttpStatusCode.OK, createProductProfileResponse.StatusCode);
        var createdProductProfile = await createProductProfileResponse.Content.ReadFromJsonAsync<CashLineERP.Contracts.IslamicFinance.IslamicFinanceProductProfileResponse>();
        Assert.NotNull(createdProductProfile);

        var submitProductProfileResponse = await _client.PostAsync($"/api/v1/islamic-finance/product-profiles/{createdProductProfile!.Id}/submit", null);
        Assert.Equal(HttpStatusCode.OK, submitProductProfileResponse.StatusCode);

        var createPartnerLenderResponse = await _client.PostAsJsonAsync("/api/v1/islamic-finance/partners", new CreateIslamicFinancePartnerLenderRequest
        {
            PartnerLenderPartyId = 1,
            DefaultCurrencyCode = "EGP",
            SupportsMurabaha = true,
            SupportsReceivablesFinance = true,
            SupportsTawarruq = true
        });
        Assert.Equal(HttpStatusCode.OK, createPartnerLenderResponse.StatusCode);
        var createdPartnerLender = await createPartnerLenderResponse.Content.ReadFromJsonAsync<IslamicFinancePartnerLenderResponse>();
        Assert.NotNull(createdPartnerLender);

        var submitPartnerLenderResponse = await _client.PostAsync($"/api/v1/islamic-finance/partners/{createdPartnerLender!.Id}/submit", null);
        Assert.Equal(HttpStatusCode.OK, submitPartnerLenderResponse.StatusCode);

        await _client.AuthenticateAsFinanceCheckerAsync();

        var approvePartnerLenderResponse = await _client.PostAsync($"/api/v1/islamic-finance/partners/{createdPartnerLender.Id}/approve", null);
        Assert.Equal(HttpStatusCode.OK, approvePartnerLenderResponse.StatusCode);

        var activatePartnerLenderResponse = await _client.PostAsync($"/api/v1/islamic-finance/partners/{createdPartnerLender.Id}/activate", null);
        Assert.Equal(HttpStatusCode.OK, activatePartnerLenderResponse.StatusCode);

        var approveProductProfileResponse = await _client.PostAsync($"/api/v1/islamic-finance/product-profiles/{createdProductProfile.Id}/approve", null);
        Assert.Equal(HttpStatusCode.OK, approveProductProfileResponse.StatusCode);

        var activateProductProfileResponse = await _client.PostAsync($"/api/v1/islamic-finance/product-profiles/{createdProductProfile.Id}/activate", null);
        Assert.Equal(HttpStatusCode.OK, activateProductProfileResponse.StatusCode);

        await _client.AuthenticateAsFinanceMakerAsync();

        var createTawarruqProductProfileResponse = await _client.PostAsJsonAsync("/api/v1/islamic-finance/product-profiles", new CreateIslamicFinanceProductProfileRequest
        {
            ProductType = "TAWARRUQ",
            ProductCode = "HTTP_PORTAL_TAWARRUQ",
            ProductName = "HTTP Portal Tawarruq",
            RequiresShariahReview = true,
            AllowsPartnerFunding = true,
            AllowsCashLineFunding = true
        });
        Assert.Equal(HttpStatusCode.OK, createTawarruqProductProfileResponse.StatusCode);
        var createdTawarruqProductProfile = await createTawarruqProductProfileResponse.Content.ReadFromJsonAsync<IslamicFinanceProductProfileResponse>();
        Assert.NotNull(createdTawarruqProductProfile);

        var submitTawarruqProductProfileResponse = await _client.PostAsync($"/api/v1/islamic-finance/product-profiles/{createdTawarruqProductProfile!.Id}/submit", null);
        Assert.Equal(HttpStatusCode.OK, submitTawarruqProductProfileResponse.StatusCode);

        await _client.AuthenticateAsFinanceCheckerAsync();

        var approveTawarruqProductProfileResponse = await _client.PostAsync($"/api/v1/islamic-finance/product-profiles/{createdTawarruqProductProfile.Id}/approve", null);
        Assert.Equal(HttpStatusCode.OK, approveTawarruqProductProfileResponse.StatusCode);

        var activateTawarruqProductProfileResponse = await _client.PostAsync($"/api/v1/islamic-finance/product-profiles/{createdTawarruqProductProfile.Id}/activate", null);
        Assert.Equal(HttpStatusCode.OK, activateTawarruqProductProfileResponse.StatusCode);

        await _client.AuthenticateAsCustomerAsync();

        var financingProductsResponse = await _client.GetAsync("/api/v1/external/parties/2/financing/products");
        Assert.Equal(HttpStatusCode.OK, financingProductsResponse.StatusCode);
        var financingProducts = await financingProductsResponse.Content.ReadFromJsonAsync<List<IslamicFinanceProductProfileResponse>>();
        Assert.NotNull(financingProducts);
        Assert.Contains(financingProducts!, item => item.ProductType == "MURABAHA" && item.Id == createdProductProfile.Id && item.IsActive);
        Assert.Contains(financingProducts!, item => item.ProductType == "TAWARRUQ" && item.Id == createdTawarruqProductProfile.Id && item.IsActive);

        var financingFamiliesResponse = await _client.GetAsync("/api/v1/external/parties/2/financing/product-families");
        Assert.Equal(HttpStatusCode.OK, financingFamiliesResponse.StatusCode);
        var financingFamilies = await financingFamiliesResponse.Content.ReadFromJsonAsync<List<System.Text.Json.JsonElement>>();
        Assert.NotNull(financingFamilies);
        Assert.Contains(financingFamilies!, item => item.GetProperty("productTypeCode").GetString() == "MURABAHA");
        Assert.Contains(financingFamilies!, item => item.GetProperty("futureReadinessCode").GetString() == "MICROFINANCE_READY");

        var createCustomerFinancingRequestResponse = await _client.PostAsJsonAsync("/api/v1/external/parties/2/financing/requests", new CreateExternalFinancingApplicationRequest
        {
            RequestNumber = "HTTP-CUS-IF-0001",
            ProductProfileId = createdProductProfile!.Id,
            FacilityId = null,
            FundingSourceMode = "PARTNER",
            SourceDocumentType = "SALES_ORDER",
            SourceDocumentId = createdCustomerOrder.SalesOrderId,
            TransactionCurrencyCode = "EGP",
            RequestedAmount = 54000m
        });
        Assert.Equal(HttpStatusCode.OK, createCustomerFinancingRequestResponse.StatusCode);
        var createdCustomerFinancingRequest = await createCustomerFinancingRequestResponse.Content.ReadFromJsonAsync<CashLineERP.Contracts.IslamicFinance.IslamicFinanceFinancingRequestResponse>();
        Assert.NotNull(createdCustomerFinancingRequest);

        var customerFinancingRequestDetailResponse = await _client.GetAsync($"/api/v1/external/parties/2/financing/requests/{createdCustomerFinancingRequest!.Id}");
        Assert.Equal(HttpStatusCode.OK, customerFinancingRequestDetailResponse.StatusCode);
        var customerFinancingRequestDetail = await customerFinancingRequestDetailResponse.Content.ReadFromJsonAsync<IslamicFinanceFinancingRequestResponse>();
        Assert.NotNull(customerFinancingRequestDetail);
        Assert.Equal(createdCustomerFinancingRequest.RequestNumber, customerFinancingRequestDetail!.RequestNumber);
        Assert.Equal(2, createdCustomerFinancingRequest!.ApplicantPartyId);
        Assert.Equal("CUSTOMER", createdCustomerFinancingRequest.ApplicantPartyTypeCode);
        Assert.Equal("DRAFT", createdCustomerFinancingRequest!.StatusCode);

        var submitCustomerFinancingRequestResponse = await _client.PostAsync($"/api/v1/external/parties/2/financing/requests/{createdCustomerFinancingRequest.Id}/submit", null);
        Assert.Equal(HttpStatusCode.OK, submitCustomerFinancingRequestResponse.StatusCode);
        var submittedCustomerFinancingRequest = await submitCustomerFinancingRequestResponse.Content.ReadFromJsonAsync<CashLineERP.Contracts.IslamicFinance.IslamicFinanceFinancingRequestResponse>();
        Assert.NotNull(submittedCustomerFinancingRequest);
        Assert.Equal("SUBMITTED", submittedCustomerFinancingRequest!.StatusCode);

        await _client.AuthenticateAsFinanceCheckerAsync();

        var approveCustomerFinancingRequestResponse = await _client.PostAsync($"/api/v1/islamic-finance/requests/{createdCustomerFinancingRequest.Id}/approve", null);
        Assert.Equal(HttpStatusCode.OK, approveCustomerFinancingRequestResponse.StatusCode);

        var createCustomerOfferDecisionResponse = await _client.PostAsJsonAsync($"/api/v1/islamic-finance/requests/{createdCustomerFinancingRequest.Id}/decisions", new CreateIslamicFinanceDecisionRequest
        {
            DecisionCode = "APPROVED",
            DecisionNotes = "Customer offer available for portal comparison.",
            DecidingPartyId = 2,
            PartnerLenderId = createdPartnerLender.Id,
            OfferProductTypeCode = "MURABAHA",
            OfferFundingSourceMode = "PARTNER",
            OfferCurrencyCode = "EGP",
            OfferedAmount = 52500m,
            TenorMonths = 10,
            ProfitRatePercent = 10.75m,
            ProcessingFeeAmount = 250m,
            SecurityRequirementText = "Promissory note and trade-document package.",
            OfferRank = 1
        });
        Assert.Equal(HttpStatusCode.OK, createCustomerOfferDecisionResponse.StatusCode);
        var customerOfferDecision = await createCustomerOfferDecisionResponse.Content.ReadFromJsonAsync<IslamicFinanceDecisionResponse>();
        Assert.NotNull(customerOfferDecision);

        var submitCustomerOfferDecisionResponse = await _client.PostAsync($"/api/v1/islamic-finance/decisions/{customerOfferDecision!.Id}/submit", null);
        Assert.Equal(HttpStatusCode.OK, submitCustomerOfferDecisionResponse.StatusCode);

        var approveCustomerOfferDecisionResponse = await _client.PostAsync($"/api/v1/islamic-finance/decisions/{customerOfferDecision.Id}/approve", null);
        Assert.Equal(HttpStatusCode.OK, approveCustomerOfferDecisionResponse.StatusCode);

        await _client.AuthenticateAsCustomerAsync();

        var customerFinancingOffersResponse = await _client.GetAsync("/api/v1/external/parties/2/financing/offers");
        Assert.Equal(HttpStatusCode.OK, customerFinancingOffersResponse.StatusCode);
        var customerFinancingOffers = await customerFinancingOffersResponse.Content.ReadFromJsonAsync<List<ExternalFinancingOfferResponse>>();
        Assert.NotNull(customerFinancingOffers);
        Assert.All(customerFinancingOffers!, item =>
        {
            Assert.False(string.IsNullOrWhiteSpace(item.FinancingRequestNumber));
            Assert.Equal(2, item.ApplicantPartyId);
            Assert.Equal("CUSTOMER", item.ApplicantPartyTypeCode);
        });
        var customerOfferToAccept = Assert.Single(customerFinancingOffers, item => item.FinancingRequestId == createdCustomerFinancingRequest.Id && item.PartnerLenderId == createdPartnerLender.Id);
        Assert.False(customerOfferToAccept.IsSelectedOffer);
        Assert.Equal("MURABAHA", customerOfferToAccept.ProductTypeCode);
        Assert.Equal(52500m, customerOfferToAccept.OfferedAmount);
        Assert.Equal(10, customerOfferToAccept.TenorMonths);

        var customerOfferComparisonResponse = await _client.GetAsync($"/api/v1/external/parties/2/financing/requests/{createdCustomerFinancingRequest.Id}/offers");
        Assert.Equal(HttpStatusCode.OK, customerOfferComparisonResponse.StatusCode);
        var customerOfferComparison = await customerOfferComparisonResponse.Content.ReadFromJsonAsync<List<ExternalFinancingOfferResponse>>();
        Assert.NotNull(customerOfferComparison);
        Assert.Single(customerOfferComparison!);

        var customerJourneyBeforeSelectionResponse = await _client.GetAsync($"/api/v1/external/parties/2/financing/requests/{createdCustomerFinancingRequest.Id}/journey-summary");
        Assert.Equal(HttpStatusCode.OK, customerJourneyBeforeSelectionResponse.StatusCode);
        var customerJourneyBeforeSelection = await customerJourneyBeforeSelectionResponse.Content.ReadFromJsonAsync<ExternalFinancingJourneySummaryResponse>();
        Assert.NotNull(customerJourneyBeforeSelection);
        Assert.Equal("COMPARE_AND_SELECT_OFFER", customerJourneyBeforeSelection!.NextExternalActionCode);
        Assert.Equal("OFFER_COMPARISON", customerJourneyBeforeSelection.ExecutionStageCode);

        var acceptCustomerOfferResponse = await _client.PostAsJsonAsync($"/api/v1/external/parties/2/financing/requests/{createdCustomerFinancingRequest.Id}/accept-offer", new AcceptExternalFinancingOfferRequest(customerOfferToAccept.FinancingDecisionId!.Value));
        Assert.Equal(HttpStatusCode.OK, acceptCustomerOfferResponse.StatusCode);
        var acceptedCustomerOffer = await acceptCustomerOfferResponse.Content.ReadFromJsonAsync<IslamicFinanceFinancingRequestResponse>();
        Assert.NotNull(acceptedCustomerOffer);
        Assert.Equal(createdPartnerLender.Id, acceptedCustomerOffer!.AssignedPartnerLenderId);
        Assert.Equal(customerOfferToAccept.FinancingDecisionId, acceptedCustomerOffer.SelectedFinancingDecisionId);

        var customerJourneyAfterSelectionResponse = await _client.GetAsync($"/api/v1/external/parties/2/financing/requests/{createdCustomerFinancingRequest.Id}/journey-summary");
        Assert.Equal(HttpStatusCode.OK, customerJourneyAfterSelectionResponse.StatusCode);
        var customerJourneyAfterSelection = await customerJourneyAfterSelectionResponse.Content.ReadFromJsonAsync<ExternalFinancingJourneySummaryResponse>();
        Assert.NotNull(customerJourneyAfterSelection);
        Assert.Equal("AWAIT_EXECUTION_CASE", customerJourneyAfterSelection!.NextExternalActionCode);
        Assert.Equal("PARTNER_LENDER", customerJourneyAfterSelection.ProviderModelCode);

        await _client.AuthenticateAsInternalAsync();

        var returnCustomerDocumentWorkflowResponse = await _client.PostAsJsonAsync($"/api/v1/customers/document-workflows/{createdCustomerDocumentWorkflow.WorkflowId}/return", new ReviewExternalDocumentWorkflowRequest(
            "Please upload the renewed commercial register."));
        Assert.Equal(HttpStatusCode.OK, returnCustomerDocumentWorkflowResponse.StatusCode);
        var returnedCustomerDocumentWorkflow = await returnCustomerDocumentWorkflowResponse.Content.ReadFromJsonAsync<ExternalDocumentWorkflowResponse>();
        Assert.NotNull(returnedCustomerDocumentWorkflow);
        Assert.Equal("RETURNED", returnedCustomerDocumentWorkflow!.StatusCode);

        var reviewCustomerServiceRequestResponse = await _client.PostAsync($"/api/v1/customers/service-requests/{createdCustomerServiceRequest.ServiceRequestId}/review", null);
        Assert.Equal(HttpStatusCode.OK, reviewCustomerServiceRequestResponse.StatusCode);

        var respondCustomerServiceRequestResponse = await _client.PostAsJsonAsync($"/api/v1/customers/service-requests/{createdCustomerServiceRequest.ServiceRequestId}/respond", new ReviewExternalCustomerServiceRequest(
            "Invoice details were reviewed and the requested clarification was sent."));
        Assert.Equal(HttpStatusCode.OK, respondCustomerServiceRequestResponse.StatusCode);

        await _client.AuthenticateAsCustomerAsync();

        var escalateCustomerServiceRequestResponse = await _client.PostAsJsonAsync($"/api/v1/external/parties/2/service-requests/{createdCustomerServiceRequest.ServiceRequestId}/escalate", new EscalateExternalCustomerServiceRequestRequest(
            "Customer needs commercial escalation before closure.",
            "FINANCE",
            "CREDIT_REVIEW"));
        Assert.Equal(HttpStatusCode.OK, escalateCustomerServiceRequestResponse.StatusCode);
        var escalatedCustomerServiceRequest = await escalateCustomerServiceRequestResponse.Content.ReadFromJsonAsync<ExternalCustomerServiceRequestResponse>();
        Assert.NotNull(escalatedCustomerServiceRequest);
        Assert.Equal("ESCALATED", escalatedCustomerServiceRequest!.StatusCode);
        Assert.Equal("Customer needs commercial escalation before closure.", escalatedCustomerServiceRequest.EscalationReasonText);
        Assert.Equal("FINANCE", escalatedCustomerServiceRequest.AssignedBackofficeLaneCode);
        Assert.Equal("CREDIT_REVIEW", escalatedCustomerServiceRequest.RequestedResolutionCode);
        Assert.Equal(1, escalatedCustomerServiceRequest.EscalationLevel);

        await _client.AuthenticateAsInternalAsync();

        var routeCustomerServiceRequestResponse = await _client.PostAsJsonAsync($"/api/v1/customers/service-requests/{createdCustomerServiceRequest.ServiceRequestId}/route", new RouteExternalCustomerServiceRequestRequest(
            "COMMERCIAL",
            "COMMERCIAL_REVIEW"));
        Assert.Equal(HttpStatusCode.OK, routeCustomerServiceRequestResponse.StatusCode);

        var reviewEscalatedCustomerServiceRequestResponse = await _client.PostAsync($"/api/v1/customers/service-requests/{createdCustomerServiceRequest.ServiceRequestId}/review", null);
        Assert.Equal(HttpStatusCode.OK, reviewEscalatedCustomerServiceRequestResponse.StatusCode);

        var closeCustomerServiceRequestResponse = await _client.PostAsJsonAsync($"/api/v1/customers/service-requests/{createdCustomerServiceRequest.ServiceRequestId}/close", new CloseExternalCustomerServiceRequest(
            "Customer confirmed the clarification."));
        Assert.Equal(HttpStatusCode.OK, closeCustomerServiceRequestResponse.StatusCode);

        await _client.AuthenticateAsCustomerAsync();

        var replaceCustomerDocumentWorkflowResponse = await _client.PostAsJsonAsync($"/api/v1/external/parties/2/document-workflows/{createdCustomerDocumentWorkflow.WorkflowId}/replace", new ReplaceExternalDocumentWorkflowRequest(
            "customer-commercial-register-v2.pdf",
            "managed://customer/customer-commercial-register-v2.pdf",
            "application/pdf",
            5120,
            "Renewed commercial register uploaded",
            "Renewed document"));
        Assert.Equal(HttpStatusCode.OK, replaceCustomerDocumentWorkflowResponse.StatusCode);
        var replacedCustomerDocumentWorkflow = await replaceCustomerDocumentWorkflowResponse.Content.ReadFromJsonAsync<ExternalDocumentWorkflowResponse>();
        Assert.NotNull(replacedCustomerDocumentWorkflow);
        Assert.Equal(2, replacedCustomerDocumentWorkflow!.VersionNumber);
        Assert.Equal("DRAFT", replacedCustomerDocumentWorkflow.StatusCode);

        var resubmitCustomerDocumentWorkflowResponse = await _client.PostAsync($"/api/v1/external/parties/2/document-workflows/{createdCustomerDocumentWorkflow.WorkflowId}/submit", null);
        Assert.Equal(HttpStatusCode.OK, resubmitCustomerDocumentWorkflowResponse.StatusCode);

        var customerServiceRequestsResponse = await _client.GetAsync("/api/v1/external/parties/2/service-requests");
        Assert.Equal(HttpStatusCode.OK, customerServiceRequestsResponse.StatusCode);
        var customerServiceRequests = await customerServiceRequestsResponse.Content.ReadFromJsonAsync<List<ExternalCustomerServiceRequestResponse>>();
        Assert.NotNull(customerServiceRequests);
        Assert.Contains(customerServiceRequests!, item => item.ServiceRequestId == createdCustomerServiceRequest.ServiceRequestId && item.StatusCode == "CLOSED" && item.EscalationReasonText == "Customer needs commercial escalation before closure.");

        await _client.AuthenticateAsSupplierAsync();

        var createSupplierFinancingRequestResponse = await _client.PostAsJsonAsync("/api/v1/external/parties/1/financing/requests", new CreateExternalFinancingApplicationRequest
        {
            RequestNumber = "HTTP-SUP-IF-0001",
            ProductProfileId = createdProductProfile.Id,
            FacilityId = null,
            FundingSourceMode = "PARTNER",
            SourceDocumentType = "PURCHASE_ORDER",
            SourceDocumentId = 1,
            TransactionCurrencyCode = "EGP",
            RequestedAmount = 42000m
        });
        Assert.Equal(HttpStatusCode.OK, createSupplierFinancingRequestResponse.StatusCode);
        var createdSupplierFinancingRequest = await createSupplierFinancingRequestResponse.Content.ReadFromJsonAsync<CashLineERP.Contracts.IslamicFinance.IslamicFinanceFinancingRequestResponse>();
        Assert.NotNull(createdSupplierFinancingRequest);
        Assert.Equal(1, createdSupplierFinancingRequest!.ApplicantPartyId);
        Assert.Equal("SUPPLIER", createdSupplierFinancingRequest.ApplicantPartyTypeCode);

        var submitSupplierFinancingRequestResponse = await _client.PostAsync($"/api/v1/external/parties/1/financing/requests/{createdSupplierFinancingRequest!.Id}/submit", null);
        Assert.Equal(HttpStatusCode.OK, submitSupplierFinancingRequestResponse.StatusCode);

        var supplierFinancingNotificationsResponse = await _client.GetAsync($"/api/v1/external/parties/1/financing/requests/{createdSupplierFinancingRequest.Id}/notifications");
        Assert.Equal(HttpStatusCode.OK, supplierFinancingNotificationsResponse.StatusCode);
        var supplierFinancingNotifications = await supplierFinancingNotificationsResponse.Content.ReadFromJsonAsync<List<ExternalFinancingNotificationResponse>>();
        Assert.NotNull(supplierFinancingNotifications);
        Assert.Contains(supplierFinancingNotifications!, item => item.TemplateCode == "NTTMP-000002" && item.StatusCode == "PENDING");

        var supplierFinancingTasksResponse = await _client.GetAsync("/api/v1/external/parties/1/financing/tasks");
        Assert.Equal(HttpStatusCode.OK, supplierFinancingTasksResponse.StatusCode);
        var supplierFinancingTasks = await supplierFinancingTasksResponse.Content.ReadFromJsonAsync<List<ExternalFinancingTaskResponse>>();
        Assert.NotNull(supplierFinancingTasks);
        Assert.Contains(supplierFinancingTasks!, item => item.FinancingRequestId == createdSupplierFinancingRequest.Id);

        var supplierFinancingRequestsResponse = await _client.GetAsync("/api/v1/external/parties/1/financing/requests");
        Assert.Equal(HttpStatusCode.OK, supplierFinancingRequestsResponse.StatusCode);
        var supplierFinancingRequests = await supplierFinancingRequestsResponse.Content.ReadFromJsonAsync<List<CashLineERP.Contracts.IslamicFinance.IslamicFinanceFinancingRequestResponse>>();
        Assert.NotNull(supplierFinancingRequests);
        Assert.Contains(supplierFinancingRequests!, item => item.Id == createdSupplierFinancingRequest.Id);

        await _client.AuthenticateAsFinanceCheckerAsync();

        var approveSupplierFinancingRequestResponse = await _client.PostAsync($"/api/v1/islamic-finance/requests/{createdSupplierFinancingRequest.Id}/approve", null);
        Assert.Equal(HttpStatusCode.OK, approveSupplierFinancingRequestResponse.StatusCode);

        var routeSupplierPartnersResponse = await _client.PostAsync($"/api/v1/islamic-finance/requests/{createdSupplierFinancingRequest.Id}/route-partners", null);
        Assert.Equal(HttpStatusCode.OK, routeSupplierPartnersResponse.StatusCode);
        var routedSupplierPartners = await routeSupplierPartnersResponse.Content.ReadFromJsonAsync<IslamicFinancePartnerOrchestrationResponse>();
        Assert.NotNull(routedSupplierPartners);
        Assert.Equal("PARTNER_ASSIGNED", routedSupplierPartners!.OrchestrationStageCode);
        Assert.Equal("COLLECT_PARTNER_OFFERS", routedSupplierPartners.NextInternalActionCode);
        Assert.Equal(createdPartnerLender.Id, routedSupplierPartners.AssignedPartnerLenderId);

        await _client.AuthenticateAsSupplierAsync();

        var routedSupplierTasksResponse = await _client.GetAsync("/api/v1/external/parties/1/financing/tasks");
        Assert.Equal(HttpStatusCode.OK, routedSupplierTasksResponse.StatusCode);
        var routedSupplierTasks = await routedSupplierTasksResponse.Content.ReadFromJsonAsync<List<ExternalFinancingTaskResponse>>();
        Assert.NotNull(routedSupplierTasks);
        Assert.Contains(routedSupplierTasks!, item => item.FinancingRequestId == createdSupplierFinancingRequest.Id && item.TaskCode == "WAIT_FOR_PARTNER_OFFERS");

        await _client.AuthenticateAsFinanceMakerAsync();

        var createReceivablesProductProfileResponse = await _client.PostAsJsonAsync("/api/v1/islamic-finance/product-profiles", new CreateIslamicFinanceProductProfileRequest
        {
            ProductType = "RECEIVABLES_FINANCE",
            ProductCode = "HTTP_PORTAL_REC",
            ProductName = "HTTP Portal Receivables",
            RequiresShariahReview = false,
            AllowsPartnerFunding = true,
            AllowsCashLineFunding = true
        });
        Assert.Equal(HttpStatusCode.OK, createReceivablesProductProfileResponse.StatusCode);
        var createdReceivablesProductProfile = await createReceivablesProductProfileResponse.Content.ReadFromJsonAsync<IslamicFinanceProductProfileResponse>();
        Assert.NotNull(createdReceivablesProductProfile);

        var submitReceivablesProductProfileResponse = await _client.PostAsync($"/api/v1/islamic-finance/product-profiles/{createdReceivablesProductProfile!.Id}/submit", null);
        Assert.Equal(HttpStatusCode.OK, submitReceivablesProductProfileResponse.StatusCode);

        await _client.AuthenticateAsFinanceCheckerAsync();

        var approveReceivablesProductProfileResponse = await _client.PostAsync($"/api/v1/islamic-finance/product-profiles/{createdReceivablesProductProfile.Id}/approve", null);
        Assert.Equal(HttpStatusCode.OK, approveReceivablesProductProfileResponse.StatusCode);

        var activateReceivablesProductProfileResponse = await _client.PostAsync($"/api/v1/islamic-finance/product-profiles/{createdReceivablesProductProfile.Id}/activate", null);
        Assert.Equal(HttpStatusCode.OK, activateReceivablesProductProfileResponse.StatusCode);

        await _client.AuthenticateAsCustomerAsync();

        var createReceivablesFinancingRequestResponse = await _client.PostAsJsonAsync("/api/v1/external/parties/2/financing/requests", new CreateExternalFinancingApplicationRequest
        {
            RequestNumber = "HTTP-CUS-REC-0001",
            ProductProfileId = createdReceivablesProductProfile.Id,
            FundingSourceMode = "PARTNER",
            SourceDocumentType = "AR_INVOICE",
            SourceDocumentId = createdCustomerInvoice.AccountsReceivableInvoiceId,
            TransactionCurrencyCode = "EGP",
            RequestedAmount = createdCustomerInvoice.TotalAmount
        });
        Assert.Equal(HttpStatusCode.OK, createReceivablesFinancingRequestResponse.StatusCode);
        var createdReceivablesFinancingRequest = await createReceivablesFinancingRequestResponse.Content.ReadFromJsonAsync<IslamicFinanceFinancingRequestResponse>();
        Assert.NotNull(createdReceivablesFinancingRequest);

        var submitReceivablesFinancingRequestResponse = await _client.PostAsync($"/api/v1/external/parties/2/financing/requests/{createdReceivablesFinancingRequest!.Id}/submit", null);
        Assert.Equal(HttpStatusCode.OK, submitReceivablesFinancingRequestResponse.StatusCode);

        await _client.AuthenticateAsFinanceCheckerAsync();

        var approveReceivablesFinancingRequestResponse = await _client.PostAsync($"/api/v1/islamic-finance/requests/{createdReceivablesFinancingRequest.Id}/approve", null);
        Assert.Equal(HttpStatusCode.OK, approveReceivablesFinancingRequestResponse.StatusCode);

        var createReceivablesOfferDecisionResponse = await _client.PostAsJsonAsync($"/api/v1/islamic-finance/requests/{createdReceivablesFinancingRequest.Id}/decisions", new CreateIslamicFinanceDecisionRequest
        {
            DecisionCode = "APPROVED",
            DecisionNotes = "Receivables-finance offer available for portal comparison.",
            DecidingPartyId = 2,
            PartnerLenderId = createdPartnerLender.Id,
            OfferProductTypeCode = "RECEIVABLES_FINANCE",
            OfferFundingSourceMode = "PARTNER",
            OfferCurrencyCode = "EGP",
            OfferedAmount = createdCustomerInvoice.TotalAmount * 0.85m,
            TenorMonths = 6,
            ProfitRatePercent = 8.25m,
            ProcessingFeeAmount = 175m,
            SecurityRequirementText = "Invoice assignment and collection undertaking.",
            OfferRank = 1
        });
        Assert.Equal(HttpStatusCode.OK, createReceivablesOfferDecisionResponse.StatusCode);
        var receivablesOfferDecision = await createReceivablesOfferDecisionResponse.Content.ReadFromJsonAsync<IslamicFinanceDecisionResponse>();
        Assert.NotNull(receivablesOfferDecision);

        var submitReceivablesOfferDecisionResponse = await _client.PostAsync($"/api/v1/islamic-finance/decisions/{receivablesOfferDecision!.Id}/submit", null);
        Assert.Equal(HttpStatusCode.OK, submitReceivablesOfferDecisionResponse.StatusCode);

        var approveReceivablesOfferDecisionResponse = await _client.PostAsync($"/api/v1/islamic-finance/decisions/{receivablesOfferDecision.Id}/approve", null);
        Assert.Equal(HttpStatusCode.OK, approveReceivablesOfferDecisionResponse.StatusCode);

        await _client.AuthenticateAsCustomerAsync();

        var acceptReceivablesOfferResponse = await _client.PostAsJsonAsync($"/api/v1/external/parties/2/financing/requests/{createdReceivablesFinancingRequest.Id}/accept-offer", new AcceptExternalFinancingOfferRequest(receivablesOfferDecision.Id));
        Assert.Equal(HttpStatusCode.OK, acceptReceivablesOfferResponse.StatusCode);

        var receivablesNotificationsResponse = await _client.GetAsync($"/api/v1/external/parties/2/financing/requests/{createdReceivablesFinancingRequest.Id}/notifications");
        Assert.Equal(HttpStatusCode.OK, receivablesNotificationsResponse.StatusCode);
        var receivablesNotifications = await receivablesNotificationsResponse.Content.ReadFromJsonAsync<List<ExternalFinancingNotificationResponse>>();
        Assert.NotNull(receivablesNotifications);
        Assert.Contains(receivablesNotifications!, item => item.TemplateCode == "NTTMP-000002");
        Assert.Contains(receivablesNotifications!, item => item.TemplateCode == "NTTMP-000004");

        await _client.AuthenticateAsFinanceCheckerAsync();

        var officerWorkbenchResponse = await _client.GetAsync("/api/v1/islamic-finance/officer-workbench");
        Assert.Equal(HttpStatusCode.OK, officerWorkbenchResponse.StatusCode);
        var officerWorkbench = await officerWorkbenchResponse.Content.ReadFromJsonAsync<IslamicFinanceOfficerWorkbenchResponse>();
        Assert.NotNull(officerWorkbench);
        Assert.Contains(officerWorkbench!.Items, item => item.FinancingRequestId == createdReceivablesFinancingRequest.Id
            && item.AttentionStatusCode == "BACKOFFICE_ACTION_REQUIRED"
            && item.SlaStatusCode == "ON_TRACK"
            && item.SlaDueAtUtc.HasValue);

        var partnerOrchestrationResponse = await _client.GetAsync($"/api/v1/islamic-finance/requests/{createdReceivablesFinancingRequest.Id}/partner-orchestration");
        Assert.Equal(HttpStatusCode.OK, partnerOrchestrationResponse.StatusCode);
        var partnerOrchestration = await partnerOrchestrationResponse.Content.ReadFromJsonAsync<IslamicFinancePartnerOrchestrationResponse>();
        Assert.NotNull(partnerOrchestration);
        Assert.Equal(createdReceivablesFinancingRequest.Id, partnerOrchestration!.FinancingRequestId);
        Assert.Equal("OFFER_SELECTED", partnerOrchestration.OrchestrationStageCode);
        Assert.Equal("ADVANCE_EXECUTION_WORKFLOW", partnerOrchestration.NextInternalActionCode);
        Assert.Contains(partnerOrchestration.CandidatePartners, item => item.PartnerLenderId == createdPartnerLender.Id && item.HasApprovedOffer);

        var executionWorkbenchResponse = await _client.GetAsync("/api/v1/islamic-finance/execution-workbench");
        Assert.Equal(HttpStatusCode.OK, executionWorkbenchResponse.StatusCode);
        var executionWorkbench = await executionWorkbenchResponse.Content.ReadFromJsonAsync<IslamicFinanceExecutionWorkbenchResponse>();
        Assert.NotNull(executionWorkbench);
        Assert.Contains(executionWorkbench!.Items, item => item.FinancingRequestId == createdReceivablesFinancingRequest.Id
            && item.ExecutionStageCode == "OFFER_SELECTED"
            && item.PendingExecutionActionCode == "START_EXECUTION_CASE");

        await _client.AuthenticateAsFinanceMakerAsync();

        var createReceivablesCaseResponse = await _client.PostAsJsonAsync("/api/v1/islamic-finance/receivables-cases", new CreateIslamicFinanceReceivablesCaseRequest
        {
            CaseNumber = "HTTP-REC-CASE-0001",
            FinancingRequestId = createdReceivablesFinancingRequest.Id,
            Lines =
            [
                new CreateIslamicFinanceReceivablesCaseLineRequest
                {
                    AccountsReceivableInvoiceId = createdCustomerInvoice.AccountsReceivableInvoiceId,
                    FinancedAmount = createdCustomerInvoice.TotalAmount * 0.85m
                }
            ]
        });
        Assert.Equal(HttpStatusCode.OK, createReceivablesCaseResponse.StatusCode);
        var createdReceivablesCase = await createReceivablesCaseResponse.Content.ReadFromJsonAsync<IslamicFinanceReceivablesCaseResponse>();
        Assert.NotNull(createdReceivablesCase);

        await _client.AuthenticateAsCustomerAsync();

        var receivablesCasesResponse = await _client.GetAsync("/api/v1/external/parties/2/financing/receivables-cases");
        Assert.Equal(HttpStatusCode.OK, receivablesCasesResponse.StatusCode);
        var externalReceivablesCases = await receivablesCasesResponse.Content.ReadFromJsonAsync<List<IslamicFinanceReceivablesCaseResponse>>();
        Assert.NotNull(externalReceivablesCases);
        Assert.Contains(externalReceivablesCases!, item => item.Id == createdReceivablesCase!.Id && item.FinancingRequestId == createdReceivablesFinancingRequest.Id);

        var receivablesCaseDetailResponse = await _client.GetAsync($"/api/v1/external/parties/2/financing/receivables-cases/{createdReceivablesCase.Id}");
        Assert.Equal(HttpStatusCode.OK, receivablesCaseDetailResponse.StatusCode);
        var receivablesCaseDetail = await receivablesCaseDetailResponse.Content.ReadFromJsonAsync<IslamicFinanceReceivablesCaseResponse>();
        Assert.NotNull(receivablesCaseDetail);
        Assert.Equal(createdReceivablesCase.CaseNumber, receivablesCaseDetail!.CaseNumber);
        Assert.NotEmpty(receivablesCaseDetail.Lines);

        var receivablesOfferComparisonResponse = await _client.GetAsync($"/api/v1/external/parties/2/financing/requests/{createdReceivablesFinancingRequest.Id}/offers");
        Assert.Equal(HttpStatusCode.OK, receivablesOfferComparisonResponse.StatusCode);
        var receivablesOfferComparison = await receivablesOfferComparisonResponse.Content.ReadFromJsonAsync<List<ExternalFinancingOfferResponse>>();
        Assert.NotNull(receivablesOfferComparison);
        Assert.Contains(receivablesOfferComparison!, item => item.ProductTypeCode == "RECEIVABLES_FINANCE" && item.FinancingDecisionId == receivablesOfferDecision.Id);

        var receivablesJourneyResponse = await _client.GetAsync($"/api/v1/external/parties/2/financing/requests/{createdReceivablesFinancingRequest.Id}/journey-summary");
        Assert.Equal(HttpStatusCode.OK, receivablesJourneyResponse.StatusCode);
        var receivablesJourney = await receivablesJourneyResponse.Content.ReadFromJsonAsync<ExternalFinancingJourneySummaryResponse>();
        Assert.NotNull(receivablesJourney);
        Assert.Equal("TRACK_RECEIVABLES_COLLECTION", receivablesJourney!.NextExternalActionCode);
        Assert.Equal("RECEIVABLES_CASE", receivablesJourney.ExecutionStageCode);
        Assert.Equal(createdReceivablesCase.Id, receivablesJourney.ReceivablesCaseId);

        var disbursementsResponse = await _client.GetAsync("/api/v1/external/parties/2/financing/disbursements");
        Assert.Equal(HttpStatusCode.OK, disbursementsResponse.StatusCode);
        var externalDisbursements = await disbursementsResponse.Content.ReadFromJsonAsync<List<IslamicFinanceMurabahaDisbursementResponse>>();
        Assert.NotNull(externalDisbursements);
        if (externalDisbursements!.Count > 0)
        {
            var disbursementDetailResponse = await _client.GetAsync($"/api/v1/external/parties/2/financing/disbursements/{externalDisbursements[0].Id}");
            Assert.Equal(HttpStatusCode.OK, disbursementDetailResponse.StatusCode);
            var disbursementDetail = await disbursementDetailResponse.Content.ReadFromJsonAsync<IslamicFinanceMurabahaDisbursementResponse>();
            Assert.NotNull(disbursementDetail);
            Assert.Equal(externalDisbursements[0].DisbursementNumber, disbursementDetail!.DisbursementNumber);
        }

        var settlementsResponse = await _client.GetAsync("/api/v1/external/parties/2/financing/settlements");
        Assert.Equal(HttpStatusCode.OK, settlementsResponse.StatusCode);
        var externalSettlements = await settlementsResponse.Content.ReadFromJsonAsync<List<IslamicFinanceSettlementResponse>>();
        Assert.NotNull(externalSettlements);
        if (externalSettlements!.Count > 0)
        {
            var settlementDetailResponse = await _client.GetAsync($"/api/v1/external/parties/2/financing/settlements/{externalSettlements[0].Id}");
            Assert.Equal(HttpStatusCode.OK, settlementDetailResponse.StatusCode);
            var settlementDetail = await settlementDetailResponse.Content.ReadFromJsonAsync<IslamicFinanceSettlementResponse>();
            Assert.NotNull(settlementDetail);
            Assert.Equal(externalSettlements[0].SettlementNumber, settlementDetail!.SettlementNumber);
            Assert.NotEmpty(settlementDetail.Lines);
        }
    }

    private async Task<CashLineERP.Contracts.Integration.IntegrationEndpointResponse> CreateAndActivateEndpointAsync(string endpointName, string providerCode, string directionCode, string relativePath)
    {
        await _client.AuthenticateAsFinanceMakerAsync();

        var createResponse = await _client.PostAsJsonAsync("/api/v1/integrations/endpoints", new CashLineERP.Contracts.Integration.CreateIntegrationEndpointRequest(
            EndpointName: endpointName,
            IntegrationProviderCode: providerCode,
            EnvironmentCode: "UAT",
            DirectionCode: directionCode,
            TransportCode: "REST",
            HttpMethodCode: "POST",
            BaseUrl: "https://gateway.uat.example",
            RelativePath: relativePath,
            AuthenticationModeCode: "SIGNATURE",
            CredentialReference: $"secret://{providerCode.ToLowerInvariant()}/uat/key",
            TimeoutSeconds: 20,
            RetryPolicyCode: "STANDARD",
            MaxRetryCount: 2,
            IsIdempotencyKeyRequired: true,
            Notes: "External portal HTTP QA payment endpoint"));
        Assert.Equal(HttpStatusCode.OK, createResponse.StatusCode);
        var created = await createResponse.Content.ReadFromJsonAsync<CashLineERP.Contracts.Integration.IntegrationEndpointResponse>();
        Assert.NotNull(created);

        Assert.Equal(HttpStatusCode.OK, (await _client.PostAsync($"/api/v1/integrations/endpoints/{created!.IntegrationEndpointId}/submit", null)).StatusCode);

        await _client.AuthenticateAsFinanceCheckerAsync();
        Assert.Equal(HttpStatusCode.OK, (await _client.PostAsync($"/api/v1/integrations/endpoints/{created.IntegrationEndpointId}/approve", null)).StatusCode);
        var activateResponse = await _client.PostAsync($"/api/v1/integrations/endpoints/{created.IntegrationEndpointId}/activate", null);
        Assert.Equal(HttpStatusCode.OK, activateResponse.StatusCode);
        var activated = await activateResponse.Content.ReadFromJsonAsync<CashLineERP.Contracts.Integration.IntegrationEndpointResponse>();
        Assert.NotNull(activated);
        return activated!;
    }

    private async Task<PaymentChannelConfigurationResponse> CreateAndActivateCollectionChannelAsync(
        CashLineERP.Contracts.Integration.IntegrationEndpointResponse outbound,
        CashLineERP.Contracts.Integration.IntegrationEndpointResponse inbound)
    {
        await _client.AuthenticateAsFinanceMakerAsync();

        var createResponse = await _client.PostAsJsonAsync("/api/v1/finance/payment-channels", new CreatePaymentChannelConfigurationRequest(
            ChannelName: "HTTP Paymob customer collection channel",
            BranchId: 1,
            IntegrationProviderCode: "PAYMOB",
            ChannelTypeCode: "CHECKOUT_LINK",
            UsageCode: "CUSTOMER_COLLECTION",
            CurrencyCode: "EGP",
            OutboundIntegrationEndpointId: outbound.IntegrationEndpointId,
            InboundIntegrationEndpointId: inbound.IntegrationEndpointId,
            SupportsCardTokenReferences: false,
            UsesWalletRuleEngine: false,
            RequiresCustomerReference: true,
            MinimumAmount: 1m,
            MaximumAmount: 5000m,
            SettlementLeadDays: 1,
            Notes: "External portal HTTP QA collection channel"));
        Assert.Equal(HttpStatusCode.OK, createResponse.StatusCode);
        var created = await createResponse.Content.ReadFromJsonAsync<PaymentChannelConfigurationResponse>();
        Assert.NotNull(created);

        Assert.Equal(HttpStatusCode.OK, (await _client.PostAsync($"/api/v1/finance/payment-channels/{created!.PaymentChannelConfigurationId}/submit", null)).StatusCode);

        await _client.AuthenticateAsFinanceCheckerAsync();
        Assert.Equal(HttpStatusCode.OK, (await _client.PostAsync($"/api/v1/finance/payment-channels/{created.PaymentChannelConfigurationId}/approve", null)).StatusCode);
        var activateResponse = await _client.PostAsync($"/api/v1/finance/payment-channels/{created.PaymentChannelConfigurationId}/activate", null);
        Assert.Equal(HttpStatusCode.OK, activateResponse.StatusCode);
        var activated = await activateResponse.Content.ReadFromJsonAsync<PaymentChannelConfigurationResponse>();
        Assert.NotNull(activated);
        return activated!;
    }
}
