using MBN_STOCK_WEBVIEW.Core.Playout;
using MBN_STOCK_WEBVIEW.Core.Playout.Scenes;

namespace MBN_STOCK_WEBVIEW.Playout.Tests;

public sealed class PlayoutSceneCompositionFactoryTests
{
    [Fact]
    public void Default_MatchesLegacyFadeAndRequiresNoExternalAsset()
    {
        var result = PlayoutSceneCompositionFactory.Create(new PlayoutOptions());

        Assert.Equal(6, result.FadeDuration);
        Assert.Equal(LegacySceneBackgroundKind.None, result.BackgroundKind);
        Assert.Null(result.BackgroundAssetPath);
    }

    [Theory]
    [InlineData(0)]
    [InlineData(6)]
    [InlineData(19)]
    public void Fade_AcceptsOriginalDissolveComboIndexRange(int fadeDuration)
    {
        var result = PlayoutSceneCompositionFactory.Create(new PlayoutOptions
        {
            LegacySceneFadeDuration = fadeDuration
        });

        Assert.Equal(fadeDuration, result.FadeDuration);
    }

    [Theory]
    [InlineData(-1)]
    [InlineData(20)]
    [InlineData(60)]
    public void Fade_RejectsValuesOutsideOriginalDissolveComboIndexRange(int fadeDuration)
    {
        Assert.Throws<PlayoutConfigurationException>(() =>
            PlayoutSceneCompositionFactory.Create(new PlayoutOptions
            {
                LegacySceneFadeDuration = fadeDuration
            }));
    }

    [Fact]
    public void TrustedRelativeVideo_IsVerifiedEvenInDryRun()
    {
        using var scenes = TemporarySceneDirectory.Create("5001.t2s");
        var backgroundRoot = Path.Combine(Directory.GetParent(scenes.Path)!.FullName, "배경");
        Directory.CreateDirectory(backgroundRoot);
        File.WriteAllText(Path.Combine(backgroundRoot, "studio.vrv"), "trusted background");
        var result = PlayoutSceneCompositionFactory.Create(new PlayoutOptions
        {
            Mode = PlayoutMode.DryRun,
            SceneDirectory = scenes.Path,
            LegacySceneBackgroundKind = LegacySceneBackgroundKind.Video,
            LegacySceneBackgroundAssetPath = "studio.vrv"
        });

        Assert.Equal(LegacySceneBackgroundKind.Video, result.BackgroundKind);
        Assert.Equal("studio.vrv", result.BackgroundAssetPath);
        Assert.Equal(2004, result.BackgroundVideoLoopCount);
        Assert.Equal(
            PlayoutAssetRoot.OperatorBackgroundDirectory,
            result.BackgroundAssetRoot);
    }

    [Theory]
    [InlineData("Video:studio.vrv")]
    [InlineData("..\\outside.vrv")]
    [InlineData("Video\\missing.vrv")]
    [InlineData("Video\\studio.exe")]
    public void InvalidOrMissingBackground_FailsBeforeDryRunPrepare(string relativePath)
    {
        using var scenes = TemporarySceneDirectory.Create("5001.t2s");
        var backgroundRoot = Path.Combine(Directory.GetParent(scenes.Path)!.FullName, "배경");
        Directory.CreateDirectory(backgroundRoot);
        Directory.CreateDirectory(Path.Combine(backgroundRoot, "Video"));
        File.WriteAllText(
            Path.Combine(backgroundRoot, "Video", "studio.vrv"),
            "trusted background");
        var options = new PlayoutOptions
        {
            Mode = PlayoutMode.DryRun,
            SceneDirectory = scenes.Path,
            LegacySceneBackgroundKind = LegacySceneBackgroundKind.Video,
            LegacySceneBackgroundAssetPath = relativePath
        };

        Assert.Throws<PlayoutConfigurationException>(() =>
            PlayoutSceneCompositionFactory.Create(options));
    }

    [Fact]
    public void LegacyDefault_UsesSiblingBackgroundRoot_NotTheCutsRoot()
    {
        using var scenes = TemporarySceneDirectory.Create("기본.vrv");
        var backgroundRoot = Path.Combine(Directory.GetParent(scenes.Path)!.FullName, "배경");
        Directory.CreateDirectory(backgroundRoot);
        File.WriteAllText(
            Path.Combine(backgroundRoot, PlayoutSceneCompositionFactory.LegacyDefaultBackgroundFileName),
            "trusted background");

        var result = PlayoutSceneCompositionFactory.CreateLegacyDefault(
            new PlayoutOptions { SceneDirectory = scenes.Path },
            fadeDuration: 6);

        Assert.Equal("기본.vrv", result.BackgroundAssetPath);
        Assert.Equal(PlayoutAssetRoot.OperatorBackgroundDirectory, result.BackgroundAssetRoot);
    }

    [Fact]
    public void LegacyDefault_MissingSiblingDirectory_FailsClosed()
    {
        using var scenes = TemporarySceneDirectory.Create("기본.vrv");

        Assert.Throws<PlayoutConfigurationException>(() =>
            PlayoutSceneCompositionFactory.CreateLegacyDefault(
                new PlayoutOptions { SceneDirectory = scenes.Path },
                fadeDuration: 6));
    }

    [Fact]
    public void LegacyStartupDefault_UsesCutsVideo_NotSiblingBackgroundRoot()
    {
        using var scenes = TemporarySceneDirectory.Create(
            "5001.t2s",
            PlayoutSceneCompositionFactory.LegacyStartupDefaultBackgroundAssetPath);
        var backgroundRoot = Path.Combine(Directory.GetParent(scenes.Path)!.FullName, "배경");
        Directory.CreateDirectory(backgroundRoot);
        File.WriteAllText(
            Path.Combine(
                backgroundRoot,
                PlayoutSceneCompositionFactory.LegacyDefaultBackgroundFileName),
            "trusted F2/F3 background");

        var result = PlayoutSceneCompositionFactory.CreateLegacyStartupDefault(
            new PlayoutOptions { SceneDirectory = scenes.Path },
            fadeDuration: 6);

        Assert.Equal(@"video\기본.vrv", result.BackgroundAssetPath);
        Assert.Equal(PlayoutAssetRoot.SceneDirectory, result.BackgroundAssetRoot);
    }

    [Fact]
    public void LegacyStartupDefault_MissingCutsVideo_FailsEvenWhenSiblingDefaultExists()
    {
        using var scenes = TemporarySceneDirectory.Create("5001.t2s");
        var backgroundRoot = Path.Combine(Directory.GetParent(scenes.Path)!.FullName, "배경");
        Directory.CreateDirectory(backgroundRoot);
        File.WriteAllText(
            Path.Combine(
                backgroundRoot,
                PlayoutSceneCompositionFactory.LegacyDefaultBackgroundFileName),
            "trusted F2/F3 background");

        Assert.Throws<PlayoutConfigurationException>(() =>
            PlayoutSceneCompositionFactory.CreateLegacyStartupDefault(
                new PlayoutOptions { SceneDirectory = scenes.Path },
                fadeDuration: 6));
    }
}
