using Inspectron.Epson.PrintServer.Printers.Utils;

namespace Inspectron.Epson.Templates.Tests.Helpers;

public static class PrintCommandAssertions
{
    public static void AssertCommandExists(
        List<PrintCommand> commands,
        string textContains,
        bool? isBold = null,
        bool? isBig = null,
        bool? isTall = null,
        bool? isRed = null)
    {
        var matching = commands.Where(c => c.Text.Contains(textContains)).ToList();

        if (matching.Count == 0)
        {
            throw new Xunit.Sdk.XunitException($"No command found containing text: '{textContains}'");
        }

        foreach (var cmd in matching)
        {
            if (isBold.HasValue && cmd.IsBold != isBold.Value)
            {
                throw new Xunit.Sdk.XunitException(
                    $"Command with text '{textContains}' has IsBold={cmd.IsBold}, expected {isBold.Value}");
            }
            if (isBig.HasValue && cmd.IsBig != isBig.Value)
            {
                throw new Xunit.Sdk.XunitException(
                    $"Command with text '{textContains}' has IsBig={cmd.IsBig}, expected {isBig.Value}");
            }
            if (isTall.HasValue && cmd.IsTall != isTall.Value)
            {
                throw new Xunit.Sdk.XunitException(
                    $"Command with text '{textContains}' has IsTall={cmd.IsTall}, expected {isTall.Value}");
            }
            if (isRed.HasValue && cmd.IsRed != isRed.Value)
            {
                throw new Xunit.Sdk.XunitException(
                    $"Command with text '{textContains}' has IsRed={cmd.IsRed}, expected {isRed.Value}");
            }
        }
    }

    public static void AssertSequence(List<PrintCommand> commands, params string[] expectedTexts)
    {
        var commandTexts = commands.Select(c => c.Text).ToList();
        int searchIndex = 0;

        foreach (var expected in expectedTexts)
        {
            var foundIndex = -1;
            for (int i = searchIndex; i < commandTexts.Count; i++)
            {
                if (commandTexts[i].Contains(expected))
                {
                    foundIndex = i;
                    break;
                }
            }

            if (foundIndex < 0)
            {
                throw new Xunit.Sdk.XunitException(
                    $"Expected text '{expected}' not found in sequence after index {searchIndex}");
            }

            searchIndex = foundIndex + 1;
        }
    }

    public static void AssertCommandCount(List<PrintCommand> commands, string textContains, int expectedCount)
    {
        var count = commands.Count(c => c.Text.Contains(textContains));
        if (count != expectedCount)
        {
            throw new Xunit.Sdk.XunitException(
                $"Expected {expectedCount} commands containing '{textContains}', found {count}");
        }
    }
}
