using NeonSprawl.Server.Game.PositionState;
using NeonSprawl.Server.Game.World;

namespace NeonSprawl.Server.Game.Targeting;

/// <summary>Computes <see cref="PlayerTargetStateResponse.Validity"/> from authoritative position + persisted lock (NEO-23).</summary>
public static class PlayerTargetStateReader
{
    public static string ComputeValidity(string? lockIdLowercase, in PositionSnapshot snap)
    {
        if (string.IsNullOrEmpty(lockIdLowercase))
        {
            return TargetValidity.None;
        }

        if (!PrototypeTargetRegistry.TryGet(lockIdLowercase, out var entry))
        {
            return TargetValidity.InvalidTarget;
        }

        if (!HorizontalReach.IsWithinHorizontalRadius(snap.X, snap.Z, entry.X, entry.Z, entry.LockRadius))
        {
            return TargetValidity.OutOfRange;
        }

        return TargetValidity.Ok;
    }

    public static PlayerTargetStateResponse Build(string routePlayerId, string? lockIdLowercase, int sequence, in PositionSnapshot snap) =>
        new()
        {
            SchemaVersion = PlayerTargetStateResponse.CurrentSchemaVersion,
            PlayerId = routePlayerId,
            LockedTargetId = lockIdLowercase,
            Validity = ComputeValidity(lockIdLowercase, in snap),
            Sequence = sequence,
        };
}
