using System.Net;
using System.Text;
using Xunit;
using ytLive.Models;
using ytLive.Services;

namespace ytLive.Tests;

/// <summary>
/// The one integration test for ship step 7 (private-only go live): the
/// broadcast-insert request must carry privacyStatus "private" — the dialog is
/// locked to Private and the service must never send anything else.
/// </summary>
public class YouTubeStreamServiceTests
{
    private sealed class RecordingHandler : HttpMessageHandler
    {
        public string? LastBody;
        public string ResponseBody = """{"id":"BC123","snippet":{"title":"t"}}""";

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

    private static YouTubeAuthService CreateAuth() => new("test-id", "test-secret");

    [Fact]
    public async Task CreateBroadcast_Always_Sends_Private_PrivacyStatus()
    {
        var handler = new RecordingHandler();
        var auth = CreateAuth();
        auth.SetSession(new YouTubeChannel
        {
            AccessToken = "acc-123",
            TokenExpiry = DateTime.UtcNow.AddHours(1),
        });
        var service = new YouTubeStreamService(auth, new HttpClient(handler));

        var id = await service.CreateBroadcast("Test Stream", "A description", DateTime.UtcNow);

        Assert.Equal("BC123", id);
        Assert.NotNull(handler.LastBody);
        Assert.Contains("\"privacyStatus\":\"private\"", handler.LastBody);
    }

    [Fact]
    public async Task CreateBroadcast_Without_Session_Returns_Null()
    {
        var handler = new RecordingHandler();
        var auth = CreateAuth(); // no session
        var service = new YouTubeStreamService(auth, new HttpClient(handler));

        var id = await service.CreateBroadcast("Test Stream", "A description", DateTime.UtcNow);

        Assert.Null(id);
        Assert.Null(handler.LastBody); // never reached the API
    }
}
