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

namespace Baya.Test.Api;

public class RoleSelectionTests(BayaApiFactory factory) : IClassFixture<BayaApiFactory>
{
    [Fact]
    public async Task SelectRole_PublicRoles_AreGrantedIdempotentlyAndCanCoexist()
    {
        var client = factory.CreateClient();
        var tokens = await AuthTestClient.LoginAsync(factory, client, "09120000020");
        AuthTestClient.UseBearer(client, tokens.GetProperty("accessToken").GetString()!);

        var customer = await client.PostAsJsonAsync("/api/v1/me/select_role", new { role = "customer" });
        Assert.Equal(HttpStatusCode.OK, customer.StatusCode);
        var afterCustomer = await AuthTestClient.ReadDataAsync(customer);
        Assert.Contains("customer", afterCustomer.GetProperty("roles").EnumerateArray().Select(r => r.GetString()));

        // Selecting the same role again is an idempotent success.
        var repeat = await client.PostAsJsonAsync("/api/v1/me/select_role", new { role = "customer" });
        Assert.Equal(HttpStatusCode.OK, repeat.StatusCode);

        // A user may hold customer and nurse at once.
        var nurse = await client.PostAsJsonAsync("/api/v1/me/select_role", new { role = "nurse" });
        Assert.Equal(HttpStatusCode.OK, nurse.StatusCode);
        var afterNurse = await AuthTestClient.ReadDataAsync(nurse);
        var roles = afterNurse.GetProperty("roles").EnumerateArray().Select(r => r.GetString()).ToList();
        Assert.Contains("customer", roles);
        Assert.Contains("nurse", roles);
    }

    [Fact]
    public async Task SelectRole_AdminSubRole_Returns403()
    {
        var client = factory.CreateClient();
        var tokens = await AuthTestClient.LoginAsync(factory, client, "09120000021");
        AuthTestClient.UseBearer(client, tokens.GetProperty("accessToken").GetString()!);

        var response = await client.PostAsJsonAsync("/api/v1/me/select_role", new { role = "super_admin" });

        Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);
    }
}