using System.Net;
using System.Text;

namespace TeleWave.Application.Tests.TestSupport;

/// <summary>
/// Фабрика HTTP-клиентов поверх подставного обработчика: наружу запрос не уходит, ответ выбирается
/// по URL. Запрошенные адреса копятся в <see cref="Urls"/> — по ним проверяем, что провайдер собрал
/// правильный запрос (сегмент tv/movie, язык, append_to_response).
/// </summary>
internal sealed class FakeHttpClientFactory(Func<string, HttpResponseMessage> respond)
    : IHttpClientFactory
{
    public List<string> Urls { get; } = [];

    /// <summary>Один и тот же JSON на любой запрос — самый частый случай в тестах.</summary>
    public static FakeHttpClientFactory Json(string json) => new(_ => Ok(json));

    /// <summary>Ответ-ошибка: провайдеры обязаны деградировать в null/пустой список.</summary>
    public static FakeHttpClientFactory Failing(
        HttpStatusCode status = HttpStatusCode.ServiceUnavailable
    ) => new(_ => new HttpResponseMessage(status) { Content = new StringContent("{}") });

    public static HttpResponseMessage Ok(string json) =>
        new(HttpStatusCode.OK)
        {
            Content = new StringContent(json, Encoding.UTF8, "application/json"),
        };

    public HttpClient CreateClient(string name) =>
        new(
            new StubHandler(url =>
            {
                Urls.Add(url);
                return respond(url);
            })
        );

    /// <summary>Последний запрошенный адрес — короче, чем каждый раз доставать из списка.</summary>
    public string LastUrl => Urls.Count > 0 ? Urls[^1] : string.Empty;

    private sealed class StubHandler(Func<string, HttpResponseMessage> respond) : HttpMessageHandler
    {
        protected override Task<HttpResponseMessage> SendAsync(
            HttpRequestMessage request,
            CancellationToken cancellationToken
        ) => Task.FromResult(respond(request.RequestUri!.ToString()));
    }
}
