using NeonSprawl.Server.Game.PositionState;
using NeonSprawl.Server.Game.Targeting;
using Xunit;

namespace NeonSprawl.Server.Tests.Game.Targeting;

public class PlayerTargetStateReaderTests
{
    [Fact]
    public void ComputeValidity_ShouldReturnInvalidTarget_WhenLockIdNotInRegistry()
    {
        // Arrange

        var snap = new PositionSnapshot(0, 0, 0, 0);
        // Act
        var validity = PlayerTargetStateReader.ComputeValidity("not_in_registry", in snap);
        // Assert
        Assert.Equal(TargetValidity.InvalidTarget, validity);
    }

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

        var snap = new PositionSnapshot(0, 0, 0, 0);
        // Act
        var validity = PlayerTargetStateReader.ComputeValidity(null, in snap);
        // Assert
        Assert.Equal(TargetValidity.None, validity);
    }

    [Fact]
    public void ComputeValidity_AtExactLockRadius_ReturnsOk()
    {
        // Arrange
        // Alpha anchor XZ (-3, -3), lockRadius 6 -> horizontal distance 6 from (3, -3) is on boundary (inclusive).
        var snap = new PositionSnapshot(3, 0, -3, 0);
        // Act
        var validity = PlayerTargetStateReader.ComputeValidity(PrototypeTargetRegistry.PrototypeTargetAlphaId, in snap);
        // Assert
        Assert.Equal(TargetValidity.Ok, validity);
    }

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

        const double eps = 1e-6;
        var snap = new PositionSnapshot(3 + eps, 0, -3, 0);
        // Act
        var validity = PlayerTargetStateReader.ComputeValidity(PrototypeTargetRegistry.PrototypeTargetAlphaId, in snap);
        // Assert
        Assert.Equal(TargetValidity.OutOfRange, validity);
    }

    [Fact]
    public void ComputeValidity_AtOrigin_ShouldReturnOk_ForBothPrototypeTargets()
    {
        // Arrange
        // NEO-24 post-merge: alpha (-3,-3) r=6 and beta (3,3) r=6 overlap at origin so Tab can
        // flip without locomotion. Origin is ~4.24 m from each anchor (< 6 m).
        var snap = new PositionSnapshot(0, 0, 0, 0);
        // Act
        var alphaValidity = PlayerTargetStateReader.ComputeValidity(PrototypeTargetRegistry.PrototypeTargetAlphaId, in snap);
        var betaValidity = PlayerTargetStateReader.ComputeValidity(PrototypeTargetRegistry.PrototypeTargetBetaId, in snap);
        // Assert
        Assert.Equal(TargetValidity.Ok, alphaValidity);
        Assert.Equal(TargetValidity.Ok, betaValidity);
    }
}
