namespace Theriapolis.Core.Util;

/// <summary>
/// Lightweight 2D float vector for world-pixel-space polyline coordinates.
/// Intentionally avoids System.Numerics to keep Core dependency-free.
/// </summary>
public readonly struct Vec2
{
    public readonly float X;
    public readonly float Y;

    public Vec2(float x, float y) { X = x; Y = y; }

    public static Vec2 operator +(Vec2 a, Vec2 b) => new(a.X + b.X, a.Y + b.Y);
    public static Vec2 operator -(Vec2 a, Vec2 b) => new(a.X - b.X, a.Y - b.Y);
    public static Vec2 operator *(Vec2 a, float s) => new(a.X * s, a.Y * s);
    public static Vec2 operator *(float s, Vec2 a) => new(a.X * s, a.Y * s);
    public static Vec2 operator /(Vec2 a, float s) => new(a.X / s, a.Y / s);

    public float LengthSquared => X * X + Y * Y;
    public float Length => MathF.Sqrt(LengthSquared);

    public Vec2 Normalized
    {
        get
        {
            float len = Length;
            return len < 1e-6f ? new Vec2(0, 0) : this * (1f / len);
        }
    }

    /// <summary>90° CCW rotation — perpendicular vector.</summary>
    public Vec2 Perp => new(-Y, X);

    public static float Dot(Vec2 a, Vec2 b) => a.X * b.X + a.Y * b.Y;
    public static float DistSq(Vec2 a, Vec2 b) => (a - b).LengthSquared;
    public static float Dist(Vec2 a, Vec2 b) => (a - b).Length;

    /// <summary>Linear interpolation between a and b at parameter t.</summary>
    public static Vec2 Lerp(Vec2 a, Vec2 b, float t) => a + (b - a) * t;

    public override string ToString() => $"({X:F1}, {Y:F1})";
}
