using JSMR.Application.Integrations.Chobit.Models;
using JSMR.Infrastructure.Integrations.Chobit;
using JSMR.Tests.Http;
using JSMR.Tests.Utilities;
using Microsoft.Extensions.Logging;
using NSubstitute;
using Shouldly;
using System.Net;
using System.Text;

namespace JSMR.Tests.Integrations.Chobit;

public class ChobitClientTests
{
    private static async Task<string> ReadJsonResourceAsync(string resourceName)
    {
        return await ResourceHelper.ReadAsync($"JSMR.Tests.Integrations.Chobit.{resourceName}");
    }

    private static async Task<ChobitClient> GetChobitClientThatReturns(string resourceName)
    {
        string content = await ReadJsonResourceAsync(resourceName);

        FakeHttpMessageHandler handler = new(request =>
        {
            return new HttpResponseMessage(HttpStatusCode.OK)
            {
                Content = new StringContent(content, Encoding.UTF8, "application/json")
            };
        });

        HttpClient httpClient = new(handler)
        {
            BaseAddress = new Uri("https://fake-chobit.cc/")
        };

        var logger = Substitute.For<ILogger<ChobitClient>>();
        var client = new ChobitClient(httpClient, logger);

        return client;
    }

    [Fact]
    public async Task Deserialize_Chobit_Sample_Info()
    {
        var client = await GetChobitClientThatReturns("Sample-Chobit-Result.jsonp");
        var result = await client.GetSampleInfoAsync("RJ01430276", CancellationToken.None);

        result.Count.ShouldBe(1);
        result.Works.Length.ShouldBe(1);

        ChobitWork work = result.Works[0];
        work.WorkId.ShouldBe("70nh8");
        work.DLSiteWorkId.ShouldBe("RJ01430276");
        work.WorkName.ShouldBe("【ブルーアーカイブ】シグレ(温泉)ASMR～溶けていく温度を交わして～");
    }

    [Fact]
    public async Task Deserialize_Chobit_Sample_Info_Collection()
    {
        var client = await GetChobitClientThatReturns("Sample-Chobit-Result-Collection.jsonp");
        var result = await client.GetSampleInfoAsync(["RJ01430276"], CancellationToken.None);

        result.Count.ShouldBe(1);
        result.ShouldContainKey("RJ01430276");

        result["RJ01430276"].Count.ShouldBe(1);
        result["RJ01430276"].Works.Length.ShouldBe(1);

        ChobitWork work = result["RJ01430276"].Works[0];
        work.WorkId.ShouldBe("70nh8");
        work.DLSiteWorkId.ShouldBe("RJ01430276");
        work.WorkName.ShouldBe("【ブルーアーカイブ】シグレ(温泉)ASMR～溶けていく温度を交わして～");
    }

    [Fact]
    public async Task Deserialize_Chobit_Sample_Info_No_Data()
    {
        var client = await GetChobitClientThatReturns("Sample-Chobit-Result-No-Data.jsonp");
        var result = await client.GetSampleInfoAsync("RJ01585659", CancellationToken.None);

        result.Count.ShouldBe(0);
        result.Works.Length.ShouldBe(0);
    }

    [Fact]
    public async Task Deserialize_Chobit_Sample_Info_Collection_No_Data()
    {
        var client = await GetChobitClientThatReturns("Sample-Chobit-Result-Collection-No-Data.jsonp");
        var result = await client.GetSampleInfoAsync(["RJ01585659"], CancellationToken.None);

        result.Count.ShouldBe(1);
        result.ShouldContainKey("RJ01585659");

        result["RJ01585659"].Count.ShouldBe(0);
        result["RJ01585659"].Works.Length.ShouldBe(0);
    }
}