using TeleWave.Domain.Library;
using Xunit;

namespace TeleWave.Domain.Tests.Library;

public class ShowGenreTests
{
    private static Show NewShow() => Show.Create("A", ShowKind.Series);

    [Fact]
    public void SetGenres_MarksRequestedPrimary()
    {
        var show = NewShow();
        var action = Guid.NewGuid();
        var comedy = Guid.NewGuid();

        show.SetGenres([action, comedy], comedy);

        Assert.Equal(2, show.Genres.Count);
        Assert.Equal(comedy, show.PrimaryGenreId);
    }

    [Fact]
    public void SetGenres_FallsBackToFirst_WhenPrimaryNotInSet()
    {
        var show = NewShow();
        var action = Guid.NewGuid();
        var comedy = Guid.NewGuid();

        show.SetGenres([action, comedy], Guid.NewGuid());

        // Шоу с жанрами не должно оставаться без основного — иначе список показывал бы прочерк.
        Assert.Equal(action, show.PrimaryGenreId);
        Assert.Single(show.Genres, g => g.IsPrimary);
    }

    [Fact]
    public void SetGenres_DropsDuplicatesAndEmpty()
    {
        var show = NewShow();
        var action = Guid.NewGuid();

        show.SetGenres([action, action, Guid.Empty]);

        Assert.Single(show.Genres);
        Assert.Equal(action, show.PrimaryGenreId);
    }

    [Fact]
    public void SetGenres_ReplacesPreviousSet()
    {
        var show = NewShow();
        var first = Guid.NewGuid();
        var second = Guid.NewGuid();

        show.SetGenres([first]);
        show.SetGenres([second]);

        Assert.Single(show.Genres);
        Assert.Equal(second, show.PrimaryGenreId);
    }

    [Fact]
    public void SetGenres_Empty_LeavesNoPrimary()
    {
        var show = NewShow();
        show.SetGenres([Guid.NewGuid()]);

        show.SetGenres([]);

        Assert.Empty(show.Genres);
        Assert.Null(show.PrimaryGenreId);
    }
}

public class GenreTests
{
    [Theory]
    [InlineData("  Sci-Fi  ", "sci-fi")]
    [InlineData("Action  &   Adventure", "action & adventure")]
    [InlineData("БОЕВИК", "боевик")]
    [InlineData("   ", "")]
    [InlineData(null, "")]
    public void Normalize_CollapsesCaseAndSpacing(string? input, string expected) =>
        Assert.Equal(expected, GenreAlias.Normalize(input));

    [Fact]
    public void AddAlias_IgnoresDuplicatesRegardlessOfSpelling()
    {
        var genre = Genre.Create("Боевик", "action");

        genre.AddAlias("Action");
        genre.AddAlias("  action ");
        genre.AddAlias("боевик");

        Assert.Equal(2, genre.Aliases.Count);
    }

    [Fact]
    public void ReplaceAliases_DropsOldOnes()
    {
        var genre = Genre.Create("Боевик", "action");
        genre.AddAlias("tmdb:28");

        genre.ReplaceAliases(["tmdb:10759"]);

        Assert.Single(genre.Aliases);
        Assert.Equal("tmdb:10759", genre.Aliases[0].Value);
    }

    [Fact]
    public void ProviderKey_BuildsNormalizedPrefixedAlias() =>
        Assert.Equal("tmdb:28", GenreAlias.ProviderKey("TMDB", "28"));
}
