using CashLineERP.Application.Finance;
using CashLineERP.Application.Integration;
using CashLineERP.Application.Tax;
using CashLineERP.Contracts.Finance;
using CashLineERP.Contracts.Integration;
using CashLineERP.Contracts.Tax;
using CashLineERP.Infrastructure.Persistence.Repositories;

namespace CashLineERP.Api.Tests;

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

        var integrationService = new IntegrationEndpointRegistryService(new IntegrationEndpointRegistryRepository(dbContext));
        var invoiceService = new AccountsReceivableInvoiceService(new AccountsReceivableInvoiceRepository(dbContext));
        var etaService = new EtaComplianceService(new EtaComplianceRepository(dbContext));

        CreateAndActivateEtaEndpoint(integrationService);

        var invoice = invoiceService.CreateInvoice(new CreateAccountsReceivableInvoiceRequest(
            CustomerId: 2,
            SalesOrderId: 1,
            DispatchOrderId: 1,
            InvoiceType: "TAX",
            InvoiceDate: new DateOnly(2026, 5, 5),
            TaxDate: new DateOnly(2026, 5, 5),
            DueDate: new DateOnly(2026, 5, 15),
            CurrencyCode: "EGP",
            Lines:
            [
                new CreateAccountsReceivableInvoiceLineRequest(1, 1001, 2m, "EA", 32m, "VAT14")
            ]));

        var postedInvoice = AccountsReceivableWorkflowTestHelper.SubmitApproveAndPostInvoice(invoiceService, invoice.AccountsReceivableInvoiceId);
        var submission = etaService.SubmitInvoice(postedInvoice.AccountsReceivableInvoiceId, new SubmitInvoiceToEtaRequest(4, null));

        var queued = etaService.QueueTransmission(postedInvoice.AccountsReceivableInvoiceId, submission.EtaSubmissionLogId, 4);
        Assert.Equal("QUEUED", queued.StatusCode);

        var dispatched = etaService.DispatchQueuedTransmissions(new DispatchEtaTransmissionBatchRequest("ETA_ADAPTER_WORKER", 10));
        Assert.Single(dispatched.Transmissions);

        var transmission = dispatched.Transmissions.Single();
        Assert.Equal("DISPATCHED", transmission.StatusCode);
        Assert.NotNull(transmission.SignatureText);
        Assert.NotNull(transmission.SignedPayloadText);
        Assert.NotNull(transmission.AdapterReference);

        var polled = etaService.PollDispatchedTransmissions(new PollEtaTransmissionBatchRequest("ETA_POLL_WORKER", 10));
        Assert.Single(polled.Transmissions);
        var acceptedTransmission = polled.Transmissions.Single();
        Assert.Equal("ACCEPTED", acceptedTransmission.StatusCode);
        Assert.NotNull(acceptedTransmission.PolledAtUtc);
        Assert.Equal("ETA_POLL_WORKER", acceptedTransmission.PolledByProcess);

        var submissions = etaService.GetSubmissionLogs(postedInvoice.AccountsReceivableInvoiceId);
        Assert.Contains(submissions, entry => entry.EtaSubmissionLogId == submission.EtaSubmissionLogId && entry.StatusCode == "ACCEPTED");

        var events = etaService.GetDocumentEvents(postedInvoice.AccountsReceivableInvoiceId);
        Assert.Contains(events, evt => evt.EventType == "TRANSPORT" && evt.EventStatus == "QUEUED");
        Assert.Contains(events, evt => evt.EventType == "TRANSPORT" && evt.EventStatus == "DISPATCHED");
        Assert.Contains(events, evt => evt.EventType == "POLLING" && evt.EventStatus == "ACCEPTED");
    }

    private static void CreateAndActivateEtaEndpoint(IntegrationEndpointRegistryService integrationService)
    {
        var created = integrationService.CreateIntegrationEndpoint(new CreateIntegrationEndpointRequest(
            EndpointName: "ETA outbound adapter",
            IntegrationProviderCode: "ETA",
            EnvironmentCode: "UAT",
            DirectionCode: "OUTBOUND",
            TransportCode: "REST",
            HttpMethodCode: "POST",
            BaseUrl: "https://eta.uat.example",
            RelativePath: "/documentsubmissions",
            AuthenticationModeCode: "SIGNATURE",
            CredentialReference: "secret://eta/uat/key",
            TimeoutSeconds: 20,
            RetryPolicyCode: "STANDARD",
            MaxRetryCount: 2,
            IsIdempotencyKeyRequired: true,
            Notes: "ETA transport QA endpoint"));

        integrationService.SubmitIntegrationEndpoint(created.IntegrationEndpointId, 3);
        integrationService.ApproveIntegrationEndpoint(created.IntegrationEndpointId, 4);
        integrationService.ActivateIntegrationEndpoint(created.IntegrationEndpointId, 4);
    }
}
