using System.Net;
using System.Text;
using Microsoft.Extensions.Options;
using TeleWave.Infrastructure.Metadata;
using Xunit;

namespace TeleWave.Application.Tests.Metadata;

/// <summary>
/// TMDb принимает и ключ v3 (в query), и токен v4 (в заголовке). Способ выбирается по форме самого
/// значения, поэтому проверяем именно то, что уходит в запрос.
/// </summary>
public class TmdbAuthTests
{
    [Fact]
    public async Task V3Key_GoesToQuery()
    {
        var handler = new CapturingHandler();
        var provider = ProviderWith("fa38966b51f0043827fa89a5e42a0afe", handler);

        await provider.GetSeasonNumbersAsync("123", CancellationToken.None);

        var request = handler.Last!;
        Assert.Contains("api_key=fa38966b51f0043827fa89a5e42a0afe", request.RequestUri!.Query);
        Assert.Null(request.Headers.Authorization);
    }

    [Fact]
    public async Task V4Token_GoesToAuthorizationHeader()
    {
        var handler = new CapturingHandler();
        var token = "eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJ0ZWxld2F2ZSJ9.c2lnbmF0dXJl";
        var provider = ProviderWith(token, handler);

        await provider.GetSeasonNumbersAsync("123", CancellationToken.None);

        var request = handler.Last!;
        Assert.DoesNotContain("api_key", request.RequestUri!.Query);
        Assert.Equal("Bearer", request.Headers.Authorization?.Scheme);
        Assert.Equal(token, request.Headers.Authorization?.Parameter);
    }

    private static TmdbMetadataProvider ProviderWith(string apiKey, HttpMessageHandler handler) =>
        new(
            new SingleClientFactory(handler),
            Options.Create(new MetadataOptions { Tmdb = new TmdbOptions { ApiKey = apiKey } })
        );

    private sealed class CapturingHandler : HttpMessageHandler
    {
        public HttpRequestMessage? Last { get; private set; }

        protected override Task<HttpResponseMessage> SendAsync(
            HttpRequestMessage request,
            CancellationToken cancellationToken
        )
        {
            Last = request;
            return Task.FromResult(
                new HttpResponseMessage(HttpStatusCode.OK)
                {
                    Content = new StringContent("{}", Encoding.UTF8, "application/json"),
                }
            );
        }
    }

    private sealed class SingleClientFactory(HttpMessageHandler handler) : IHttpClientFactory
    {
        public HttpClient CreateClient(string name) => new(handler, disposeHandler: false);
    }
}
