using Ehwrj.Core.Models;

namespace Ehwrj.Core.Geometry;

public static class CoordinateProjector
{
    public static ProjectedPoint? Project(MapObject obj, MapInfo mapInfo, MapViewport viewport)
    {
        if (!obj.X.HasValue || !obj.Y.HasValue || viewport.Width <= 0 || viewport.Height <= 0)
        {
            return null;
        }

        var x = Normalize(obj.X.Value, mapInfo.MinX, mapInfo.MaxX);
        var y = Normalize(obj.Y.Value, mapInfo.MinY, mapInfo.MaxY);

        return new ProjectedPoint(
            viewport.Left + x * viewport.Width,
            viewport.Top + y * viewport.Height);
    }

    public static double ApproximateDistanceKm(MapObject a, MapObject b)
    {
        if (!a.X.HasValue || !a.Y.HasValue || !b.X.HasValue || !b.Y.HasValue)
        {
            return double.NaN;
        }

        var dx = a.X.Value - b.X.Value;
        var dy = a.Y.Value - b.Y.Value;
        return Math.Sqrt(dx * dx + dy * dy) * 100;
    }

    private static double Normalize(double value, double? min, double? max)
    {
        if (min.HasValue && max.HasValue && Math.Abs(max.Value - min.Value) > double.Epsilon)
        {
            return Math.Clamp((value - min.Value) / (max.Value - min.Value), 0, 1);
        }

        if (value is >= 0 and <= 1)
        {
            return value;
        }

        return Math.Clamp((value + 1) / 2, 0, 1);
    }
}

