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

namespace CashLineERP.Api.Tests;

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

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

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

        var createEndpointResponse = await _client.PostAsJsonAsync("/api/v1/integrations/endpoints", new CreateIntegrationEndpointRequest(
            EndpointName: "HTTP FX Source",
            IntegrationProviderCode: "FX_SOURCE",
            EnvironmentCode: "UAT",
            DirectionCode: "INBOUND",
            TransportCode: "REST",
            HttpMethodCode: "POST",
            BaseUrl: "https://fx.http.example.com",
            RelativePath: "/quotes",
            AuthenticationModeCode: "API_KEY",
            CredentialReference: "secret://fx/http/key",
            TimeoutSeconds: 20,
            RetryPolicyCode: "STANDARD",
            MaxRetryCount: 2,
            IsIdempotencyKeyRequired: true,
            Notes: "HTTP FX source"));
        Assert.Equal(HttpStatusCode.OK, createEndpointResponse.StatusCode);
        var createdEndpoint = await createEndpointResponse.Content.ReadFromJsonAsync<IntegrationEndpointResponse>();
        Assert.NotNull(createdEndpoint);

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

        await _client.AuthenticateAsFinanceCheckerAsync();

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

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

        await _client.AuthenticateAsFinanceMakerAsync();

        var ingestResponse = await _client.PostAsJsonAsync("/api/v1/finance/fx-quotes/ingest", new IngestForeignExchangeQuotesRequest(
            IntegrationEndpointId: createdEndpoint.IntegrationEndpointId,
            QuoteDate: new DateOnly(2026, 4, 24),
            BaseCurrencyCode: "EGP",
            SourceBatchReference: "HTTP-FX-BATCH-1",
            Notes: "HTTP quote batch",
            Quotes:
            [
                new IngestForeignExchangeQuoteLineRequest("USD", 49.75m, "USD-HTTP-1", null)
            ]));
        Assert.Equal(HttpStatusCode.OK, ingestResponse.StatusCode);
        var ingestedQuotes = await ingestResponse.Content.ReadFromJsonAsync<ForeignExchangeQuoteResponse[]>();
        Assert.NotNull(ingestedQuotes);
        var ingestedQuote = Assert.Single(ingestedQuotes!);
        Assert.Equal("USD", ingestedQuote.CurrencyCode);

        var listResponse = await _client.GetAsync($"/api/v1/finance/fx-quotes?currencyCode=USD&baseCurrencyCode=EGP&integrationEndpointId={createdEndpoint.IntegrationEndpointId}");
        Assert.Equal(HttpStatusCode.OK, listResponse.StatusCode);
        var listedQuotes = await listResponse.Content.ReadFromJsonAsync<ForeignExchangeQuoteResponse[]>();
        Assert.NotNull(listedQuotes);
        Assert.Single(listedQuotes!);

        var latestResponse = await _client.GetAsync($"/api/v1/finance/fx-quotes/latest?currencyCode=USD&baseCurrencyCode=EGP&integrationEndpointId={createdEndpoint.IntegrationEndpointId}&asOfDate=2026-04-24");
        Assert.Equal(HttpStatusCode.OK, latestResponse.StatusCode);
        var latestQuote = await latestResponse.Content.ReadFromJsonAsync<ForeignExchangeQuoteResponse>();
        Assert.NotNull(latestQuote);
        Assert.Equal(49.75m, latestQuote!.RateToBase);
        Assert.Equal("FX_SOURCE", latestQuote.SourceProviderCode);
    }
}
