using System.Text.Json;

namespace WorkClub.Tests.Integration.Infrastructure;

public abstract class IntegrationTestBase : IClassFixture<CustomWebApplicationFactory<Program>>, IAsyncLifetime
{
    protected readonly HttpClient Client;
    protected readonly CustomWebApplicationFactory<Program> Factory;

    protected IntegrationTestBase(CustomWebApplicationFactory<Program> factory)
    {
        Factory = factory;
        Client = factory.CreateClient();
    }

    protected void AuthenticateAs(string email, Dictionary<string, string> clubs, string? userId = null)
    {
        var clubsCsv = string.Join(",", clubs.Keys);
        Client.DefaultRequestHeaders.Remove("X-Test-Clubs");
        Client.DefaultRequestHeaders.Add("X-Test-Clubs", clubsCsv);

        // Preserve role mapping as JSON for role claim injection in TestAuthHandler
        var clubRolesJson = JsonSerializer.Serialize(clubs);
        Client.DefaultRequestHeaders.Remove("X-Test-ClubRoles");
        Client.DefaultRequestHeaders.Add("X-Test-ClubRoles", clubRolesJson);

        Client.DefaultRequestHeaders.Remove("X-Test-Email");
        Client.DefaultRequestHeaders.Add("X-Test-Email", email);

        Client.DefaultRequestHeaders.Remove("X-Test-Unauthenticated");

        if (!string.IsNullOrEmpty(userId))
        {
            Client.DefaultRequestHeaders.Remove("X-Test-UserId");
            Client.DefaultRequestHeaders.Add("X-Test-UserId", userId);
        }
    }

    protected void AuthenticateAsUnauthenticated()
    {
        Client.DefaultRequestHeaders.Remove("X-Test-Clubs");
        Client.DefaultRequestHeaders.Remove("X-Test-Email");
        Client.DefaultRequestHeaders.Remove("X-Test-UserId");
        Client.DefaultRequestHeaders.Remove("X-Test-Unauthenticated");
        Client.DefaultRequestHeaders.Add("X-Test-Unauthenticated", "true");
    }

    protected void SetTenant(string tenantId)
    {
        Client.DefaultRequestHeaders.Remove("X-Tenant-Id");
        Client.DefaultRequestHeaders.Add("X-Tenant-Id", tenantId);
    }

    public virtual Task InitializeAsync() => Task.CompletedTask;

    public virtual Task DisposeAsync() => Task.CompletedTask;
}
