using System.Net;
using System.Net.Http.Json;

namespace Baya.Test.Api;

public class CatalogPublicApiTests(BayaApiFactory factory) : IClassFixture<BayaApiFactory>
{
    private const long ElderlyCategoryId = 1;

    [Fact]
    public async Task Categories_Seeded_ReturnsFiveWithBothLabels()
    {
        var client = factory.CreateClient();

        var response = await client.GetAsync("/api/v1/catalog/categories");
        Assert.Equal(HttpStatusCode.OK, response.StatusCode);

        var data = await AuthTestClient.ReadDataAsync(response);
        Assert.Equal(5, data.GetProperty("total").GetInt32());

        var first = data.GetProperty("items").EnumerateArray().First();
        Assert.False(string.IsNullOrWhiteSpace(first.GetProperty("nameFa").GetString()));
        Assert.False(string.IsNullOrWhiteSpace(first.GetProperty("nameEn").GetString()));
        // Ordered by sort_order → Elderly Care (seed id/sort 1) leads.
        Assert.Equal("Elderly Care", first.GetProperty("nameEn").GetString());
    }

    [Fact]
    public async Task AdminBuildsDimension_PublicListsGroupWithValuesPlusCrossCategory()
    {
        var client = factory.CreateClient();
        await AdminTestClient.AuthenticateAsync(factory, client, "09131000001");

        // A category-scoped required dimension.
        var group = await client.PostAsJsonAsync("/api/v1/admin_catalog/create_option_group",
            new { serviceCategoryId = ElderlyCategoryId, nameFa = "نوع شیفت", nameEn = "Shift type", isRequired = true, sortOrder = 1 });
        Assert.Equal(HttpStatusCode.OK, group.StatusCode);
        var groupId = (await AuthTestClient.ReadDataAsync(group)).GetProperty("id").GetInt64();

        // A cross-category (null category) dimension applies to every category.
        var crossGroup = await client.PostAsJsonAsync("/api/v1/admin_catalog/create_option_group",
            new { serviceCategoryId = (long?)null, nameFa = "تعداد بیمار", nameEn = "Patient count", isRequired = false, sortOrder = 2 });
        Assert.Equal(HttpStatusCode.OK, crossGroup.StatusCode);
        var crossGroupId = (await AuthTestClient.ReadDataAsync(crossGroup)).GetProperty("id").GetInt64();

        var v1 = await client.PostAsJsonAsync("/api/v1/admin_catalog/create_option_value",
            new { optionGroupId = groupId, nameFa = "شبانه‌روزی", nameEn = "Live-in", sortOrder = 1 });
        var v2 = await client.PostAsJsonAsync("/api/v1/admin_catalog/create_option_value",
            new { optionGroupId = groupId, nameFa = "روزانه", nameEn = "Daytime", sortOrder = 2 });
        Assert.Equal(HttpStatusCode.OK, v1.StatusCode);
        Assert.Equal(HttpStatusCode.OK, v2.StatusCode);

        var groups = await client.GetAsync($"/api/v1/catalog/option_groups?category_id={ElderlyCategoryId}");
        var arr = (await AuthTestClient.ReadDataAsync(groups)).EnumerateArray().ToList();

        var shift = arr.Single(g => g.GetProperty("id").GetInt64() == groupId);
        Assert.True(shift.GetProperty("isRequired").GetBoolean());
        Assert.Equal(2, shift.GetProperty("values").GetArrayLength());

        // The cross-category group shows up under this category too.
        Assert.Contains(arr, g => g.GetProperty("id").GetInt64() == crossGroupId);
    }

    [Fact]
    public async Task CreateCategory_Unauthenticated_Returns401()
    {
        var client = factory.CreateClient();
        var response = await client.PostAsJsonAsync("/api/v1/admin_catalog/create_category",
            new { nameFa = "x", nameEn = "x", sortOrder = 1 });
        Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
    }
}
