namespace NeonSprawl.Server.Game.Targeting;

/// <summary>Prototype combat target ids → world anchor + horizontal lock radius (NEO-23). Keys are lowercase.</summary>
public static class PrototypeTargetRegistry
{
    /// <summary>
    /// All prototype combat targets share a single <c>LockRadius</c>. Scoped to prototype
    /// stubs — per-target radii will come back with real combat design (E5.M1). Changing
    /// this requires updating <c>client/scripts/prototype_target_constants.gd</c> in the
    /// same commit so markers/HUD match server range checks.
    /// </summary>
    public const double SharedLockRadius = 6.0;

    /// <summary>On the -x/-z side of spawn; overlaps <see cref="PrototypeTargetBeta"/>'s ring at origin so Tab can flip without moving.</summary>
    public const string PrototypeTargetAlphaId = "prototype_target_alpha";

    /// <summary>On the +x/+z side; mirrors alpha across the origin for symmetric overlap (NEO-24 Tab cycle).</summary>
    public const string PrototypeTargetBetaId = "prototype_target_beta";

    /// <summary>Alpha anchor; <see cref="PrototypeTargetEntry.LockRadius"/> is XZ-only. Distance to beta ~8.49 m ⇒ ~3.5 m overlap at origin.</summary>
    public static readonly PrototypeTargetEntry PrototypeTargetAlpha = new(-3, 0.5, -3, SharedLockRadius);

    public static readonly PrototypeTargetEntry PrototypeTargetBeta = new(3, 0, 3, SharedLockRadius);

    private static readonly Dictionary<string, PrototypeTargetEntry> ById = new(StringComparer.Ordinal)
    {
        [PrototypeTargetAlphaId] = PrototypeTargetAlpha,
        [PrototypeTargetBetaId] = PrototypeTargetBeta,
    };

    public static bool TryGet(string targetIdLowercase, out PrototypeTargetEntry entry) =>
        ById.TryGetValue(targetIdLowercase, out entry);
}

/// <param name="LockRadius">Horizontal reach on X/Z; inclusive boundary (same as NEO-9).</param>
public readonly record struct PrototypeTargetEntry(double X, double Y, double Z, double LockRadius);
