using System.Net;
using System.Net.Http.Json;
using CashLineERP.Contracts.Integration;
using CashLineERP.Contracts.Internal;

namespace CashLineERP.Api.Tests;

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

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

    [Fact]
    public async Task Integration_Endpoint_Registry_Endpoints_Work_End_To_End()
    {
        await _client.AuthenticateAsInternalAsync();

        var createResponse = await _client.PostAsJsonAsync("/api/v1/integrations/endpoints", new CreateIntegrationEndpointRequest(
            EndpointName: "Paymob callback UAT",
            IntegrationProviderCode: "PAYMOB",
            EnvironmentCode: "UAT",
            DirectionCode: "INBOUND",
            TransportCode: "WEBHOOK",
            HttpMethodCode: "POST",
            BaseUrl: "https://gateway.uat.paymob.example",
            RelativePath: "/callbacks/payment-status",
            AuthenticationModeCode: "SIGNATURE",
            CredentialReference: "secret://paymob/uat/signature",
            TimeoutSeconds: 25,
            RetryPolicyCode: "STANDARD",
            MaxRetryCount: 4,
            IsIdempotencyKeyRequired: true,
            Notes: "Operational callback endpoint"));
        Assert.Equal(HttpStatusCode.OK, createResponse.StatusCode);

        var createdEndpoint = await createResponse.Content.ReadFromJsonAsync<IntegrationEndpointResponse>();
        Assert.NotNull(createdEndpoint);
        Assert.Equal("DRAFT", createdEndpoint!.StatusCode);

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

        var queueResponse = await _client.GetAsync("/api/v1/internal/work-queues/approvals?moduleCode=INTEGRATION");
        Assert.Equal(HttpStatusCode.OK, queueResponse.StatusCode);
        var queueItems = await queueResponse.Content.ReadFromJsonAsync<InternalApprovalQueueItemResponse[]>();
        Assert.NotNull(queueItems);
        Assert.Contains(queueItems!, item => item.DocumentType == "INTEGRATION_ENDPOINT" && item.DocumentId == createdEndpoint.IntegrationEndpointId);

        await _client.AuthenticateAsFinanceCheckerAsync();

        var approveResponse = await _client.PostAsync($"/api/v1/integrations/endpoints/{createdEndpoint.IntegrationEndpointId}/approve", null);
        Assert.Equal(HttpStatusCode.OK, approveResponse.StatusCode);

        var activateResponse = await _client.PostAsync($"/api/v1/integrations/endpoints/{createdEndpoint.IntegrationEndpointId}/activate", null);
        Assert.Equal(HttpStatusCode.OK, activateResponse.StatusCode);

        var activatedEndpoint = await activateResponse.Content.ReadFromJsonAsync<IntegrationEndpointResponse>();
        Assert.NotNull(activatedEndpoint);
        Assert.True(activatedEndpoint!.IsActive);

        await _client.AuthenticateAsInternalAsync();

        var listResponse = await _client.GetAsync("/api/v1/integrations/endpoints?activeOnly=true&integrationProviderCode=PAYMOB&environmentCode=UAT");
        Assert.Equal(HttpStatusCode.OK, listResponse.StatusCode);
        var listedEndpoints = await listResponse.Content.ReadFromJsonAsync<IntegrationEndpointResponse[]>();
        Assert.NotNull(listedEndpoints);
        var listedEndpoint = Assert.Single(listedEndpoints!);
        Assert.Equal(createdEndpoint.IntegrationEndpointId, listedEndpoint.IntegrationEndpointId);

        var detailResponse = await _client.GetAsync($"/api/v1/integrations/endpoints/{createdEndpoint.IntegrationEndpointId}");
        Assert.Equal(HttpStatusCode.OK, detailResponse.StatusCode);
        var detailedEndpoint = await detailResponse.Content.ReadFromJsonAsync<IntegrationEndpointResponse>();
        Assert.NotNull(detailedEndpoint);
        Assert.Equal("SIGNATURE", detailedEndpoint!.AuthenticationModeCode);
        Assert.Equal("/callbacks/payment-status", detailedEndpoint.RelativePath);
    }
}
