using Autodesk.Navisworks.Api;
using System.Numerics;

namespace NavisworksTransport.Utils.CoordinateSystem
{
    /// <summary>
    /// Y轴向上坐标系实现（常见于 Revit 等软件导出）
    /// X = Right, Y = Up, Z = Front
    /// </summary>
    public class YUpCoordinateSystem : ICoordinateSystem
    {
        private static readonly HostCoordinateAdapter Adapter = new HostCoordinateAdapter(CoordinateSystemType.YUp);

        public CoordinateSystemType Type => CoordinateSystemType.YUp;
        
        public Vector3D UpVector => new Vector3D(0, 1, 0);
        
        public int UpAxisIndex => 1;  // Y轴向上
        
        public Vector3D VerticalScanDirection => new Vector3D(0, -1, 0);
        
        public double GetElevation(Point3D point)
        {
            return HostPlanarGridHelper.GetElevation3(ToVector3(point), Adapter);
        }
        
        public Point3D SetElevation(Point3D point, double elevation)
        {
            return ToPoint3D(HostPlanarGridHelper.SetElevation3(ToVector3(point), elevation, Adapter));
        }
        
        public (double h1, double h2) GetHorizontalCoords(Point3D point)
        {
            return HostPlanarGridHelper.GetHorizontalCoords3(ToVector3(point), Adapter);
        }
        
        public Point3D CreatePoint(double h1, double h2, double elevation)
        {
            return ToPoint3D(HostPlanarGridHelper.CreateHostPoint3(h1, h2, elevation, Adapter));
        }
        
        public (double min, double max) GetHeightRange(BoundingBox3D bounds)
        {
            return (bounds.Min.Y, bounds.Max.Y);
        }
        
        public (double min1, double max1, double min2, double max2) GetHorizontalRange(BoundingBox3D bounds)
        {
            return HostPlanarGridHelper.GetHorizontalRange3(ToVector3(bounds.Min), ToVector3(bounds.Max), Adapter);
        }
        
        public override string ToString()
        {
            return "Y-Up 坐标系 (Y轴向上)";
        }

        private static Vector3 ToVector3(Point3D point)
        {
            return new Vector3((float)point.X, (float)point.Y, (float)point.Z);
        }

        private static Point3D ToPoint3D(Vector3 point)
        {
            return new Point3D(point.X, point.Y, point.Z);
        }
    }
}
