using System.Net;
using System.Text.Json;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging.Abstractions;
using UniVerse.Application.DTOs.Sync;
using UniVerse.Infrastructure.ExternalServices;
using Xunit;

namespace UniVerse.Api.Tests.Sync;

public class ModeusApiClientTests
{
    [Fact]
    public async Task SearchEventsAsync_RequestsIctisEndpointWithCounts()
    {
        var handler = new CapturingHandler();
        var http = new HttpClient(handler)
        {
            BaseAddress = new Uri("https://schedule.test")
        };
        var config = new ConfigurationBuilder().Build();
        var client = new ModeusApiClient(http, config, NullLogger<ModeusApiClient>.Instance);

        await client.SearchEventsAsync(new SyncScheduleRequest(
            SpecialtyCode: ["09.03.04"],
            TimeMin: new DateTime(2026, 4, 30, 21, 0, 0, DateTimeKind.Utc),
            TimeMax: new DateTime(2026, 6, 13, 20, 59, 0, DateTimeKind.Utc),
            TypeId: ["LECT"],
            Size: 50));

        Assert.Equal(HttpMethod.Post, handler.RequestMethod);
        Assert.Equal("/api/ictis?includeCounts=true", handler.RequestPathAndQuery);
        Assert.NotNull(handler.RequestBody);
        using var body = JsonDocument.Parse(handler.RequestBody);
        Assert.Equal(50, body.RootElement.GetProperty("size").GetInt32());
        Assert.Equal("09.03.04", body.RootElement.GetProperty("specialtyCode")[0].GetString());
        Assert.Equal("LECT", body.RootElement.GetProperty("typeId")[0].GetString());
    }

    private sealed class CapturingHandler : HttpMessageHandler
    {
        public HttpMethod? RequestMethod { get; private set; }
        public string? RequestPathAndQuery { get; private set; }
        public string? RequestBody { get; private set; }

        protected override async Task<HttpResponseMessage> SendAsync(
            HttpRequestMessage request,
            CancellationToken cancellationToken)
        {
            RequestMethod = request.Method;
            RequestPathAndQuery = request.RequestUri?.PathAndQuery;
            RequestBody = request.Content is null
                ? null
                : await request.Content.ReadAsStringAsync(cancellationToken);

            return new HttpResponseMessage(HttpStatusCode.OK)
            {
                Content = new StringContent("""{"events":[]}""")
            };
        }
    }
}
