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

namespace CashLineERP.Api.Tests;

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

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

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

        var createResponse = await _client.PostAsJsonAsync("/api/v1/finance/card-token-references", new CreateCardTokenReferenceRequest(
            PartyId: 2,
            PartyTypeCode: "CUSTOMER",
            IntegrationProviderCode: "PAYMOB",
            UsageCode: "CUSTOMER_COLLECTION",
            CardBrandCode: "VISA",
            MaskedPan: "4111********1234",
            ExpiryMonth: 12,
            ExpiryYear: 2028,
            TokenReference: "tok_http_card_001",
            ExternalCustomerReference: "cust_http_001",
            IsDefault: true,
            Notes: "HTTP token baseline"));
        Assert.Equal(HttpStatusCode.OK, createResponse.StatusCode);
        var created = await createResponse.Content.ReadFromJsonAsync<CardTokenReferenceResponse>();
        Assert.NotNull(created);
        Assert.Equal("DRAFT", created!.StatusCode);

        var submitResponse = await _client.PostAsync($"/api/v1/finance/card-token-references/{created.CardTokenReferenceId}/submit", null);
        Assert.Equal(HttpStatusCode.OK, submitResponse.StatusCode);

        await _client.AuthenticateAsFinanceCheckerAsync();

        var approveResponse = await _client.PostAsync($"/api/v1/finance/card-token-references/{created.CardTokenReferenceId}/approve", null);
        Assert.Equal(HttpStatusCode.OK, approveResponse.StatusCode);

        var activateResponse = await _client.PostAsync($"/api/v1/finance/card-token-references/{created.CardTokenReferenceId}/activate", null);
        Assert.Equal(HttpStatusCode.OK, activateResponse.StatusCode);
        var activated = await activateResponse.Content.ReadFromJsonAsync<CardTokenReferenceResponse>();
        Assert.NotNull(activated);
        Assert.True(activated!.IsActive);
        Assert.True(activated.IsDefault);

        var detailResponse = await _client.GetAsync($"/api/v1/finance/card-token-references/{created.CardTokenReferenceId}");
        Assert.Equal(HttpStatusCode.OK, detailResponse.StatusCode);

        var listResponse = await _client.GetAsync("/api/v1/finance/card-token-references?activeOnly=true&partyId=2&integrationProviderCode=PAYMOB&usageCode=CUSTOMER_COLLECTION");
        Assert.Equal(HttpStatusCode.OK, listResponse.StatusCode);
        var list = await listResponse.Content.ReadFromJsonAsync<CardTokenReferenceResponse[]>();
        Assert.NotNull(list);
        Assert.Single(list!);

        var suspendResponse = await _client.PostAsJsonAsync($"/api/v1/finance/card-token-references/{created.CardTokenReferenceId}/suspend", new SuspendCardTokenReferenceRequest(
            ReasonCode: "CUSTOMER_REQUEST",
            Notes: "Customer removed card"));
        Assert.Equal(HttpStatusCode.OK, suspendResponse.StatusCode);
        var suspended = await suspendResponse.Content.ReadFromJsonAsync<CardTokenReferenceResponse>();
        Assert.NotNull(suspended);
        Assert.False(suspended!.IsActive);
        Assert.Equal("CUSTOMER_REQUEST", suspended.SuspensionReasonCode);
    }
}
