using Theriapolis.Core.Rules.Stats;
using Xunit;

namespace Theriapolis.Tests.Rules;

public sealed class XpTableTests
{
    [Theory]
    [InlineData(0,         1)]
    [InlineData(1,         1)]
    [InlineData(299,       1)]
    [InlineData(300,       2)]
    [InlineData(899,       2)]
    [InlineData(900,       3)]
    [InlineData(2_700,     4)]
    [InlineData(355_000,  20)]
    [InlineData(1_000_000,20)]
    public void LevelForXp_MatchesD20Table(int xp, int expectedLevel)
    {
        Assert.Equal(expectedLevel, XpTable.LevelForXp(xp));
    }

    [Fact]
    public void LevelForXp_NegativeThrows()
    {
        Assert.Throws<ArgumentOutOfRangeException>(() => XpTable.LevelForXp(-1));
    }

    [Theory]
    [InlineData(1,    300)]
    [InlineData(2,    900)]
    [InlineData(19,   355_000)]
    public void XpRequiredForNextLevel_MatchesTable(int currentLevel, int expectedNext)
    {
        Assert.Equal(expectedNext, XpTable.XpRequiredForNextLevel(currentLevel));
    }

    [Fact]
    public void XpRequiredForNextLevel_AtCap_ReturnsMaxValue()
    {
        Assert.Equal(int.MaxValue, XpTable.XpRequiredForNextLevel(20));
    }

    [Fact]
    public void Threshold_IsMonotonicallyIncreasing()
    {
        for (int lv = 2; lv <= 20; lv++)
            Assert.True(XpTable.Threshold[lv] > XpTable.Threshold[lv - 1],
                $"Threshold[{lv}]={XpTable.Threshold[lv]} should be > Threshold[{lv-1}]={XpTable.Threshold[lv-1]}");
    }
}
