using ErsatzTV.Application.Filler;
using ErsatzTV.Core.Api.Filler;
using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Domain.Filler;
using ErsatzTV.Infrastructure.Data;
using ErsatzTV.Tests.Support;
using NUnit.Framework;
using Shouldly;

namespace ErsatzTV.Tests.Application.Filler;

[TestFixture]
public class FillerPresetHandlerTests
{
    private InMemoryTvContext _db = null!;

    [SetUp]
    public async Task SetUp() => _db = await InMemoryTvContext.CreateAsync();

    [TearDown]
    public async Task TearDown() => await _db.DisposeAsync();

    [Test]
    public async Task GetAllFillerPresetsForApi_Should_Return_All_Presets()
    {
        await SeedPreset(1, "Intro");
        await SeedPreset(2, "Outro");

        var handler = new GetAllFillerPresetsForApiHandler(_db.Factory);

        List<FillerPresetResponseModel> result =
            await handler.Handle(new GetAllFillerPresetsForApi(), CancellationToken.None);

        result.Count.ShouldBe(2);
        result.ShouldContain(new FillerPresetResponseModel(1, "Intro", FillerKind.PreRoll));
        result.ShouldContain(new FillerPresetResponseModel(2, "Outro", FillerKind.PreRoll));
    }

    [Test]
    public async Task GetAllFillerPresetsForApi_Should_Filter_By_FillerKind()
    {
        await SeedPreset(1, "Intro", FillerKind.PreRoll);
        await SeedPreset(2, "Mid", FillerKind.MidRoll);
        await SeedPreset(3, "Outro", FillerKind.PostRoll);

        var handler = new GetAllFillerPresetsForApiHandler(_db.Factory);

        List<FillerPresetResponseModel> result =
            await handler.Handle(new GetAllFillerPresetsForApi(FillerKind.MidRoll), CancellationToken.None);

        result.Count.ShouldBe(1);
        result.ShouldContain(new FillerPresetResponseModel(2, "Mid", FillerKind.MidRoll));
    }

    [Test]
    public async Task GetAllFillerPresetsForApi_Should_Return_Empty_List_When_None_Exist()
    {
        var handler = new GetAllFillerPresetsForApiHandler(_db.Factory);

        List<FillerPresetResponseModel> result =
            await handler.Handle(new GetAllFillerPresetsForApi(), CancellationToken.None);

        result.ShouldBeEmpty();
    }

    private async Task SeedPreset(int id, string name, FillerKind fillerKind = FillerKind.PreRoll)
    {
        await using TvContext context = _db.CreateContext();
        context.FillerPresets.Add(new FillerPreset
        {
            Id = id,
            Name = name,
            FillerKind = fillerKind,
            FillerMode = FillerMode.Duration,
            CollectionType = CollectionType.Collection
        });
        await context.SaveChangesAsync();
    }
}
