using System;
using Autodesk.Navisworks.Api;

namespace NavisworksTransport.Utils
{
    /// <summary>
    /// ModelItem变换辅助工具
    /// 提供临时移动和恢复物体位置的通用方法
    /// </summary>
    public static class ModelItemTransformHelper
    {
        /// <summary>
        /// 临时移动物体到指定位置
        /// </summary>
        /// <param name="item">要移动的物体</param>
        /// <param name="targetPosition">目标位置（物体中心）</param>
        /// <returns>用于恢复的偏移向量</returns>
        public static Vector3D MoveItemToPosition(ModelItem item, Point3D targetPosition)
        {
            var doc = Application.ActiveDocument;
            var modelItems = new ModelItemCollection { item };

            // 计算当前中心位置
            var currentBounds = item.BoundingBox();
            var currentPos = new Point3D(
                (currentBounds.Min.X + currentBounds.Max.X) / 2,
                (currentBounds.Min.Y + currentBounds.Max.Y) / 2,
                (currentBounds.Min.Z + currentBounds.Max.Z) / 2
            );

            // 计算偏移
            var offset = new Vector3D(
                targetPosition.X - currentPos.X,
                targetPosition.Y - currentPos.Y,
                targetPosition.Z - currentPos.Z
            );

            // 应用变换
            var transform = Transform3D.CreateTranslation(offset);
            doc.Models.OverridePermanentTransform(modelItems, transform, false);

            return offset;
        }

        /// <summary>
        /// 从Transform3D中提取Yaw角度（绕Z轴旋转，单位：弧度）
        /// </summary>
        /// <param name="transform">变换矩阵</param>
        /// <returns>Yaw角度（弧度）</returns>
        public static double GetYawFromTransform(Transform3D transform)
        {
            if (transform == null) return 0.0;

            try
            {
                // 获取变换的组件
                var components = transform.Factor();
                var rotation = components.Rotation;

                // 使用ToAxisAndAngle()提取轴和角度
                var rotationResult = rotation.ToAxisAndAngle();
                double angle = rotationResult.Angle;
                double ux = rotationResult.Axis.X;
                double uy = rotationResult.Axis.Y;
                double uz = rotationResult.Axis.Z;

                // 旋转公式（罗德里格旋转公式简化版，提取局部X轴(1,0,0)旋转后的方向）
                // 旋转后的向量 v' = v*cosθ + (u×v)*sinθ + u*(u·v)*(1-cosθ)
                // 当 v = (1,0,0) 时:
                // v'.x = cosθ + ux*ux*(1-cosθ)
                // v'.y = uz*sinθ + ux*uy*(1-cosθ)

                double cos = Math.Cos(angle);
                double sin = Math.Sin(angle);

                // 计算旋转后的X轴在世界坐标系XY平面上的分量
                double vx = cos + ux * ux * (1 - cos);
                double vy = uz * sin + ux * uy * (1 - cos);

                // 在XY平面上通过Atan2计算偏航角
                return Math.Atan2(vy, vx);
            }
            catch (Exception)
            {
                return 0.0;
            }
        }

        /// <summary>
        /// 恢复物体到原位置
        /// </summary>
        /// <param name="item">要恢复的物体</param>
        /// <param name="originalOffset">原始移动偏移向量</param>
        public static void RestoreItemPosition(ModelItem item, Vector3D originalOffset)
        {
            var doc = Application.ActiveDocument;
            var modelItems = new ModelItemCollection { item };

            // 反向偏移
            var restoreOffset = new Vector3D(-originalOffset.X, -originalOffset.Y, -originalOffset.Z);
            var restoreTransform = Transform3D.CreateTranslation(restoreOffset);
            doc.Models.OverridePermanentTransform(modelItems, restoreTransform, false);
        }
    }
}
