using System.Net;
using System.Net.Http.Json;
using FluentAssertions;
using Microsoft.Extensions.DependencyInjection;

[Collection("Integration")]
public class GatewayRegistryTests : IAsyncLifetime
{
    private readonly ApiFixture _fixture;
    private readonly HttpClient _client;
    private Guid _siteId;
    private Guid _gatewayId;

    public GatewayRegistryTests(ApiFixture fixture)
    {
        _fixture = fixture;
        _client = fixture.CreateClient();
    }

    public async Task InitializeAsync()
    {
        _client.AsAdmin();
        using var scope = _fixture.Services.CreateScope();
        var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
        await DbResetHelper.ResetAsync(db);
        await GatewayRegistrySeeder.SeedAsync(db);
        _siteId = GatewayRegistrySeeder.DemoSiteId;
        _gatewayId = GatewayRegistrySeeder.DemoGatewayId;
    }

    public Task DisposeAsync() => Task.CompletedTask;

    [Fact]
    public async Task RegisterGateway_UnderSite_Returns201()
    {
        var resp = await _client.PostAsJsonAsync(
            $"/api/v1/sites/{_siteId}/gateways",
            new { gatewayCode = "GW-ICU-1A", department = "ICU" });
        resp.StatusCode.Should().Be(HttpStatusCode.Created);
        var body = await resp.Content.ReadFromJsonAsync<ApiResponse<WardGatewayResponse>>();
        body!.Data!.GatewayCode.Should().Be("GW-ICU-1A");
    }

    [Fact]
    public async Task Heartbeat_UpdatesStatusAndBufferDepth()
    {
        _client.WithGatewayApiKey(_gatewayId);
        var resp = await _client.PatchAsJsonAsync(
            $"/api/v1/gateways/{_gatewayId}/heartbeat",
            new { status = "ONLINE", bufferDepth = 42, reportedAtUtc = DateTimeOffset.UtcNow });
        resp.StatusCode.Should().Be(HttpStatusCode.OK);

        _client.AsAdmin();
        var get = await _client.GetAsync($"/api/v1/gateways/{_gatewayId}");
        var body = await get.Content.ReadFromJsonAsync<ApiResponse<WardGatewayResponse>>();
        body!.Data!.Status.Should().Be("ONLINE");
        body.Data.ReportedBufferDepth.Should().Be(42);
        body.Data.LastHeartbeatAt.Should().NotBeNull();
    }

    [Fact]
    public async Task Heartbeat_InvalidApiKey_Returns401()
    {
        _client.WithGatewayApiKey(_gatewayId, apiKey: "wrong-key");
        var resp = await _client.PatchAsJsonAsync(
            $"/api/v1/gateways/{_gatewayId}/heartbeat",
            new { status = "ONLINE", bufferDepth = 0, reportedAtUtc = DateTimeOffset.UtcNow });
        resp.StatusCode.Should().Be(HttpStatusCode.Unauthorized);
    }

    [Fact]
    public async Task Heartbeat_DegradedStatus_Persisted()
    {
        _client.WithGatewayApiKey(_gatewayId);
        await _client.PatchAsJsonAsync(
            $"/api/v1/gateways/{_gatewayId}/heartbeat",
            new { status = "DEGRADED", bufferDepth = 847, reportedAtUtc = DateTimeOffset.UtcNow });

        _client.AsAdmin();
        var get = await _client.GetAsync($"/api/v1/gateways/{_gatewayId}");
        var body = await get.Content.ReadFromJsonAsync<ApiResponse<WardGatewayResponse>>();
        body!.Data!.Status.Should().Be("DEGRADED");
        body.Data.ReportedBufferDepth.Should().Be(847);
    }

    [Fact]
    public async Task ListGateways_FilterByDepartment()
    {
        await _client.PostAsJsonAsync(
            $"/api/v1/sites/{_siteId}/gateways",
            new { gatewayCode = "GW-GM-8B", department = "GENERAL_MEDICINE" });

        var resp = await _client.GetAsync($"/api/v1/sites/{_siteId}/gateways?department=ICU");
        var body = await resp.Content.ReadFromJsonAsync<ApiResponse<List<WardGatewayResponse>>>();
        body!.Data.Should().OnlyContain(g => g.Department == "ICU");
    }
}