using Xunit;
using ytLive.Models;
using ytLive.ViewModels;

namespace ytLive.Tests;

/// <summary>
/// The app is a five-scene product: Starting/Live/BRB/Chat/Ending. Scenes are
/// worked on by name; you can delete them but never add beyond the set, and the
/// live backdrop belongs to Live alone.
/// </summary>
public class SceneCatalogTests
{
    [Fact]
    public void SceneCatalog_Defines_The_Five_Canonical_Scenes()
    {
        Assert.Equal(
            new[] { "Starting", "Live", "BRB", "Chat", "Ending" },
            SceneCatalog.All);
    }

    [Theory]
    [InlineData("Starting", true)]
    [InlineData("Live", true)]
    [InlineData("BRB", true)]
    [InlineData("Chat", true)]
    [InlineData("Ending", true)]
    [InlineData("live", true)]
    [InlineData("My Scene", false)]
    [InlineData("", false)]
    [InlineData(null, false)]
    public void SceneCatalog_IsCanonical_Matches_By_Name(string? name, bool expected)
    {
        Assert.Equal(expected, SceneCatalog.IsCanonical(name));
    }

    [Theory]
    [InlineData("Starting", false)]
    [InlineData("Live", true)]
    [InlineData("BRB", false)]
    [InlineData("Chat", false)]
    [InlineData("Ending", false)]
    public void SceneCatalog_HasBackdrop_Only_For_Live(string name, bool expected)
    {
        Assert.Equal(expected, SceneCatalog.HasBackdrop(name));
    }

    [Fact]
    public void EnforceBackdropPolicy_Removes_Backdrop_From_NonLive_Scenes()
    {
        var chat = new Scene { Name = "Chat", HasBackdrop = true };
        var live = new Scene { Name = "Live", HasBackdrop = true };
        var chatBackdrop = MainViewModel.EnsureBackdrop(chat)!;
        var liveBackdrop = MainViewModel.EnsureBackdrop(live)!;
        Assert.Contains(chat.Elements, e => ReferenceEquals(e, chatBackdrop));

        MainViewModel.EnforceBackdropPolicy(new[] { chat, live });

        Assert.False(chat.HasBackdrop);
        Assert.DoesNotContain(chat.Elements, e => e is Source { IsBackdrop: true });
        Assert.True(live.HasBackdrop);
        Assert.Contains(live.Elements, e => ReferenceEquals(e, liveBackdrop));
    }

    [Fact]
    public void EnforceBackdropPolicy_Marks_Live_And_Clears_A_Pre_Policy_Database()
    {
        var starting = new Scene { Name = "Starting", HasBackdrop = true };
        MainViewModel.EnsureBackdrop(starting);
        var live = new Scene { Name = "Live", HasBackdrop = false };

        MainViewModel.EnforceBackdropPolicy(new[] { starting, live });

        Assert.False(starting.HasBackdrop);
        Assert.True(live.HasBackdrop);
    }
}
