using CashLineERP.Application.External;
using CashLineERP.Application.Customers;
using CashLineERP.Application.Finance;
using CashLineERP.Application.Integration;
using CashLineERP.Application.IslamicFinance.ProductProfiles;
using CashLineERP.Application.IslamicFinance.PartnerLenders;
using CashLineERP.Application.IslamicFinance.Disbursements;
using CashLineERP.Application.IslamicFinance.ReceivablesFinance;
using CashLineERP.Application.IslamicFinance.Requests;
using CashLineERP.Application.IslamicFinance.Settlements;
using CashLineERP.Application.Notifications;
using CashLineERP.Application.Parties;
using CashLineERP.Application.Sales;
using CashLineERP.Application.Suppliers;
using CashLineERP.Contracts.External;
using CashLineERP.Contracts.Customers;
using CashLineERP.Contracts.Finance;
using CashLineERP.Contracts.IslamicFinance;
using CashLineERP.Contracts.Parties;
using CashLineERP.Contracts.Sales;
using CashLineERP.Contracts.Suppliers;
using CashLineERP.Infrastructure.Persistence.Repositories;
using CashLineERP.Infrastructure.Persistence.Repositories.IslamicFinance;

namespace CashLineERP.Api.Tests;

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

        var payablePaymentService = new AccountsPayablePaymentService(new AccountsPayablePaymentRepository(dbContext));
        var invoiceService = new AccountsReceivableInvoiceService(new AccountsReceivableInvoiceRepository(dbContext));
        var receiptService = new AccountsReceivableReceiptService(new AccountsReceivableReceiptRepository(dbContext));
        var supplierStatementService = new SupplierStatementService(new SupplierStatementRepository(dbContext));
        var customerStatementService = new CustomerStatementService(new CustomerStatementRepository(dbContext));
        var supplierProfileService = new SupplierProfileService(new SupplierProfileRepository(dbContext));
        var customerProfileService = new CustomerProfileService(new CustomerProfileRepository(dbContext));
        var partyOnboardingService = new PartyOnboardingService(new BusinessPartyRepository(dbContext));
        var integrationService = new IntegrationEndpointRegistryService(new IntegrationEndpointRegistryRepository(dbContext));
        var paymentChannelService = new PaymentChannelConfigurationService(new PaymentChannelConfigurationRepository(dbContext));
        var productService = new IslamicFinanceProductService(new IslamicFinanceProductRepository(dbContext));
        var partnerService = new IslamicFinancePartnerService(new IslamicFinancePartnerRepository(dbContext));
        var notificationTemplateService = new NotificationTemplateService(new NotificationTemplateRepository(dbContext));
        var notificationOrchestrationService = new NotificationOrchestrationService(new NotificationOrchestrationRepository(dbContext));
        var paymentGatewayExecutionService = new PaymentGatewayExecutionService(new PaymentGatewayExecutionRepository(dbContext));
        var salesOrderService = new SalesOrderService(new SalesOrderRepository(dbContext));
        var islamicFinanceRequestService = new IslamicFinanceRequestService(
            new IslamicFinanceRequestRepository(dbContext),
            notificationTemplateService,
            notificationOrchestrationService);
        var receivablesFinanceService = new ReceivablesFinanceService(new ReceivablesFinanceRepository(dbContext));
        var disbursementService = new IslamicFinanceMurabahaDisbursementService(new IslamicFinanceMurabahaDisbursementRepository(dbContext));
        var settlementService = new IslamicFinanceSettlementService(new IslamicFinanceSettlementRepository(dbContext));
        var externalPortalService = new ExternalPortalService(
            new ExternalPortalRepository(dbContext),
            supplierProfileService,
            customerProfileService,
            partyOnboardingService,
            salesOrderService,
            productService,
            islamicFinanceRequestService,
            receivablesFinanceService,
            disbursementService,
            settlementService,
            notificationTemplateService,
            notificationOrchestrationService,
            paymentGatewayExecutionService);

        var createdPayment = payablePaymentService.CreatePayment(new CreateAccountsPayablePaymentRequest(
            SupplierId: 1,
            PaymentDate: new DateOnly(2026, 4, 8),
            PaymentMethod: "BANK_TRANSFER",
            CurrencyCode: "EGP",
            AmountAmount: 1000m,
            ReferenceNumber: "SUP-PORTAL-PAY-001",
            Notes: "Supplier portal payment",
            Allocations:
            [
                new CreateAccountsPayablePaymentAllocationRequest(1, 1000m, new DateOnly(2026, 4, 8))
            ]));
        payablePaymentService.SubmitPayment(createdPayment.AccountsPayablePaymentId, 3);
        payablePaymentService.ApprovePayment(createdPayment.AccountsPayablePaymentId, 4);
        payablePaymentService.PostPayment(createdPayment.AccountsPayablePaymentId, 4);

        var supplierStatement = supplierStatementService.GenerateStatement(4, new CreateSupplierStatementRequest(
            SupplierId: 1,
            DateFrom: new DateOnly(2026, 4, 1),
            DateTo: new DateOnly(2026, 4, 30),
            CurrencyCode: "EGP"));
        supplierStatementService.RecordDelivery(supplierStatement.SupplierStatementId, 4, new RecordSupplierStatementDeliveryRequest(
            DeliveredAtUtc: DateTime.UtcNow,
            ChannelCode: "EMAIL",
            RecipientAddress: "supplier@example.com",
            DeliveryStatusCode: "DELIVERED",
            Notes: "Supplier statement delivery for external QA"));

        var postedCustomerInvoice = AccountsReceivableWorkflowTestHelper.SubmitApproveAndPostInvoice(
            invoiceService,
            invoiceService.CreateInvoice(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")
                ])).AccountsReceivableInvoiceId);
        var postedCustomerReceiptAmount = decimal.Round(postedCustomerInvoice.TotalAmount * 0.10m, 2, MidpointRounding.AwayFromZero);

        var postedCustomerReceipt = AccountsReceivableWorkflowTestHelper.SubmitApproveAndPostReceipt(
            receiptService,
            receiptService.CreateReceipt(new CreateAccountsReceivableReceiptRequest(
                CustomerId: 2,
                ReceiptDate: new DateOnly(2026, 4, 10),
                ReceiptMethod: "BANK_TRANSFER",
                CurrencyCode: "EGP",
                AmountAmount: postedCustomerReceiptAmount,
                ReferenceNumber: "CUS-PORTAL-RCPT-0001",
                Notes: "Customer portal receipt",
                Allocations:
                [
                    new CreateAccountsReceivableReceiptAllocationRequest(postedCustomerInvoice.AccountsReceivableInvoiceId, postedCustomerReceiptAmount, new DateOnly(2026, 4, 10))
                ])).AccountsReceivableReceiptId);

        var supplierQuotations = externalPortalService.GetQuotations(1);
        Assert.Contains(supplierQuotations, item => item.QuotationNumber == "QTN-000001");

        var supplierRfqs = externalPortalService.GetRfqInvitations(1);
        Assert.Contains(supplierRfqs, item => item.RfqNumber == "RFQ-000001");

        var supplierRfqDetail = externalPortalService.GetRfqInvitation(1, 1);
        Assert.NotNull(supplierRfqDetail);
        Assert.NotEmpty(supplierRfqDetail!.Lines);

        var acceptedRfq = externalPortalService.RespondToRfqInvitation(1, 5, 1, new RespondExternalRfqInvitationRequest(
            "ACCEPTED",
            null));
        Assert.Equal("ACCEPTED", acceptedRfq.InviteStatusCode);

        var createdSupplierQuotation = externalPortalService.CreateQuotation(1, 5, 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 service QA",
            Lines: supplierRfqDetail.Lines.Select(line => new CreateExternalSupplierQuotationLineRequest(
                line.RfqLineId,
                line.ItemId,
                line.RequestedQuantity,
                line.UnitOfMeasureCode,
                line.TargetUnitPrice ?? 30m,
                0m,
                0m,
                line.TaxCode,
                5)).ToArray()));
        Assert.Equal(1, createdSupplierQuotation.SupplierId);
        Assert.Equal(supplierRfqDetail.Lines.Count, createdSupplierQuotation.Lines.Count);

        var submittedSupplierQuotation = externalPortalService.SubmitQuotation(1, createdSupplierQuotation.SupplierQuotationId, 5);
        Assert.Equal("SUBMITTED", submittedSupplierQuotation.StatusCode);

        var quotationDetail = externalPortalService.GetQuotation(1, createdSupplierQuotation.SupplierQuotationId);
        Assert.NotNull(quotationDetail);
        Assert.Equal(createdSupplierQuotation.SupplierQuotationId, quotationDetail!.SupplierQuotationId);

        var supplierOrders = externalPortalService.GetOrders(1);
        Assert.Contains(supplierOrders, item => item.OrderType == "PURCHASE_ORDER" && item.OrderNumber == "PO-000001");

        var supplierPurchaseOrders = externalPortalService.GetPurchaseOrders(1);
        Assert.Contains(supplierPurchaseOrders, item => item.PurchaseOrderNumber == "PO-000001");

        var raisedPurchaseOrderIssue = externalPortalService.RaisePurchaseOrderIssue(1, 1, 5, new RaiseExternalPurchaseOrderIssueRequest(
            IssueCategoryCode: "DELIVERY",
            IssueNotes: "Supplier needs a confirmed delivery schedule before acknowledgment."));
        Assert.Equal("ISSUE_RAISED", raisedPurchaseOrderIssue.AcknowledgmentStatusCode);
        Assert.Contains("DELIVERY", raisedPurchaseOrderIssue.AcknowledgmentNotes);

        var acknowledgedPurchaseOrder = externalPortalService.AcknowledgePurchaseOrder(1, 1, 5, new AcknowledgeExternalPurchaseOrderRequest(
            AcknowledgmentStatusCode: "ACKNOWLEDGED",
            Notes: "Acknowledged from supplier service QA"));
        Assert.Equal("ACKNOWLEDGED", acknowledgedPurchaseOrder.AcknowledgmentStatusCode);

        var supplierInvoices = externalPortalService.GetInvoices(1);
        Assert.Contains(supplierInvoices, item => item.InvoiceNumber == "BILL-000001" && item.OpenAmount == 1992.5m);

        var supplierPayments = externalPortalService.GetPayments(1);
        Assert.Contains(supplierPayments, item => item.PaymentId == createdPayment.AccountsPayablePaymentId && item.Amount == 1000m);

        var supplierSummary = externalPortalService.GetStatementSummary(1);
        Assert.Equal("SUPPLIER", supplierSummary.PartyType);
        Assert.True(supplierSummary.QuotationCount >= 1);
        Assert.True(supplierSummary.OrderCount >= 1);
        Assert.True(supplierSummary.InvoiceCount >= 1);
        Assert.True(supplierSummary.PaymentCount >= 1);
        Assert.Equal(1992.5m, supplierSummary.OpenInvoiceAmount);
        Assert.Equal(1992.5m, supplierSummary.StatementBalanceAmount);

        var supplierStatementLines = externalPortalService.GetStatementLines(1);
        Assert.Contains(supplierStatementLines, item => item.DocumentType == "INVOICE" && item.DocumentNumber == "BILL-000001");
        Assert.Contains(supplierStatementLines, item => item.DocumentType == "AP_PAYMENT");

        var supplierStatementDocuments = externalPortalService.GetStatementDocuments(1);
        Assert.Contains(supplierStatementDocuments, item => item.StatementType == "SUPPLIER_STATEMENT");

        var supplierStatementDetail = externalPortalService.GetStatementDetail(1, supplierStatement.SupplierStatementId);
        Assert.NotNull(supplierStatementDetail);
        Assert.Equal(supplierStatement.StatementNumber, supplierStatementDetail!.StatementNumber);
        Assert.NotEmpty(supplierStatementDetail.Lines);
        Assert.Contains(supplierStatementDetail.DeliveryLogs, item => item.ChannelCode == "EMAIL");

        var supplierDeliveryLogs = externalPortalService.GetStatementDeliveryLogs(1, supplierStatement.SupplierStatementId);
        Assert.Contains(supplierDeliveryLogs, item => item.ChannelCode == "EMAIL");

        var supplierFinancingCases = externalPortalService.GetMurabahaCases(1);
        Assert.NotNull(supplierFinancingCases);

        var createdSupplierProfile = externalPortalService.CreateSupplierProfile(1, new CreateSupplierProfileRequest(
            1,
            null,
            "STRATEGIC_VENDOR",
            "EGP",
            "BANK_TRANSFER",
            30,
            7,
            2500m,
            "Banque Misr",
            "1234567890098765",
            "BMISEGCX",
            "External onboarding profile"));
        Assert.Equal(1, createdSupplierProfile.BusinessPartyId);

        var submittedSupplierProfile = externalPortalService.SubmitSupplierProfile(1, 5);
        Assert.Equal("SUBMITTED", submittedSupplierProfile.StatusCode);

        var supplierProfile = externalPortalService.GetSupplierProfile(1);
        Assert.NotNull(supplierProfile);
        Assert.Equal(createdSupplierProfile.SupplierProfileCode, supplierProfile!.SupplierProfileCode);

        var supplierDocumentWorkflow = externalPortalService.CreateDocumentWorkflow(1, 5, new CreateExternalDocumentWorkflowRequest(
            "COMMERCIAL_REGISTER",
            "supplier-commercial-register.pdf",
            "managed://supplier/commercial-register-v1.pdf",
            "application/pdf",
            4096,
            "Initial supplier onboarding evidence"));
        Assert.Equal("DRAFT", supplierDocumentWorkflow.StatusCode);

        var submittedSupplierDocumentWorkflow = externalPortalService.SubmitDocumentWorkflow(1, supplierDocumentWorkflow.WorkflowId, 5);
        Assert.Equal("SUBMITTED", submittedSupplierDocumentWorkflow.StatusCode);

        var approvedSupplierDocumentWorkflow = externalPortalService.ApproveDocumentWorkflow(
            submittedSupplierDocumentWorkflow.WorkflowId,
            3,
            new ReviewExternalDocumentWorkflowRequest("Approved for supplier onboarding."));
        Assert.Equal("APPROVED", approvedSupplierDocumentWorkflow.StatusCode);

        var customerQuotations = externalPortalService.GetQuotations(2);
        Assert.Empty(customerQuotations);

        var createdCustomerOrder = externalPortalService.CreateCustomerOrder(2, 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(2, createdCustomerOrder.CustomerId);
        Assert.Equal("DRAFT", createdCustomerOrder.StatusCode);

        var submittedCustomerOrder = externalPortalService.SubmitCustomerOrder(2, createdCustomerOrder.SalesOrderId, 6);
        Assert.Equal("SUBMITTED", submittedCustomerOrder.StatusCode);

        var customerOrders = externalPortalService.GetOrders(2);
        Assert.Contains(customerOrders, item => item.OrderType == "SALES_ORDER" && item.OrderNumber == "SO-000001");
        Assert.Contains(customerOrders, item => item.OrderId == createdCustomerOrder.SalesOrderId && item.StatusCode == "SUBMITTED");

        var customerInvoices = externalPortalService.GetInvoices(2);
        var expectedCustomerOpenAmount = postedCustomerInvoice.TotalAmount - postedCustomerReceiptAmount;
        Assert.Contains(customerInvoices, item => item.InvoiceNumber == postedCustomerInvoice.InvoiceNumber && item.OpenAmount == expectedCustomerOpenAmount);

        var customerPayments = externalPortalService.GetPayments(2);
        Assert.Contains(customerPayments, item => item.PaymentType == "AR_RECEIPT" && item.PaymentNumber == postedCustomerReceipt.ReceiptNumber);

        var collectionOutbound = CreateAndActivateEndpoint(integrationService, "Paymob collection outbound", "PAYMOB", "OUTBOUND", "/checkout", 3, 4);
        var collectionInbound = CreateAndActivateEndpoint(integrationService, "Paymob collection callback", "PAYMOB", "INBOUND", "/checkout-callback", 3, 4);
        CreateAndActivateCollectionChannel(paymentChannelService, collectionOutbound.IntegrationEndpointId, collectionInbound.IntegrationEndpointId, 3, 4);

        var createdCustomerPayment = externalPortalService.CreateCustomerPayment(2, 6, new CreateExternalCustomerPaymentRequest(
            AccountsReceivableInvoiceId: postedCustomerInvoice.AccountsReceivableInvoiceId,
            IntegrationProviderCode: "PAYMOB",
            CurrencyCode: "EGP",
            AmountAmount: expectedCustomerOpenAmount,
            PaymentDate: new DateOnly(2026, 4, 10),
            ReferenceNumber: "CUS-PORTAL-GW-0001",
            Notes: "Customer initiated a gateway payment request from the service QA path."));
        Assert.Equal("CUSTOMER_PAYMENT_REQUEST", createdCustomerPayment.PaymentType);
        Assert.Equal("PENDING_CUSTOMER_ACTION", createdCustomerPayment.StatusCode);

        customerPayments = externalPortalService.GetPayments(2);
        Assert.Contains(customerPayments, item => item.PaymentType == "CUSTOMER_PAYMENT_REQUEST" && item.PaymentNumber == createdCustomerPayment.PaymentNumber);

        var customerStatement = customerStatementService.GenerateStatement(4, new CreateCustomerStatementRequest(
            CustomerId: 2,
            DateFrom: new DateOnly(2026, 4, 1),
            DateTo: new DateOnly(2026, 4, 30),
            CurrencyCode: "EGP"));
        customerStatementService.RecordDelivery(customerStatement.CustomerStatementId, 4, new RecordCustomerStatementDeliveryRequest(
            DeliveredAtUtc: DateTime.UtcNow,
            ChannelCode: "EMAIL",
            RecipientAddress: "customer@example.com",
            DeliveryStatusCode: "DELIVERED",
            Notes: "Customer statement delivery for external QA"));

        var customerSummary = externalPortalService.GetStatementSummary(2);
        Assert.Equal("CUSTOMER", customerSummary.PartyType);
        Assert.True(customerSummary.OrderCount >= 1);
        Assert.True(customerSummary.InvoiceCount >= 1);
        Assert.True(customerSummary.PaymentCount >= 1);
        Assert.Equal(expectedCustomerOpenAmount, customerSummary.OpenInvoiceAmount);
        Assert.Equal(expectedCustomerOpenAmount, customerSummary.StatementBalanceAmount);

        var customerStatementLines = externalPortalService.GetStatementLines(2);
        Assert.Contains(customerStatementLines, item => item.DocumentType == postedCustomerInvoice.InvoiceType && item.DocumentNumber == postedCustomerInvoice.InvoiceNumber);
        Assert.Contains(customerStatementLines, item => item.DocumentType == "AR_RECEIPT" && item.DocumentNumber == postedCustomerReceipt.ReceiptNumber);

        var customerDeliveries = externalPortalService.GetCustomerDeliveries(2);
        Assert.Contains(customerDeliveries, item => item.DispatchNumber == "DSP-000001");

        var customerStatementDocuments = externalPortalService.GetStatementDocuments(2);
        Assert.Contains(customerStatementDocuments, item => item.StatementType == "CUSTOMER_STATEMENT");

        var customerStatementDetail = externalPortalService.GetStatementDetail(2, customerStatement.CustomerStatementId);
        Assert.NotNull(customerStatementDetail);
        Assert.Equal(customerStatement.StatementNumber, customerStatementDetail!.StatementNumber);
        Assert.NotEmpty(customerStatementDetail.Lines);
        Assert.Contains(customerStatementDetail.DeliveryLogs, item => item.ChannelCode == "EMAIL");

        var customerDeliveryLogs = externalPortalService.GetStatementDeliveryLogs(2, customerStatement.CustomerStatementId);
        Assert.Contains(customerDeliveryLogs, item => item.ChannelCode == "EMAIL");

        var customerFinancingRequests = externalPortalService.GetFinancingRequests(2);
        Assert.NotNull(customerFinancingRequests);

        var productProfile = productService.CreateProductProfile(new CashLineERP.Contracts.IslamicFinance.CreateIslamicFinanceProductProfileRequest
        {
            ProductType = "MURABAHA",
            ProductCode = "PORTAL_MURABAHA",
            ProductName = "Portal Murabaha",
            RequiresShariahReview = true,
            AllowsPartnerFunding = true,
            AllowsCashLineFunding = false
        });
        productProfile = productService.SubmitProductProfile(productProfile.Id, 3);
        productProfile = productService.ApproveProductProfile(productProfile.Id, 4);
        productProfile = productService.ActivateProductProfile(productProfile.Id, 4);

        var tawarruqProduct = productService.CreateProductProfile(new CreateIslamicFinanceProductProfileRequest
        {
            ProductType = "TAWARRUQ",
            ProductCode = "PORTAL_TAWARRUQ",
            ProductName = "Portal Tawarruq",
            RequiresShariahReview = true,
            AllowsPartnerFunding = true,
            AllowsCashLineFunding = true
        });
        tawarruqProduct = productService.SubmitProductProfile(tawarruqProduct.Id, 3);
        tawarruqProduct = productService.ApproveProductProfile(tawarruqProduct.Id, 4);
        tawarruqProduct = productService.ActivateProductProfile(tawarruqProduct.Id, 4);

        var financingProducts = externalPortalService.GetFinancingProducts(2);
        Assert.Contains(financingProducts, item => item.ProductType == "MURABAHA" && item.Id == productProfile.Id && item.IsActive);
        Assert.Contains(financingProducts, item => item.ProductType == "TAWARRUQ" && item.Id == tawarruqProduct.Id && item.IsActive);
        var financingFamilies = externalPortalService.GetFinancingProductFamilies(2);
        Assert.Contains(financingFamilies, item => item.ProductTypeCode == "MURABAHA" && item.FundingReadinessCode == "PARTNER_READY");
        Assert.Contains(financingFamilies, item => item.ProductTypeCode == "TAWARRUQ" && item.FutureReadinessCode == "MICROFINANCE_READY");

        var createdCustomerFinancingRequest = externalPortalService.CreateFinancingRequest(2, new CreateExternalFinancingApplicationRequest
        {
            RequestNumber = "PORTAL-CUS-0001",
            ApplicantPartyTypeCode = "CUSTOMER",
            ProductProfileId = productProfile.Id,
            FacilityId = null,
            FundingSourceMode = "PARTNER",
            SourceDocumentType = "SALES_ORDER",
            SourceDocumentId = createdCustomerOrder.SalesOrderId,
            TransactionCurrencyCode = "EGP",
            RequestedAmount = 62000m
        });
        Assert.Equal(2, createdCustomerFinancingRequest.CustomerPartyId);
        Assert.Equal(2, createdCustomerFinancingRequest.ApplicantPartyId);
        Assert.Equal("CUSTOMER", createdCustomerFinancingRequest.ApplicantPartyTypeCode);
        Assert.Equal("DRAFT", createdCustomerFinancingRequest.StatusCode);

        var submittedCustomerFinancingRequest = externalPortalService.SubmitFinancingRequest(2, createdCustomerFinancingRequest.Id, 6);
        Assert.Equal("SUBMITTED", submittedCustomerFinancingRequest.StatusCode);

        var returnedCustomerDocumentWorkflow = externalPortalService.ReturnDocumentWorkflow(
            externalPortalService.SubmitDocumentWorkflow(2, externalPortalService.CreateDocumentWorkflow(2, 6, new CreateExternalDocumentWorkflowRequest(
                "VAT_CERTIFICATE",
                "customer-vat-v1.pdf",
                "managed://customer/customer-vat-v1.pdf",
                "application/pdf",
                2048,
                "Initial customer VAT certificate")).WorkflowId, 6).WorkflowId,
            3,
            new ReviewExternalDocumentWorkflowRequest("Please upload the renewed VAT certificate."));
        Assert.Equal("RETURNED", returnedCustomerDocumentWorkflow.StatusCode);

        var replacedCustomerDocumentWorkflow = externalPortalService.ReplaceDocumentWorkflow(2, returnedCustomerDocumentWorkflow.WorkflowId, 6, new ReplaceExternalDocumentWorkflowRequest(
            "customer-vat-v2.pdf",
            "managed://customer/customer-vat-v2.pdf",
            "application/pdf",
            3072,
            "Updated with renewed VAT certificate",
            "Renewed document"));
        Assert.Equal(2, replacedCustomerDocumentWorkflow.VersionNumber);
        Assert.Equal("DRAFT", replacedCustomerDocumentWorkflow.StatusCode);

        var customerServiceRequest = externalPortalService.CreateCustomerServiceRequest(2, 6, new CreateExternalCustomerServiceRequestRequest(
            "DELIVERY_DISPUTE",
            "Delivery status needs clarification",
            "The customer wants clarification on the delayed dispatch status.",
            "HIGH",
            "DELIVERY",
            "COMMERCIAL_REVIEW",
            "COMMERCIAL",
            "SALES_ORDER",
            createdCustomerOrder.SalesOrderId));
        Assert.Equal("DRAFT", customerServiceRequest.StatusCode);
        Assert.Equal("COMMERCIAL", customerServiceRequest.AssignedBackofficeLaneCode);

        var submittedCustomerServiceRequest = externalPortalService.SubmitCustomerServiceRequest(2, customerServiceRequest.ServiceRequestId, 6);
        Assert.Equal("SUBMITTED", submittedCustomerServiceRequest.StatusCode);

        var reviewedCustomerServiceRequest = externalPortalService.StartCustomerServiceRequestReview(submittedCustomerServiceRequest.ServiceRequestId, 3);
        Assert.Equal("IN_REVIEW", reviewedCustomerServiceRequest.StatusCode);

        var respondedCustomerServiceRequest = externalPortalService.RespondToCustomerServiceRequest(
            submittedCustomerServiceRequest.ServiceRequestId,
            3,
            new ReviewExternalCustomerServiceRequest("Dispatch is scheduled and the customer will be notified automatically."));
        Assert.Equal("RESPONDED", respondedCustomerServiceRequest.StatusCode);

        var escalatedCustomerServiceRequest = externalPortalService.EscalateCustomerServiceRequest(
            2,
            submittedCustomerServiceRequest.ServiceRequestId,
            6,
            new EscalateExternalCustomerServiceRequestRequest("Customer still needs commercial escalation before closure.", "FINANCE", "CREDIT_REVIEW"));
        Assert.Equal("ESCALATED", escalatedCustomerServiceRequest.StatusCode);
        Assert.Equal("Customer still needs commercial escalation before closure.", escalatedCustomerServiceRequest.EscalationReasonText);
        Assert.Equal("FINANCE", escalatedCustomerServiceRequest.AssignedBackofficeLaneCode);
        Assert.Equal("CREDIT_REVIEW", escalatedCustomerServiceRequest.RequestedResolutionCode);
        Assert.Equal(1, escalatedCustomerServiceRequest.EscalationLevel);

        var reroutedCustomerServiceRequest = externalPortalService.RouteCustomerServiceRequest(
            submittedCustomerServiceRequest.ServiceRequestId,
            3,
            new RouteExternalCustomerServiceRequestRequest("COMMERCIAL", "COMMERCIAL_REVIEW"));
        Assert.Equal("COMMERCIAL", reroutedCustomerServiceRequest.AssignedBackofficeLaneCode);
        Assert.Equal("COMMERCIAL_REVIEW", reroutedCustomerServiceRequest.RequestedResolutionCode);

        var reviewedEscalatedCustomerServiceRequest = externalPortalService.StartCustomerServiceRequestReview(submittedCustomerServiceRequest.ServiceRequestId, 3);
        Assert.Equal("IN_REVIEW", reviewedEscalatedCustomerServiceRequest.StatusCode);

        var closedCustomerServiceRequest = externalPortalService.CloseCustomerServiceRequest(
            submittedCustomerServiceRequest.ServiceRequestId,
            3,
            new CloseExternalCustomerServiceRequest("Customer informed and follow-up closed."));
        Assert.Equal("CLOSED", closedCustomerServiceRequest.StatusCode);

        var supplierFinancingRequest = externalPortalService.CreateFinancingRequest(1, new CreateExternalFinancingApplicationRequest
        {
            RequestNumber = "PORTAL-SUP-0001",
            ApplicantPartyTypeCode = "SUPPLIER",
            ProductProfileId = productProfile.Id,
            FacilityId = null,
            FundingSourceMode = "PARTNER",
            SourceDocumentType = "PURCHASE_ORDER",
            SourceDocumentId = 1,
            TransactionCurrencyCode = "EGP",
            RequestedAmount = 48000m
        });
        Assert.Equal(1, supplierFinancingRequest.CustomerPartyId);
        Assert.Equal(1, supplierFinancingRequest.ApplicantPartyId);
        Assert.Equal("SUPPLIER", supplierFinancingRequest.ApplicantPartyTypeCode);

        var submittedSupplierFinancingRequest = externalPortalService.SubmitFinancingRequest(1, supplierFinancingRequest.Id, 5);
        Assert.Equal("SUBMITTED", submittedSupplierFinancingRequest.StatusCode);

        var activePartner = partnerService.CreatePartnerLender(new CreateIslamicFinancePartnerLenderRequest
        {
            PartnerLenderPartyId = 1,
            DefaultCurrencyCode = "EGP",
            SupportsMurabaha = true,
            SupportsReceivablesFinance = true,
            SupportsTawarruq = true
        });
        partnerService.SubmitPartnerLender(activePartner.Id, 3);
        partnerService.ApprovePartnerLender(activePartner.Id, 4);
        activePartner = partnerService.ActivatePartnerLender(activePartner.Id, 4);

        var approvedCustomerFinancingRequest = islamicFinanceRequestService.ApproveRequest(createdCustomerFinancingRequest.Id, 3);
        Assert.Equal("APPROVED", approvedCustomerFinancingRequest.StatusCode);

        var customerOfferDecision = islamicFinanceRequestService.CreateDecision(createdCustomerFinancingRequest.Id, new CreateIslamicFinanceDecisionRequest
        {
            DecisionCode = "APPROVED",
            DecisionNotes = "Customer lender offer is now available for execution selection.",
            DecidingPartyId = 2,
            PartnerLenderId = activePartner.Id,
            OfferProductTypeCode = "MURABAHA",
            OfferFundingSourceMode = "PARTNER",
            OfferCurrencyCode = "EGP",
            OfferedAmount = 61000m,
            TenorMonths = 10,
            ProfitRatePercent = 10.5m,
            ProcessingFeeAmount = 200m,
            SecurityRequirementText = "Trade-document package and customer undertaking.",
            OfferRank = 1
        });
        islamicFinanceRequestService.SubmitDecision(customerOfferDecision.Id, 3);
        islamicFinanceRequestService.ApproveDecision(customerOfferDecision.Id, 4);

        var customerOfferComparison = externalPortalService.GetFinancingOffersForRequest(2, createdCustomerFinancingRequest.Id);
        Assert.Single(customerOfferComparison);
        Assert.Equal(customerOfferDecision.Id, customerOfferComparison.Single().FinancingDecisionId);

        var customerJourneyBeforeSelection = externalPortalService.GetFinancingJourneySummary(2, createdCustomerFinancingRequest.Id);
        Assert.NotNull(customerJourneyBeforeSelection);
        Assert.Equal("COMPARE_AND_SELECT_OFFER", customerJourneyBeforeSelection!.NextExternalActionCode);
        Assert.Equal("OFFER_COMPARISON", customerJourneyBeforeSelection.ExecutionStageCode);
        Assert.Equal("MURABAHA", customerJourneyBeforeSelection.ProductFamilyCode);

        var acceptedCustomerOffer = externalPortalService.AcceptFinancingOffer(
            2,
            createdCustomerFinancingRequest.Id,
            6,
            new AcceptExternalFinancingOfferRequest(customerOfferDecision.Id));
        Assert.Equal(activePartner.Id, acceptedCustomerOffer.AssignedPartnerLenderId);
        Assert.Equal(customerOfferDecision.Id, acceptedCustomerOffer.SelectedFinancingDecisionId);

        var customerJourneyAfterSelection = externalPortalService.GetFinancingJourneySummary(2, createdCustomerFinancingRequest.Id);
        Assert.NotNull(customerJourneyAfterSelection);
        Assert.Equal("AWAIT_EXECUTION_CASE", customerJourneyAfterSelection!.NextExternalActionCode);
        Assert.Equal("OFFER_SELECTED", customerJourneyAfterSelection.ExecutionStageCode);
        Assert.Equal("PARTNER_LENDER", customerJourneyAfterSelection.ProviderModelCode);

        var customerFinancingNotifications = externalPortalService.GetFinancingNotifications(2, createdCustomerFinancingRequest.Id);
        Assert.True(customerFinancingNotifications.Count >= 2);
        Assert.Contains(customerFinancingNotifications, item => item.TemplateCode == "NTTMP-000002" && item.StatusCode == "PENDING");
        Assert.Contains(customerFinancingNotifications, item => item.TemplateCode == "NTTMP-000004" && item.StatusCode == "PENDING");
        var customerFinancingTasks = externalPortalService.GetFinancingTasks(2);
        Assert.Contains(customerFinancingTasks, item => item.FinancingRequestId == createdCustomerFinancingRequest.Id && item.TaskCode == "WAIT_FOR_EXECUTION_START");
        Assert.Contains(customerFinancingTasks, item => item.FinancingRequestId == createdCustomerFinancingRequest.Id && item.TaskCode == "REVIEW_FINANCING_UPDATES");

        var approvedSupplierFinancingRequest = islamicFinanceRequestService.ApproveRequest(supplierFinancingRequest.Id, 3);
        Assert.Equal("APPROVED", approvedSupplierFinancingRequest.StatusCode);

        var routedSupplierOrchestration = islamicFinanceRequestService.RoutePartnerLenders(supplierFinancingRequest.Id, 4);
        Assert.Equal("PARTNER_ASSIGNED", routedSupplierOrchestration.OrchestrationStageCode);
        Assert.Equal("COLLECT_PARTNER_OFFERS", routedSupplierOrchestration.NextInternalActionCode);
        Assert.Equal(activePartner.Id, routedSupplierOrchestration.AssignedPartnerLenderId);
        Assert.True(routedSupplierOrchestration.OfficerNotificationCount >= 1);

        var routedQueueItems = notificationOrchestrationService.GetQueueItems();
        Assert.Contains(routedQueueItems, item => item.TemplateCode == "NTTMP-000006" && item.RecipientReference == $"PARTNER_LENDER:{activePartner.Id}" && item.RelatedEntityId == supplierFinancingRequest.Id);
        Assert.Contains(routedQueueItems, item => item.TemplateCode == "NTTMP-000007" && item.RecipientReference == "ROLE:ISLAMIC_FINANCE_OFFICER" && item.RelatedEntityId == supplierFinancingRequest.Id);

        var supplierRoutingTasks = externalPortalService.GetFinancingTasks(1);
        Assert.Contains(supplierRoutingTasks, item => item.FinancingRequestId == supplierFinancingRequest.Id && item.TaskCode == "WAIT_FOR_PARTNER_OFFERS");

        var supplierOfferDecision = islamicFinanceRequestService.CreateDecision(supplierFinancingRequest.Id, new CreateIslamicFinanceDecisionRequest
        {
            DecisionCode = "APPROVED",
            DecisionNotes = "Supplier lender offer is now available for comparison.",
            DecidingPartyId = 1,
            PartnerLenderId = activePartner.Id,
            OfferProductTypeCode = "MURABAHA",
            OfferFundingSourceMode = "PARTNER",
            OfferCurrencyCode = "EGP",
            OfferedAmount = 47000m,
            TenorMonths = 12,
            ProfitRatePercent = 11.25m,
            ProcessingFeeAmount = 350m,
            SecurityRequirementText = "PO assignment and supplier undertaking.",
            OfferRank = 1
        });
        islamicFinanceRequestService.SubmitDecision(supplierOfferDecision.Id, 3);
        islamicFinanceRequestService.ApproveDecision(supplierOfferDecision.Id, 4);

        var supplierFinancingRequests = externalPortalService.GetFinancingRequests(1);
        Assert.Contains(supplierFinancingRequests, item => item.Id == supplierFinancingRequest.Id);
        var supplierFinancingRequestDetail = externalPortalService.GetFinancingRequest(1, supplierFinancingRequest.Id);
        Assert.NotNull(supplierFinancingRequestDetail);
        Assert.Equal(supplierFinancingRequest.RequestNumber, supplierFinancingRequestDetail!.RequestNumber);

        var financingOffers = externalPortalService.GetFinancingOffers(1);
        Assert.Contains(financingOffers, item => item.FinancingRequestId == supplierFinancingRequest.Id && item.PartnerLenderId == activePartner.Id && !item.IsSelectedOffer);
        Assert.Contains(financingOffers, item => item.FinancingDecisionId == supplierOfferDecision.Id && item.ProductTypeCode == "MURABAHA" && item.OfferedAmount == 47000m);
        Assert.All(financingOffers, item => Assert.False(string.IsNullOrWhiteSpace(item.FinancingRequestNumber)));

        var acceptedSupplierOffer = externalPortalService.AcceptFinancingOffer(
            1,
            supplierFinancingRequest.Id,
            5,
            new AcceptExternalFinancingOfferRequest(supplierOfferDecision.Id));
        Assert.Equal(activePartner.Id, acceptedSupplierOffer.AssignedPartnerLenderId);
        Assert.Equal(supplierOfferDecision.Id, acceptedSupplierOffer.SelectedFinancingDecisionId);

        var selectedFinancingOffers = externalPortalService.GetFinancingOffers(1)
            .Where(item => item.FinancingRequestId == supplierFinancingRequest.Id
                && item.PartnerLenderId == activePartner.Id
                && item.IsSelectedOffer)
            .ToArray();
        Assert.NotEmpty(selectedFinancingOffers);

        var officerWorkbench = islamicFinanceRequestService.GetOfficerWorkbench();
        Assert.Contains(officerWorkbench.Items, item => item.FinancingRequestId == supplierFinancingRequest.Id
            && item.ApplicantPartyTypeCode == "SUPPLIER"
            && item.SelectedFinancingDecisionId == supplierOfferDecision.Id
            && item.SelectedPartnerLenderId == activePartner.Id
            && item.PendingActionCode == "ADVANCE_EXECUTION_WORKFLOW"
            && item.AttentionStatusCode == "BACKOFFICE_ACTION_REQUIRED"
            && item.SlaStatusCode == "ON_TRACK"
            && item.SlaDueAtUtc.HasValue);
        var supplierPartnerOrchestration = islamicFinanceRequestService.GetPartnerOrchestration(supplierFinancingRequest.Id);
        Assert.NotNull(supplierPartnerOrchestration);
        Assert.Equal("OFFER_SELECTED", supplierPartnerOrchestration!.OrchestrationStageCode);
        Assert.Equal("ADVANCE_EXECUTION_WORKFLOW", supplierPartnerOrchestration.NextInternalActionCode);
        Assert.Contains(supplierPartnerOrchestration.CandidatePartners, item => item.PartnerLenderId == activePartner.Id && item.HasApprovedOffer && item.IsSelectedOffer);

        var executionWorkbench = islamicFinanceRequestService.GetExecutionWorkbench();
        Assert.Contains(executionWorkbench.Items, item => item.FinancingRequestId == supplierFinancingRequest.Id
            && item.ExecutionStageCode == "OFFER_SELECTED"
            && item.PendingExecutionActionCode == "START_EXECUTION_CASE"
            && item.SelectedPartnerLenderId == activePartner.Id
            && item.PartnerNotificationCount >= 1);

        var receivablesProduct = productService.CreateProductProfile(new CreateIslamicFinanceProductProfileRequest
        {
            ProductType = "RECEIVABLES_FINANCE",
            ProductCode = "REC-SVC-001",
            ProductName = "Receivables Finance Service QA",
            RequiresShariahReview = false,
            AllowsPartnerFunding = true,
            AllowsCashLineFunding = true
        });
        receivablesProduct = productService.SubmitProductProfile(receivablesProduct.Id, 3);
        receivablesProduct = productService.ApproveProductProfile(receivablesProduct.Id, 4);
        receivablesProduct = productService.ActivateProductProfile(receivablesProduct.Id, 4);

        var receivablesFinancingRequest = externalPortalService.CreateFinancingRequest(2, new CreateExternalFinancingApplicationRequest
        {
            RequestNumber = "PORTAL-CUS-REC-0001",
            ApplicantPartyTypeCode = "CUSTOMER",
            ProductProfileId = receivablesProduct.Id,
            FundingSourceMode = "PARTNER",
            SourceDocumentType = "AR_INVOICE",
            SourceDocumentId = postedCustomerInvoice.AccountsReceivableInvoiceId,
            TransactionCurrencyCode = "EGP",
            RequestedAmount = postedCustomerInvoice.TotalAmount
        });
        islamicFinanceRequestService.SubmitRequest(receivablesFinancingRequest.Id, 6);
        islamicFinanceRequestService.ApproveRequest(receivablesFinancingRequest.Id, 3);
        var receivablesOfferDecision = islamicFinanceRequestService.CreateDecision(receivablesFinancingRequest.Id, new CreateIslamicFinanceDecisionRequest
        {
            DecisionCode = "APPROVED",
            DecisionNotes = "Receivables-finance offer ready for customer comparison.",
            DecidingPartyId = 2,
            PartnerLenderId = activePartner.Id,
            OfferProductTypeCode = "RECEIVABLES_FINANCE",
            OfferFundingSourceMode = "PARTNER",
            OfferCurrencyCode = "EGP",
            OfferedAmount = postedCustomerInvoice.TotalAmount * 0.9m,
            TenorMonths = 6,
            ProfitRatePercent = 9.5m,
            ProcessingFeeAmount = 150m,
            SecurityRequirementText = "Invoice assignment and collection undertaking.",
            OfferRank = 1
        });
        islamicFinanceRequestService.SubmitDecision(receivablesOfferDecision.Id, 3);
        islamicFinanceRequestService.ApproveDecision(receivablesOfferDecision.Id, 4);
        var selectedReceivablesOffer = externalPortalService.AcceptFinancingOffer(2, receivablesFinancingRequest.Id, 6, new AcceptExternalFinancingOfferRequest(receivablesOfferDecision.Id));
        Assert.Equal(receivablesOfferDecision.Id, selectedReceivablesOffer.SelectedFinancingDecisionId);

        var receivablesCase = receivablesFinanceService.CreateCase(new CreateIslamicFinanceReceivablesCaseRequest
        {
            CaseNumber = "REC-CASE-0001",
            FinancingRequestId = receivablesFinancingRequest.Id,
            Lines =
            [
                new CreateIslamicFinanceReceivablesCaseLineRequest
                {
                    AccountsReceivableInvoiceId = postedCustomerInvoice.AccountsReceivableInvoiceId,
                    FinancedAmount = postedCustomerInvoice.TotalAmount * 0.9m
                }
            ]
        });
        Assert.Equal("DRAFT", receivablesCase.StatusCode);

        var externalReceivablesCases = externalPortalService.GetReceivablesCases(2);
        Assert.Contains(externalReceivablesCases, item => item.Id == receivablesCase.Id && item.FinancingRequestId == receivablesFinancingRequest.Id);
        var externalReceivablesCaseDetail = externalPortalService.GetReceivablesCase(2, receivablesCase.Id);
        Assert.NotNull(externalReceivablesCaseDetail);
        Assert.Equal(receivablesCase.CaseNumber, externalReceivablesCaseDetail!.CaseNumber);
        Assert.NotEmpty(externalReceivablesCaseDetail.Lines);
        Assert.Contains(externalReceivablesCaseDetail.Lines, item => item.AccountsReceivableInvoiceId == postedCustomerInvoice.AccountsReceivableInvoiceId);

        var receivablesOfferComparison = externalPortalService.GetFinancingOffersForRequest(2, receivablesFinancingRequest.Id);
        Assert.True(receivablesOfferComparison.Count >= 1);
        Assert.Contains(receivablesOfferComparison, item => item.ProductTypeCode == "RECEIVABLES_FINANCE" && item.FinancingDecisionId == receivablesOfferDecision.Id);

        var receivablesJourney = externalPortalService.GetFinancingJourneySummary(2, receivablesFinancingRequest.Id);
        Assert.NotNull(receivablesJourney);
        Assert.Equal("TRACK_RECEIVABLES_COLLECTION", receivablesJourney!.NextExternalActionCode);
        Assert.Equal("RECEIVABLES_CASE", receivablesJourney.ExecutionStageCode);
        Assert.Equal(receivablesCase.Id, receivablesJourney.ReceivablesCaseId);
        Assert.Equal("MICROFINANCE_READY", receivablesJourney.FutureReadinessCode);
        var receivablesTasks = externalPortalService.GetFinancingTasks(2);
        Assert.Contains(receivablesTasks, item => item.FinancingRequestId == receivablesFinancingRequest.Id && item.TaskCode == "TRACK_RECEIVABLES_CASE");

        var externalDisbursements = externalPortalService.GetMurabahaDisbursements(2);
        var firstDisbursement = externalDisbursements.FirstOrDefault();
        if (firstDisbursement is not null)
        {
            var externalDisbursementDetail = externalPortalService.GetMurabahaDisbursement(2, firstDisbursement.Id);
            Assert.NotNull(externalDisbursementDetail);
            Assert.Equal(firstDisbursement.DisbursementNumber, externalDisbursementDetail!.DisbursementNumber);
        }

        var externalSettlements = externalPortalService.GetSettlements(2);
        var firstSettlement = externalSettlements.FirstOrDefault();
        if (firstSettlement is not null)
        {
            var externalSettlementDetail = externalPortalService.GetSettlement(2, firstSettlement.Id);
            Assert.NotNull(externalSettlementDetail);
            Assert.Equal(firstSettlement.SettlementNumber, externalSettlementDetail!.SettlementNumber);
            Assert.NotEmpty(externalSettlementDetail.Lines);
        }

        var createdCustomerProfile = externalPortalService.CreateCustomerProfile(2, new CreateCustomerProfileRequest(
            2,
            null,
            "COMPANY",
            "ENTERPRISE",
            "EGP",
            "DIRECT_SALES",
            "STANDARD",
            "EMAIL",
            "External customer onboarding"));
        Assert.Equal(2, createdCustomerProfile.BusinessPartyId);

        var submittedCustomerProfile = externalPortalService.SubmitCustomerProfile(2, 6);
        Assert.Equal("SUBMITTED", submittedCustomerProfile.StatusCode);

        var customerProfile = externalPortalService.GetCustomerProfile(2);
        Assert.NotNull(customerProfile);
        Assert.Equal(createdCustomerProfile.CustomerProfileCode, customerProfile!.CustomerProfileCode);

        partyOnboardingService.RecordComplianceDocument(6, 2, new RecordBusinessPartyComplianceDocumentRequest(
            "VAT_CERTIFICATE",
            "customer-vat.pdf",
            "managed://customer/customer-vat.pdf",
            "application/pdf",
            2048));

        var customerStatusTracking = externalPortalService.GetCustomerStatusTracking(2);
        Assert.Equal(2, customerStatusTracking.PartyId);
        Assert.Equal(createdCustomerProfile.CustomerProfileId, customerStatusTracking.CustomerProfileId);
        Assert.True(customerStatusTracking.OrderCount >= 1);
        Assert.True(customerStatusTracking.DeliveryCount >= 1);

        var customerDocuments = externalPortalService.GetCustomerDocuments(2);
        Assert.Contains(customerDocuments, item => item.DocumentSourceType == "COMPLIANCE_DOCUMENT");
        Assert.Contains(customerDocuments, item => item.DocumentSourceType == "STATEMENT_DOCUMENT");

        var customerServiceRequests = externalPortalService.GetCustomerServiceRequests(2);
        Assert.Contains(customerServiceRequests, item => item.ServiceRequestId == customerServiceRequest.ServiceRequestId && item.StatusCode == "CLOSED");

        var customerDocumentWorkflows = externalPortalService.GetDocumentWorkflows(2);
        Assert.Contains(customerDocumentWorkflows, item => item.WorkflowId == replacedCustomerDocumentWorkflow.WorkflowId);
    }

    private static CashLineERP.Contracts.Integration.IntegrationEndpointResponse CreateAndActivateEndpoint(
        IntegrationEndpointRegistryService integrationService,
        string endpointName,
        string providerCode,
        string directionCode,
        string relativePath,
        long makerUserId,
        long checkerUserId)
    {
        var created = integrationService.CreateIntegrationEndpoint(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 service QA payment endpoint"));
        integrationService.SubmitIntegrationEndpoint(created.IntegrationEndpointId, makerUserId);
        integrationService.ApproveIntegrationEndpoint(created.IntegrationEndpointId, checkerUserId);
        return integrationService.ActivateIntegrationEndpoint(created.IntegrationEndpointId, checkerUserId);
    }

    private static PaymentChannelConfigurationResponse CreateAndActivateCollectionChannel(
        PaymentChannelConfigurationService paymentChannelService,
        long outboundEndpointId,
        long inboundEndpointId,
        long makerUserId,
        long checkerUserId)
    {
        var created = paymentChannelService.CreatePaymentChannel(new CreatePaymentChannelConfigurationRequest(
            ChannelName: "Paymob customer collection channel",
            BranchId: 1,
            IntegrationProviderCode: "PAYMOB",
            ChannelTypeCode: "CHECKOUT_LINK",
            UsageCode: "CUSTOMER_COLLECTION",
            CurrencyCode: "EGP",
            OutboundIntegrationEndpointId: outboundEndpointId,
            InboundIntegrationEndpointId: inboundEndpointId,
            SupportsCardTokenReferences: false,
            UsesWalletRuleEngine: false,
            RequiresCustomerReference: true,
            MinimumAmount: 1m,
            MaximumAmount: 5000m,
            SettlementLeadDays: 1,
            Notes: "External portal service QA collection channel"));
        paymentChannelService.SubmitPaymentChannel(created.PaymentChannelConfigurationId, makerUserId);
        paymentChannelService.ApprovePaymentChannel(created.PaymentChannelConfigurationId, checkerUserId);
        return paymentChannelService.ActivatePaymentChannel(created.PaymentChannelConfigurationId, checkerUserId);
    }
}
