using Inspectron.Epson.TemplateEngine.Rendering;

namespace Inspectron.Epson.TemplateEngine.Tests;

public class LayoutEngineTests
{
    private readonly LayoutEngine _engine = new();

    [Fact]
    public void AlignText_Center()
    {
        var result = _engine.AlignText("Hello", "center", 20);
        Assert.Equal("       Hello", result);
    }

    [Fact]
    public void AlignText_Right()
    {
        var result = _engine.AlignText("Hello", "right", 20);
        Assert.Equal("               Hello", result);
    }

    [Fact]
    public void AlignText_Left()
    {
        var result = _engine.AlignText("Hello", "left", 20);
        Assert.Equal("Hello", result);
    }

    [Fact]
    public void AlignText_TextExceedsWidth_NoChange()
    {
        var result = _engine.AlignText("Very long text", "center", 5);
        Assert.Equal("Very long text", result);
    }

    [Fact]
    public void FormatTwoColumns_BasicLayout()
    {
        var result = _engine.FormatTwoColumns("Left", "Right", 20);
        Assert.Equal(20, result.Length);
        Assert.StartsWith("Left", result);
        Assert.EndsWith("Right", result);
    }

    [Fact]
    public void FormatTwoColumnsWithWrap_ShortText_SingleLine()
    {
        var result = _engine.FormatTwoColumnsWithWrap("Left", "Right", 20);
        Assert.Single(result);
        Assert.Contains("Left", result[0]);
        Assert.Contains("Right", result[0]);
    }

    [Fact]
    public void FormatTwoColumnsWithWrap_LongLeft_MultipleLines()
    {
        var result = _engine.FormatTwoColumnsWithWrap(
            "This is a very long left column text that needs wrapping",
            "9.50",
            30);
        Assert.True(result.Count >= 1);
        Assert.Contains("9.50", result[0]);
    }

    [Fact]
    public void WrapText_ShortText_SingleLine()
    {
        var result = _engine.WrapText("Hello world", 20);
        Assert.Single(result);
        Assert.Equal("Hello world", result[0]);
    }

    [Fact]
    public void WrapText_LongText_MultipleLines()
    {
        var result = _engine.WrapText("The quick brown fox jumps over the lazy dog", 20);
        Assert.True(result.Count > 1);
        foreach (var line in result)
        {
            Assert.True(line.TrimStart().Length <= 20);
        }
    }

    [Fact]
    public void WrapText_WithIndent()
    {
        var result = _engine.WrapText("The quick brown fox jumps over the lazy dog", 20, indent: 4);
        Assert.True(result.Count > 1);
        // First line no indent
        Assert.False(result[0].StartsWith("    "));
        // Subsequent lines indented
        for (int i = 1; i < result.Count; i++)
        {
            Assert.StartsWith("    ", result[i]);
        }
    }

    [Fact]
    public void CreateSeparator()
    {
        var result = _engine.CreateSeparator('-', 42);
        Assert.Equal(new string('-', 42), result);
    }

    [Fact]
    public void CreateSeparator_CustomChar()
    {
        var result = _engine.CreateSeparator('*', 20);
        Assert.Equal(new string('*', 20), result);
    }

    [Fact]
    public void FormatMultiColumn_BasicLayout()
    {
        var columns = new List<(string text, int width, string align)>
        {
            ("Col1", 10, "left"),
            ("Col2", 10, "right"),
            ("Col3", 10, "center")
        };

        var result = _engine.FormatMultiColumn(columns, 30);
        Assert.Equal(30, result.Length);
    }

    [Fact]
    public void FormatTable_BasicTable()
    {
        var columns = new List<(string text, int width, string align)>
        {
            ("Name", 10, "left"),
            ("Value", 10, "right")
        };

        var headers = new List<List<string>> { new() { "Name", "Value" } };
        var data = new List<List<string>>
        {
            new() { "Item1", "100" },
            new() { "Item2", "200" }
        };

        var result = _engine.FormatTable(columns, headers, data, 23);

        // Should have: top border, header row, separator, 2 data rows, bottom border
        Assert.Equal(6, result.Count);
        Assert.StartsWith("+", result[0]);
        Assert.StartsWith("|", result[1]);
        Assert.StartsWith("+", result[2]);
        Assert.StartsWith("|", result[3]);
        Assert.StartsWith("|", result[4]);
        Assert.StartsWith("+", result[5]);
    }
}
