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

namespace CashLineERP.Api.Tests;

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

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

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

        var createResponse = await _client.PostAsJsonAsync("/api/v1/inventory/transfers", new CreateWarehouseTransferRequest(
            BranchId: 1,
            FromWarehouseId: 1,
            ToWarehouseId: 2,
            TransferDate: new DateOnly(2026, 5, 15),
            ReasonCode: "REPLENISHMENT",
            Notes: "HTTP warehouse transfer flow.",
            Lines:
            [
                new CreateWarehouseTransferLineRequest(1001, 101, 201, 5m, "EA", 24m, "AVAILABLE", "HTTP-TRF-1001-A", null, "Move to destination warehouse")
            ]));

        Assert.True(createResponse.IsSuccessStatusCode, await createResponse.Content.ReadAsStringAsync());
        var created = await createResponse.Content.ReadFromJsonAsync<WarehouseTransferResponse>();
        Assert.NotNull(created);

        var submitResponse = await _client.PostAsync($"/api/v1/inventory/transfers/{created!.WarehouseTransferId}/submit", null);
        Assert.True(submitResponse.IsSuccessStatusCode, await submitResponse.Content.ReadAsStringAsync());

        await _client.AuthenticateAsFinanceCheckerAsync();

        var approveResponse = await _client.PostAsync($"/api/v1/inventory/transfers/{created.WarehouseTransferId}/approve", null);
        Assert.True(approveResponse.IsSuccessStatusCode, await approveResponse.Content.ReadAsStringAsync());

        var postResponse = await _client.PostAsync($"/api/v1/inventory/transfers/{created.WarehouseTransferId}/post", null);
        Assert.True(postResponse.IsSuccessStatusCode, await postResponse.Content.ReadAsStringAsync());
        var posted = await postResponse.Content.ReadFromJsonAsync<WarehouseTransferResponse>();
        Assert.NotNull(posted);
        Assert.Equal("POSTED", posted!.StatusCode);

        var getResponse = await _client.GetAsync($"/api/v1/inventory/transfers/{created.WarehouseTransferId}");
        Assert.True(getResponse.IsSuccessStatusCode, await getResponse.Content.ReadAsStringAsync());

        var movementResponse = await _client.GetAsync("/api/v1/inventory/movements");
        Assert.True(movementResponse.IsSuccessStatusCode, await movementResponse.Content.ReadAsStringAsync());
        var movements = await movementResponse.Content.ReadFromJsonAsync<List<InventoryMovementResponse>>();
        Assert.NotNull(movements);
        Assert.Contains(movements!, movement =>
            movement.MovementType == "WAREHOUSE_TRANSFER" &&
            movement.FromWarehouseId == 1 &&
            movement.ToWarehouseId == 2 &&
            movement.QuantityMoved == 5m);
    }
}
