using System.Net;
using System.Net.Http.Json;
using System.Text.Json;
using FluentAssertions;
using foodmarket.IntegrationTests.Support;
using Xunit;

namespace foodmarket.IntegrationTests;

[Collection(ApiCollection.Name)]
public class PermissionTests
{
    private readonly ApiFactory _factory;
    public PermissionTests(ApiFactory factory) => _factory = factory;

    [Fact]
    public async Task Custom_role_without_ProductsEdit_gets_403_on_put_product()
    {
        var admin = new ApiActor(_factory.CreateClient());
        await admin.SignupAndLoginAsync($"permadmin-{Guid.NewGuid():N}");

        // Кастомная роль: просмотр товаров, но БЕЗ права правки.
        var roleResp = await admin.Http.PostAsJsonAsync("/api/organization/employee-roles", new
        {
            name = $"Viewer-{Guid.NewGuid():N}",
            description = "view only",
            permissions = new { productsView = true, productsEdit = false },
        });
        roleResp.EnsureSuccessStatusCode();
        var roleId = (await roleResp.Content.ReadFromJsonAsync<JsonElement>()).GetProperty("id").GetString();

        // Сотрудник с логином на этой роли.
        var empEmail = $"viewer-{Guid.NewGuid():N}@example.kz";
        var empResp = await admin.Http.PostAsJsonAsync("/api/organization/employees", new
        {
            lastName = "Просмотров", firstName = "Вью", roleId,
            isActive = true, createAccount = true, email = empEmail,
        });
        empResp.EnsureSuccessStatusCode();
        var pwd = (await empResp.Content.ReadFromJsonAsync<JsonElement>()).GetProperty("generatedPassword").GetString()!;

        var viewer = new ApiActor(_factory.CreateClient());
        viewer.UseToken(await viewer.TokenAsync(empEmail, pwd));

        // Авторизация проверяется до биндинга тела: несуществующий id → 403, если нет права.
        using var put = await viewer.Http.PutAsJsonAsync($"/api/catalog/products/{Guid.NewGuid()}", new { });
        put.StatusCode.Should().Be(HttpStatusCode.Forbidden);

        // Чтение (ProductsView) разрешено.
        using var get = await viewer.Http.GetAsync("/api/catalog/products");
        get.StatusCode.Should().Be(HttpStatusCode.OK);
    }

    [Fact]
    public async Task Admin_passes_permission_gate()
    {
        var admin = new ApiActor(_factory.CreateClient());
        await admin.SignupAndLoginAsync($"permadmin2-{Guid.NewGuid():N}");

        // Админ проходит permission-гейт (дальше — 404/400 на несуществующем товаре, но НЕ 403).
        using var put = await admin.Http.PutAsJsonAsync($"/api/catalog/products/{Guid.NewGuid()}", new { });
        put.StatusCode.Should().NotBe(HttpStatusCode.Forbidden);
    }
}
