using System.Threading;
using System.Threading.Tasks;
using ErsatzTV.Application.MediaCollections;
using ErsatzTV.Application.Search;
using ErsatzTV.Core.Domain;
using ErsatzTV.Infrastructure.Data;
using ErsatzTV.Tests.Support;
using NUnit.Framework;
using Shouldly;

namespace ErsatzTV.Tests.Application.Search;

// #425: the scheduling collection picker (search-smart/multi-collections) must NOT surface the
// system-owned weighted-auto-tune artifacts — selecting one into a user schedule would let a later
// channel delete cascade away that schedule item.
[TestFixture]
public class CollectionPickerHidesOwnedTests
{
    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 SearchSmartCollections_Excludes_Owned()
    {
        await using (TvContext ctx = _db.CreateContext())
        {
            ctx.SmartCollections.Add(new SmartCollection { Name = "at:tok:0", Query = "q", OwnedByChannelId = 5 });
            ctx.SmartCollections.Add(new SmartCollection { Name = "at:user:sc", Query = "q" });
            await ctx.SaveChangesAsync();
        }

        var result = await new SearchSmartCollectionsHandler(_db.Factory)
            .Handle(new SearchSmartCollections("at"), CancellationToken.None);

        result.ShouldContain(vm => vm.Name == "at:user:sc");
        result.ShouldNotContain(vm => vm.Name == "at:tok:0");
    }

    [Test]
    public async Task SearchMultiCollections_Excludes_Owned()
    {
        await using (TvContext ctx = _db.CreateContext())
        {
            ctx.MultiCollections.Add(new MultiCollection { Name = "at-mc:tok", OwnedByChannelId = 5 });
            ctx.MultiCollections.Add(new MultiCollection { Name = "at-mc:user" });
            await ctx.SaveChangesAsync();
        }

        var result = await new SearchMultiCollectionsHandler(_db.Factory)
            .Handle(new SearchMultiCollections("at"), CancellationToken.None);

        result.ShouldContain(vm => vm.Name == "at-mc:user");
        result.ShouldNotContain(vm => vm.Name == "at-mc:tok");
    }
}
