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

namespace CashLineERP.Api.Tests;

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

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

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

        var overviewResponse = await _client.GetAsync("/api/v1/admin/setup/overview");
        Assert.Equal(HttpStatusCode.OK, overviewResponse.StatusCode);
        var overview = await overviewResponse.Content.ReadFromJsonAsync<MasterDataGovernanceOverviewResponse>();
        Assert.NotNull(overview);
        Assert.True(overview!.TotalEntries >= 5);

        var createResponse = await _client.PostAsJsonAsync("/api/v1/admin/setup/reference-data", new CreateReferenceDataEntryRequest(
            ReferenceTypeCode: "UNIT_OF_MEASURE",
            ReferenceCode: "BOX",
            ReferenceName: "Box",
            LocalizedName: "صندوق",
            DescriptionText: "Packaging UOM for warehouse shipping.",
            AttributesJson: "{\"precision\":0,\"group\":\"PACKAGING\"}",
            EffectiveFrom: new DateOnly(2026, 5, 1),
            EffectiveTo: null));
        Assert.Equal(HttpStatusCode.OK, createResponse.StatusCode);

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

        var submitResponse = await _client.PostAsync($"/api/v1/admin/setup/reference-data/{createdEntry.ReferenceDataEntryId}/submit", null);
        Assert.Equal(HttpStatusCode.OK, submitResponse.StatusCode);

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

        await _client.AuthenticateAsFinanceCheckerAsync();

        var approveResponse = await _client.PostAsync($"/api/v1/admin/setup/reference-data/{createdEntry.ReferenceDataEntryId}/approve", null);
        Assert.Equal(HttpStatusCode.OK, approveResponse.StatusCode);

        var activateResponse = await _client.PostAsync($"/api/v1/admin/setup/reference-data/{createdEntry.ReferenceDataEntryId}/activate", null);
        Assert.Equal(HttpStatusCode.OK, activateResponse.StatusCode);
        var activatedEntry = await activateResponse.Content.ReadFromJsonAsync<ReferenceDataEntryResponse>();
        Assert.NotNull(activatedEntry);
        Assert.True(activatedEntry!.IsActive);

        await _client.AuthenticateAsInternalAsync();

        var activeListResponse = await _client.GetAsync("/api/v1/admin/setup/reference-data?referenceTypeCode=UNIT_OF_MEASURE&activeOnly=true");
        Assert.Equal(HttpStatusCode.OK, activeListResponse.StatusCode);
        var activeEntries = await activeListResponse.Content.ReadFromJsonAsync<ReferenceDataEntryResponse[]>();
        Assert.NotNull(activeEntries);
        Assert.Contains(activeEntries!, item => item.ReferenceCode == "BOX" && item.IsActive);
    }
}
