using NeonSprawl.Server.Game.World;
using Xunit;

namespace NeonSprawl.Server.Tests.Game.Interaction;

public class HorizontalReachTests
{
    [Fact]
    public void HorizontalDistance_IgnoresY()
    {
        // Arrange
        // Y is not a parameter; identical X/Z -> zero horizontal separation regardless of implied height difference.

        // Act
        var d = HorizontalReach.HorizontalDistance(1, 2, 1, 2);

        // Assert
        Assert.Equal(0, d);
    }

    [Fact]
    public void IsWithinHorizontalRadius_AtExactBoundary_ReturnsTrue()
    {
        // Arrange

        // Act
        var isInRange = HorizontalReach.IsWithinHorizontalRadius(0, 0, 3, 0, 3);

        // Assert
        Assert.True(isInRange);
    }

    [Fact]
    public void IsWithinHorizontalRadius_JustInside_ReturnsTrue()
    {
        // Arrange
        const double radius = 3.0;
        const double eps = 1e-10;

        // Act
        var isInRange = HorizontalReach.IsWithinHorizontalRadius(0, 0, radius - eps, 0, radius);

        // Assert
        Assert.True(isInRange);
    }

    [Fact]
    public void IsWithinHorizontalRadius_JustOutside_ReturnsFalse()
    {
        // Arrange
        const double radius = 3.0;
        const double eps = 1e-7;

        // Act
        var isInRange = HorizontalReach.IsWithinHorizontalRadius(0, 0, radius + eps, 0, radius);

        // Assert
        Assert.False(isInRange);
    }

    [Fact]
    public void IsWithinHorizontalRadius_NegativeRadius_ThrowsArgumentOutOfRange()
    {
        // Arrange
        Action act = () => HorizontalReach.IsWithinHorizontalRadius(0, 0, 0, 0, -1.0);

        // Act
        var ex = Assert.Throws<ArgumentOutOfRangeException>(act);

        // Assert
        Assert.NotNull(ex);
    }
}
