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

namespace NavisworksTransport.Utils.CoordinateSystem
{
    /// <summary>
    /// 工程业务基准框架。
    /// 
    /// 该对象建立在 Canonical Space 之上，用来承载：
    /// - 球心
    /// - 项目 up 方向
    /// - 后续的终端安装基准和轨道参考面
    /// 
    /// 注意：
    /// - 这不是宿主坐标系定义
    /// - 这不是 Navisworks 世界坐标
    /// - 这是业务语义层
    /// </summary>
    public sealed class ProjectReferenceFrame
    {
        private readonly Vector3 _sphereCenterInCanonical;
        private readonly Vector3 _projectUpInCanonical;

        /// <summary>
        /// Canonical Space 中的球心坐标。
        /// </summary>
        public Vector3 SphereCenterInCanonical3 => _sphereCenterInCanonical;
        public Point3D SphereCenterInCanonical => new Point3D(_sphereCenterInCanonical.X, _sphereCenterInCanonical.Y, _sphereCenterInCanonical.Z);

        /// <summary>
        /// Canonical Space 中的项目上方向。
        /// 当前固定与 Canonical Space 一致，为 (0,0,1)。
        /// </summary>
        public Vector3 ProjectUpInCanonical3 => _projectUpInCanonical;
        public Vector3D ProjectUpInCanonical => new Vector3D(_projectUpInCanonical.X, _projectUpInCanonical.Y, _projectUpInCanonical.Z);

        /// <summary>
        /// 真实模型默认局部轴约定。
        /// </summary>
        public ModelAxisConvention DefaultModelAxisConvention { get; }

        public ProjectReferenceFrame(
            Point3D sphereCenterInCanonical,
            Vector3D projectUpInCanonical,
            ModelAxisConvention defaultModelAxisConvention)
            : this(
                new Vector3((float)sphereCenterInCanonical.X, (float)sphereCenterInCanonical.Y, (float)sphereCenterInCanonical.Z),
                new Vector3((float)projectUpInCanonical.X, (float)projectUpInCanonical.Y, (float)projectUpInCanonical.Z),
                defaultModelAxisConvention)
        {
        }

        public ProjectReferenceFrame(
            Vector3 sphereCenterInCanonical,
            Vector3 projectUpInCanonical,
            ModelAxisConvention defaultModelAxisConvention)
        {
            if (projectUpInCanonical.LengthSquared() < 1e-12f)
            {
                throw new ArgumentException("项目 up 方向不能为零向量。", nameof(projectUpInCanonical));
            }

            if (defaultModelAxisConvention == null)
            {
                throw new ArgumentNullException(nameof(defaultModelAxisConvention));
            }

            _sphereCenterInCanonical = sphereCenterInCanonical;
            _projectUpInCanonical = Vector3.Normalize(projectUpInCanonical);
            DefaultModelAxisConvention = defaultModelAxisConvention;
        }

        /// <summary>
        /// 创建默认业务基准框架。
        /// 
        /// 说明：
        /// - 当前只是 M1 骨架，先显式使用原点和 CanonicalUp
        /// - 后续应改为来自项目配置或显式求解，不应长期依赖该默认值
        /// </summary>
        public static ProjectReferenceFrame CreateDefault()
        {
            return CreateDefault(CoordinateSystemType.ZUp);
        }

        /// <summary>
        /// 按宿主坐标系创建默认业务基准框架。
        /// </summary>
        public static ProjectReferenceFrame CreateDefault(CoordinateSystemType hostType)
        {
            return new ProjectReferenceFrame(
                Vector3.Zero,
                HostCoordinateAdapter.CanonicalUpVector3,
                ModelAxisConvention.CreateDefaultForHost(hostType));
        }
    }
}
