using TeleWave.Application.Library.BulkTagShows;
using TeleWave.Application.Library.Collections.AddShowsToCollection;
using TeleWave.Application.Programming.Groups.UpdateGroup;
using TeleWave.Domain.Library;
using Xunit;

namespace TeleWave.Application.Tests.Validators;

/// <summary>
/// Валидаторы массовых операций. Они ловят не злой умысел, а недосмотр вызывающей стороны: команда,
/// которая ничего не меняет или не говорит куда складывать, — это ошибка UI, и падать она должна
/// понятно.
/// </summary>
public class BulkOperationValidatorsTests
{
    [Fact]
    public void BulkTag_RequiresShowsAndSomethingToApply()
    {
        var validator = new BulkTagShowsCommandValidator();

        Assert.True(
            validator
                .Validate(new BulkTagShowsCommand([Guid.NewGuid()], GenreIds: [Guid.NewGuid()]))
                .IsValid
        );
        Assert.True(
            validator
                .Validate(
                    new BulkTagShowsCommand(
                        [Guid.NewGuid()],
                        Audience: ShowAudience.Pg,
                        SetAudience: true
                    )
                )
                .IsValid
        );

        // Ни жанров, ни рейтинга — применять нечего.
        Assert.False(validator.Validate(new BulkTagShowsCommand([Guid.NewGuid()])).IsValid);
        // Пустой список отмеченных.
        Assert.False(
            validator.Validate(new BulkTagShowsCommand([], GenreIds: [Guid.NewGuid()])).IsValid
        );
    }

    [Fact]
    public void AddShowsToCollection_RequiresTarget()
    {
        var validator = new AddShowsToCollectionCommandValidator();
        var shows = new[] { Guid.NewGuid() };

        Assert.True(
            validator.Validate(new AddShowsToCollectionCommand(shows, Guid.NewGuid())).IsValid
        );
        Assert.True(
            validator
                .Validate(new AddShowsToCollectionCommand(shows, NewCollectionName: "Франшиза"))
                .IsValid
        );

        // Ни существующей коллекции, ни имени новой — складывать некуда.
        Assert.False(validator.Validate(new AddShowsToCollectionCommand(shows)).IsValid);
        Assert.False(
            validator
                .Validate(new AddShowsToCollectionCommand(shows, NewCollectionName: "   "))
                .IsValid
        );
        Assert.False(
            validator.Validate(new AddShowsToCollectionCommand([], Guid.NewGuid())).IsValid
        );
        Assert.False(
            validator
                .Validate(
                    new AddShowsToCollectionCommand(shows, NewCollectionName: new string('x', 257))
                )
                .IsValid
        );
    }

    [Fact]
    public void UpdateGroup_ChecksNameAndDescription()
    {
        var validator = new UpdateGroupCommandValidator();

        Assert.True(
            validator
                .Validate(new UpdateGroupCommand(Guid.NewGuid(), "Боевики", null, null))
                .IsValid
        );
        Assert.False(
            validator.Validate(new UpdateGroupCommand(Guid.NewGuid(), "  ", null, null)).IsValid
        );
        Assert.False(
            validator
                .Validate(new UpdateGroupCommand(Guid.NewGuid(), new string('x', 257), null, null))
                .IsValid
        );
    }
}
