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

namespace Baya.Test.Api;

public class NurseServiceAreasApiTests(BayaApiFactory factory) : IClassFixture<BayaApiFactory>
{
    private const long TehranCityId = 101;
    private const long TehranDistrict1 = 1001;

    private static async Task SetUpNurseAsync(BayaApiFactory factory, HttpClient client, string phone)
    {
        await ProfileTestClient.AuthenticateAsync(factory, client, phone, "nurse");
        await client.PostAsJsonAsync("/api/v1/nurse_profiles/upsert",
            new { bio = "b", yearsOfExperience = 5, educationLevel = "", educationField = "", specializationsJson = "[]" });
    }

    [Fact]
    public async Task Add_WholeCity_And_District_WithDuplicatesRejected()
    {
        var client = factory.CreateClient();
        await SetUpNurseAsync(factory, client, "09125000001");

        // Whole city (no district).
        var wholeCity = await client.PostAsJsonAsync("/api/v1/nurse_service_areas/add", new { cityId = TehranCityId });
        Assert.Equal(HttpStatusCode.OK, wholeCity.StatusCode);
        Assert.True((await AuthTestClient.ReadDataAsync(wholeCity)).GetProperty("isWholeCity").GetBoolean());

        // Duplicate whole city → 409 (not a 500).
        var dupWholeCity = await client.PostAsJsonAsync("/api/v1/nurse_service_areas/add", new { cityId = TehranCityId });
        Assert.Equal(HttpStatusCode.Conflict, dupWholeCity.StatusCode);

        // City + district is a distinct coverage row.
        var district = await client.PostAsJsonAsync("/api/v1/nurse_service_areas/add",
            new { cityId = TehranCityId, districtId = TehranDistrict1 });
        Assert.Equal(HttpStatusCode.OK, district.StatusCode);
        Assert.False((await AuthTestClient.ReadDataAsync(district)).GetProperty("isWholeCity").GetBoolean());

        // Duplicate district → 409.
        var dupDistrict = await client.PostAsJsonAsync("/api/v1/nurse_service_areas/add",
            new { cityId = TehranCityId, districtId = TehranDistrict1 });
        Assert.Equal(HttpStatusCode.Conflict, dupDistrict.StatusCode);

        var list = await client.GetAsync("/api/v1/nurse_service_areas/list");
        var data = await AuthTestClient.ReadDataAsync(list);
        Assert.Equal(2, data.GetProperty("total").GetInt32());
    }

    [Fact]
    public async Task List_Unauthenticated_Returns401()
    {
        var client = factory.CreateClient();
        var response = await client.GetAsync("/api/v1/nurse_service_areas/list");
        Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
    }

    [Fact]
    public async Task Add_InvalidCity_Returns400()
    {
        var client = factory.CreateClient();
        await SetUpNurseAsync(factory, client, "09125000002");

        var response = await client.PostAsJsonAsync("/api/v1/nurse_service_areas/add", new { cityId = 0 });
        Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
    }
}
