using OpenTK.Mathematics;

namespace DoomDeathmatch.Component.Util.Collision;

public class AABBCollider
{
  public Vector3 Size { get; set; }
  public Vector3 Position { get; set; }

  public Vector3 Max => Position + Size / 2;
  public Vector3 Min => Position - Size / 2;

  public bool Intersects(AABBCollider parCollider)
  {
    var max = Max;
    var min = Min;
    var otherMax = parCollider.Max;
    var otherMin = parCollider.Min;

    return max.X >= otherMin.X && min.X <= otherMax.X && max.Y >= otherMin.Y && min.Y <= otherMax.Y &&
           max.Z >= otherMin.Z && min.Z <= otherMax.Z;
  }

  public Vector3 GetCollisionNormal(AABBCollider parOther)
  {
    var normal = Vector3.Zero;
    var diff = parOther.Position - Position;

    // Calculate penetration depths for each axis
    var penX = (Size.X / 2 + parOther.Size.X / 2) - Math.Abs(diff.X);
    var penY = (Size.Y / 2 + parOther.Size.Y / 2) - Math.Abs(diff.Y);
    var penZ = (Size.Z / 2 + parOther.Size.Z / 2) - Math.Abs(diff.Z);

    // Use the axis with the smallest penetration
    if (penX < penY && penX < penZ)
    {
      var sign = Math.Sign(diff.X);
      normal.X = sign == 0 ? 1 : sign;
    }
    else if (penY < penX && penY < penZ)
    {
      var sign = Math.Sign(diff.Y);
      normal.Y = sign == 0 ? 1 : sign;
    }
    else
    {
      var sign = Math.Sign(diff.Z);
      normal.Z = sign == 0 ? 1 : sign;
    }

    return normal.Normalized();
  }
}