using System.Net;
using System.Net.Http.Json;
using GerbilManagerWebAPI.Models;

namespace GerbilManager.Tests;

/// <summary>SEARCH-1: separator-insensitive name search + OriginBreeder (Herkunft) filter.</summary>
public class GerbilSearchTests : IClassFixture<ApiFactory>
{
    private readonly HttpClient _client;

    public GerbilSearchTests(ApiFactory factory) => _client = factory.CreateClient();

    private static HttpContent Gerbil(string name, string? originBreeder = null) =>
        JsonContent.Create(new
        {
            name,
            gender = "female",
            originBreeder,
        });

    [Theory]
    [InlineData("Clan-Kleine-Chaoten", "clankleinechaoten")]
    [InlineData("Clan Kleine Chaoten", "clankleinechaoten")]
    [InlineData("v.d. Kleinen_Chaoten", "vdkleinenchaoten")]
    public void Normalize_strips_separators_and_lowercases(string input, string expected) =>
        Assert.Equal(expected, GerbilSearch.Normalize(input));

    [Fact]
    public async Task NameSearch_filter_matches_across_separators()
    {
        var create = await _client.PostAsync("/gerbils", Gerbil("Clan-Kleine-Chaoten"));
        Assert.Equal(HttpStatusCode.Created, create.StatusCode);

        // Gridify contains is "=*value" (no trailing '*', per the main hotfix 0ee2b53).
        // The client normalizes the user's term the same way the column is normalized.
        var json = await _client.GetStringAsync("/gerbils?filter=nameSearch=*clankleinechaoten");
        Assert.Contains("Clan-Kleine-Chaoten", json);

        // a term that doesn't normalize-match must NOT return it
        var miss = await _client.GetStringAsync("/gerbils?filter=nameSearch=*completelyother");
        Assert.DoesNotContain("Clan-Kleine-Chaoten", miss);
    }

    [Fact]
    public async Task OriginBreeder_is_filterable_and_listed_in_breeders_endpoint()
    {
        await _client.PostAsync("/gerbils", Gerbil("Herkunftstier", originBreeder: "Zucht der kleinen Chaoten"));

        // distinct-values dropdown source
        var breeders = await _client.GetStringAsync("/gerbils/breeders");
        Assert.Contains("Zucht der kleinen Chaoten", breeders);

        // Gridify filter on the field
        var filtered = await _client.GetStringAsync("/gerbils?filter=originBreeder==Zucht der kleinen Chaoten");
        Assert.Contains("Herkunftstier", filtered);
    }
}
