using TeleWave.Domain.Library;
using Xunit;

namespace TeleWave.Domain.Tests.Library;

public class ShowTests
{
    [Fact]
    public void Create_NormalizesOriginalName()
    {
        var s = Show.Create("Симпсоны", ShowKind.Series, "desc", "  The Simpsons  ");

        Assert.Equal("Симпсоны", s.Name);
        Assert.Equal("The Simpsons", s.OriginalName);
        Assert.Equal(ShowKind.Series, s.Kind);
        Assert.Equal("desc", s.Description);
    }

    [Fact]
    public void Create_BlankOriginalName_BecomesNull()
    {
        var s = Show.Create("X", ShowKind.Single, originalName: "   ");
        Assert.Null(s.OriginalName);
    }

    [Fact]
    public void RenameAndSetName_ChangeDisplayName()
    {
        var s = Show.Create("A", ShowKind.Series);
        s.Rename("B", "d");
        Assert.Equal("B", s.Name);
        Assert.Equal("d", s.Description);

        s.SetName("C");
        Assert.Equal("C", s.Name);
    }

    [Fact]
    public void SetOriginalName_TrimsOrClears()
    {
        var s = Show.Create("A", ShowKind.Series);
        s.SetOriginalName("  orig ");
        Assert.Equal("orig", s.OriginalName);
        s.SetOriginalName("");
        Assert.Null(s.OriginalName);
    }

    [Fact]
    public void AddEpisode_AppendsInOrder()
    {
        var s = Show.Create("A", ShowKind.Series);
        var e0 = s.AddEpisode(Guid.NewGuid());
        var e1 = s.AddEpisode(Guid.NewGuid());

        Assert.Equal(0, e0.Position);
        Assert.Equal(1, e1.Position);
        Assert.Equal(2, s.Episodes.Count);
    }

    [Fact]
    public void RemoveEpisode_RemovesById()
    {
        var s = Show.Create("A", ShowKind.Series);
        var e = s.AddEpisode(Guid.NewGuid());

        Assert.True(s.RemoveEpisode(e.Id));
        Assert.False(s.RemoveEpisode(e.Id));
        Assert.Empty(s.Episodes);
    }

    [Fact]
    public void CanAddEpisode_SingleAllowsOnlyOne()
    {
        var single = Show.Create("Movie", ShowKind.Single);
        Assert.True(single.CanAddEpisode);
        single.AddEpisode(Guid.NewGuid());
        Assert.False(single.CanAddEpisode);

        var series = Show.Create("Series", ShowKind.Series);
        series.AddEpisode(Guid.NewGuid());
        Assert.True(series.CanAddEpisode);
    }

    [Fact]
    public void AddEpisode_SecondForSingle_Throws()
    {
        var single = Show.Create("Movie", ShowKind.Single);
        single.AddEpisode(Guid.NewGuid());

        Assert.Throws<InvalidOperationException>(() => single.AddEpisode(Guid.NewGuid()));
        Assert.Single(single.Episodes);
    }

    [Fact]
    public void ApplyMetadata_SetsProviderYearPoster_KeepsDescriptionIfBlank()
    {
        var s = Show.Create("A", ShowKind.Series, description: "old");
        var poster = Guid.NewGuid();

        s.ApplyMetadata("tmdb", "42", description: null, year: 1999, posterImageId: poster);

        Assert.Equal("tmdb", s.MetadataProvider);
        Assert.Equal("42", s.MetadataExternalId);
        Assert.Equal(1999, s.Year);
        Assert.Equal(poster, s.PosterImageId);
        Assert.Equal("old", s.Description); // пустое описание не затирает
    }

    [Fact]
    public void UpdateMetadataManual_MarksManualAndClearsExternal()
    {
        var s = Show.Create("A", ShowKind.Series);
        s.ApplyMetadata("tmdb", "1", "d", 2000, Guid.NewGuid());

        s.UpdateMetadataManual("new", 2001);

        Assert.Equal("manual", s.MetadataProvider);
        Assert.Null(s.MetadataExternalId);
        Assert.Equal("new", s.Description);
        Assert.Equal(2001, s.Year);
    }

    [Fact]
    public void SetPosterImage_AndClearMetadata()
    {
        var s = Show.Create("A", ShowKind.Series);
        s.ApplyMetadata("tmdb", "1", "d", 2000, Guid.NewGuid());
        s.SetPosterImage(Guid.NewGuid());

        s.ClearMetadata();

        Assert.Null(s.MetadataProvider);
        Assert.Null(s.MetadataExternalId);
        Assert.Null(s.Year);
        Assert.Null(s.PosterImageId);
        Assert.Null(s.Description);
    }
}
