using System.Linq;
using System.Net;
using System.Net.Http.Json;
using NeonSprawl.Server.Game.Combat;
using Xunit;

namespace NeonSprawl.Server.Tests.Game.Combat;

public class AbilityDefinitionsWorldApiTests
{
    /// <summary>Frozen prototype four in registry id order (ordinal). Keep in sync with Bruno.</summary>
    public static readonly string[] FrozenFourInIdOrder =
    [
        "prototype_burst",
        "prototype_dash",
        "prototype_guard",
        "prototype_pulse",
    ];

    [Fact]
    public async Task GetAbilityDefinitions_ShouldReturnSchemaV1_WithFrozenFourInIdOrder()
    {
        // Arrange
        await using var factory = new InMemoryWebApplicationFactory();
        var client = factory.CreateClient();
        // Act
        var response = await client.GetAsync("/game/world/ability-definitions");
        // Assert
        Assert.Equal(HttpStatusCode.OK, response.StatusCode);
        var body = await response.Content.ReadFromJsonAsync<AbilityDefinitionsListResponse>();
        Assert.NotNull(body);
        Assert.Equal(AbilityDefinitionsListResponse.CurrentSchemaVersion, body!.SchemaVersion);
        Assert.NotNull(body.Abilities);
        Assert.Equal(4, body.Abilities.Count);
        var ids = body.Abilities.Select(static a => a.Id).ToList();
        Assert.Equal(FrozenFourInIdOrder, ids);

        var pulse = body.Abilities.Single(a => a.Id == "prototype_pulse");
        Assert.Equal("Prototype Pulse", pulse.DisplayName);
        Assert.Equal(25, pulse.BaseDamage);
        Assert.Equal(3.0, pulse.CooldownSeconds);
        Assert.Equal("attack", pulse.AbilityKind);

        var burst = body.Abilities.Single(a => a.Id == "prototype_burst");
        Assert.Equal("Prototype Burst", burst.DisplayName);
        Assert.Equal(40, burst.BaseDamage);
        Assert.Equal(5.0, burst.CooldownSeconds);
        Assert.Equal("attack", burst.AbilityKind);

        var guard = body.Abilities.Single(a => a.Id == "prototype_guard");
        Assert.Equal("utility", guard.AbilityKind);
        Assert.Equal(0, guard.BaseDamage);
        Assert.Equal(6.0, guard.CooldownSeconds);

        var dash = body.Abilities.Single(a => a.Id == "prototype_dash");
        Assert.Equal("movement", dash.AbilityKind);
        Assert.Equal(0, dash.BaseDamage);
        Assert.Equal(4.0, dash.CooldownSeconds);
    }
}
