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

namespace NeonSprawl.Server.Tests.Game.Crafting;

public class RecipeDefinitionsWorldApiTests
{
    /// <summary>Frozen prototype eight in registry id order (ordinal). Keep in sync with manual QA and Bruno.</summary>
    public static readonly string[] FrozenEightInIdOrder =
    [
        "make_armor_quick",
        "make_contract_token",
        "make_field_stim_batch",
        "make_field_stim_mk0",
        "make_prototype_armor",
        "make_survey_drone_kit",
        "refine_scrap_efficient",
        "refine_scrap_standard",
    ];

    [Fact]
    public async Task GetRecipeDefinitions_ShouldReturnSchemaV1_WithFrozenEightInIdOrder()
    {
        // Arrange
        await using var factory = new InMemoryWebApplicationFactory();
        var client = factory.CreateClient();
        // Act
        var response = await client.GetAsync("/game/world/recipe-definitions");
        // Assert
        Assert.Equal(HttpStatusCode.OK, response.StatusCode);
        var body = await response.Content.ReadFromJsonAsync<RecipeDefinitionsListResponse>();
        Assert.NotNull(body);
        Assert.Equal(RecipeDefinitionsListResponse.CurrentSchemaVersion, body!.SchemaVersion);
        Assert.NotNull(body.Recipes);
        var ids = body.Recipes.Select(static r => r.Id).ToList();
        Assert.Equal(FrozenEightInIdOrder, ids);

        var refine = body.Recipes.Single(r => r.Id == "refine_scrap_standard");
        Assert.Equal("Refine Scrap (Standard)", refine.DisplayName);
        Assert.Equal("process", refine.RecipeKind);
        Assert.Equal("refine", refine.RequiredSkillId);
        Assert.Single(refine.Inputs);
        Assert.Equal("scrap_metal_bulk", refine.Inputs[0].ItemId);
        Assert.Equal(5, refine.Inputs[0].Quantity);
        Assert.Single(refine.Outputs);
        Assert.Equal("refined_plate_stock", refine.Outputs[0].ItemId);
        Assert.Equal(1, refine.Outputs[0].Quantity);

        var stim = body.Recipes.Single(r => r.Id == "make_field_stim_mk0");
        Assert.Equal("make", stim.RecipeKind);
        Assert.Equal(2, stim.Inputs.Count);
        Assert.Equal("refined_plate_stock", stim.Inputs[0].ItemId);
        Assert.Equal(2, stim.Inputs[0].Quantity);
        Assert.Equal("scrap_metal_bulk", stim.Inputs[1].ItemId);
        Assert.Equal(1, stim.Inputs[1].Quantity);
    }
}
