using GmRelay.Web.Services.Portfolio;

namespace GmRelay.Bot.Tests.Web;

public sealed class PortfolioValidationTests
{
    [Theory]
    [InlineData(" Dragon Heist ", "dragon-heist")]
    [InlineData("dragon_heist", "dragon-heist")]
    [InlineData("Dragon  Heist", "dragon-heist")]
    [InlineData("dragon---heist", "dragon-heist")]
    [InlineData("dragon-heist-", "dragon-heist")]
    [InlineData("DRAGON-Heist", "dragon-heist")]
    public void NormalizeSlug_ShouldReturnCanonicalSlug(string input, string expected)
    {
        Assert.Equal(expected, PortfolioValidation.NormalizeSlug(input));
    }

    [Theory]
    [InlineData("")]
    [InlineData("ab")]
    [InlineData("spaces are fine after normalization but this slug is intentionally far too long to be accepted because it exceeds the maximum portfolio slug size of one hundred and sixty characters")]
    [InlineData("кириллица")]
    [InlineData("hello world!")]
    [InlineData("---")]
    public void NormalizeSlug_ShouldRejectInvalidSlug(string input)
    {
        Assert.Throws<InvalidOperationException>(() => PortfolioValidation.NormalizeSlug(input));
    }

    [Theory]
    [InlineData("")]
    [InlineData("  ")]
    [InlineData(null)]
    public void NormalizeReviewBody_ShouldRejectBlankText(string? body)
    {
        Assert.Throws<InvalidOperationException>(() => PortfolioValidation.NormalizeReviewBody(body));
    }

    [Theory]
    [InlineData("This is a perfectly valid review body for the portfolio entry that should pass.")]
    [InlineData("  Another valid review body that meets the minimum length requirement.  ")]
    public void NormalizeReviewBody_ShouldTrimAndAcceptValidText(string body)
    {
        Assert.Equal(body.Trim(), PortfolioValidation.NormalizeReviewBody(body));
    }

    [Theory]
    [InlineData(" Hello World ")]
    [InlineData("abc")]
    public void NormalizeTitle_ShouldTrimAndAcceptValidText(string title)
    {
        Assert.Equal(title.Trim(), PortfolioValidation.NormalizeTitle(title));
    }

    [Theory]
    [InlineData("")]
    [InlineData("a")]
    public void NormalizeTitle_ShouldRejectTooShort(string title)
    {
        Assert.Throws<InvalidOperationException>(() => PortfolioValidation.NormalizeTitle(title));
    }

    [Fact]
    public void NormalizeDescription_ShouldReturnNullForWhitespace()
    {
        Assert.Null(PortfolioValidation.NormalizeDescription(null));
        Assert.Null(PortfolioValidation.NormalizeDescription(""));
        Assert.Null(PortfolioValidation.NormalizeDescription("   "));
    }

    [Fact]
    public void NormalizeDescription_ShouldTrimAndAcceptValidText()
    {
        Assert.Equal("hello", PortfolioValidation.NormalizeDescription(" hello "));
    }

    [Theory]
    [InlineData("Online")]
    [InlineData("Offline")]
    [InlineData("Hybrid")]
    public void NormalizeFormat_ShouldAcceptKnownValues(string format)
    {
        Assert.Equal(format, PortfolioValidation.NormalizeFormat(format));
    }

    [Theory]
    [InlineData("")]
    [InlineData("  ")]
    [InlineData(null)]
    public void NormalizeFormat_ShouldReturnNullForBlank(string? format)
    {
        Assert.Null(PortfolioValidation.NormalizeFormat(format));
    }

    [Theory]
    [InlineData("online")]
    [InlineData("VTT")]
    public void NormalizeFormat_ShouldRejectUnknownValues(string format)
    {
        Assert.Throws<InvalidOperationException>(() => PortfolioValidation.NormalizeFormat(format));
    }
}
