using System;
using Autodesk.Navisworks.Api;
using NavisworksTransport.Core;
using NavisworksTransport.Core.Animation;
using NavisworksTransport.Utils.CoordinateSystem;

namespace NavisworksTransport.Utils
{
    /// <summary>
    /// 碰撞场景辅助类
    /// 提供碰撞场景还原和截图的通用功能
    /// </summary>
    public static class CollisionSceneHelper
    {
        /// <summary>
        /// 将动画物体移动到碰撞位置并聚焦到碰撞场景
        /// </summary>
        /// <param name="collision">碰撞结果</param>
        /// <param name="animatedObject">动画物体（运动物体）</param>
        public static void MoveToCollisionAndFocus(CollisionResult collision, ModelItem animatedObject)
        {
            if (collision == null) return;
            MoveToCollisionAndFocus(collision.Item2 ?? collision.Item1, animatedObject, 
                collision.AnimatedObjectTrackedPosition, collision.AnimatedObjectTrackedYawRadians, collision.AnimatedObjectTrackedRotation,
                collision.AnimatedObjectHasTrackedRotation, collision.HasPositionInfo);
        }
        
        /// <summary>
        /// 将动画物体移动到碰撞位置并聚焦到碰撞场景（通用版本）
        /// </summary>
        /// <param name="hitObject">被撞对象</param>
        /// <param name="animatedObject">动画物体（运动物体）</param>
        /// <param name="animatedObjectTrackedPosition">动画跟踪点位置</param>
        /// <param name="animatedObjectTrackedYawRadians">动画跟踪点对应的碰撞朝向</param>
        /// <param name="animatedObjectTrackedRotation">动画跟踪点对应的碰撞完整姿态</param>
        /// <param name="animatedObjectHasTrackedRotation">是否有完整姿态</param>
        /// <param name="hasPositionInfo">是否有位置信息</param>
        public static void MoveToCollisionAndFocus(ModelItem hitObject, ModelItem animatedObject, 
            Point3D animatedObjectTrackedPosition, double animatedObjectTrackedYawRadians, Rotation3D animatedObjectTrackedRotation,
            bool animatedObjectHasTrackedRotation, bool hasPositionInfo)
        {
            try
            {
                if (hitObject != null)
                {
                    // 清除之前的高亮
                    ModelHighlightHelper.ClearAllHighlights();
                    
                    // 高亮被撞对象（使用碰撞检测结果专用红色）
                    ModelHighlightHelper.HighlightItems(ModelHighlightHelper.ClashDetectiveResultsCategory, new[] { hitObject });
                    
                    // 聚焦到被撞对象
                    ViewpointHelper.FocusOnModelItem(hitObject, ViewpointHelper.ViewpointStrategy.CollisionCloseUp);
                    
                    LogManager.Info(string.Format("聚焦到被撞对象: {0}", hitObject.DisplayName));
                }
                
                // 移动动画物体到碰撞位置
                if (animatedObject != null && hasPositionInfo && animatedObjectTrackedPosition != null)
                {
                    var pam = PathAnimationManager.GetInstance();
                    bool useAnimationPipeline = pam != null &&
                                                pam.ControlsAnimatedObject(animatedObject);

                    if (useAnimationPipeline)
                    {
                        pam.MoveAnimatedObjectToPose(
                            animatedObject,
                            animatedObjectTrackedPosition,
                            animatedObjectTrackedYawRadians,
                            animatedObjectTrackedRotation ?? Rotation3D.Identity,
                            animatedObjectHasTrackedRotation && animatedObjectTrackedRotation != null);

                        LogManager.Debug(string.Format(
                            "运动物体已通过动画链路移动到碰撞位置: 位置=({0:F2}, {1:F2}, {2:F2}), customRotation={3}",
                            animatedObjectTrackedPosition.X, animatedObjectTrackedPosition.Y, animatedObjectTrackedPosition.Z,
                            animatedObjectHasTrackedRotation && animatedObjectTrackedRotation != null));
                    }
                    else
                    {
                        throw new InvalidOperationException(
                            $"碰撞点恢复必须复用动画主链路，当前对象未受 PathAnimationManager 控制: {animatedObject.DisplayName}");
                    }
                }
            }
            catch (Exception ex)
            {
                LogManager.Error(string.Format("移动并聚焦到碰撞位置失败: {0}", ex.Message), ex);
            }
        }

        /// <summary>
        /// 保存动画物体当前状态
        /// </summary>
        /// <param name="animatedObject">动画物体</param>
        /// <returns>状态快照</returns>
        public static ModelItemTransformHelper.ObjectStateSnapshot SaveAnimatedObjectState(ModelItem animatedObject)
        {
            if (animatedObject == null) return null;

            var pam = PathAnimationManager.GetInstance();
            if (pam == null || !pam.ControlsAnimatedObject(animatedObject))
            {
                throw new InvalidOperationException(
                    $"保存碰撞场景前的动画物体状态必须复用 PathAnimationManager：对象 {animatedObject.DisplayName} 不受当前动画管理器控制。");
            }

            // 从 PathAnimationManager 获取当前实际姿态，不再退回工具层旧 yaw 快照语义。
            var currentYaw = pam.CurrentYaw;
            var currentRotation = pam.TrackedRotation;
            var hasCustomRotation = pam.HasTrackedRotation;
            var currentState = pam.GetObjectCurrentPosition(animatedObject);
            pam.SaveObjectState(animatedObject);

            var state = new ModelItemTransformHelper.ObjectStateSnapshot
            {
                Position = currentState.Position,
                Rotation = currentRotation,
                HasCustomRotation = hasCustomRotation
            };

            LogManager.Info(string.Format("已保存动画物体状态: {0}, 位置=({1:F2},{2:F2},{3:F2}), 朝向={4:F2}°, customRotation={5}", 
                animatedObject.DisplayName, state.Position.X, state.Position.Y, state.Position.Z, 
                currentYaw * 180 / Math.PI, state.HasCustomRotation));
            if (state.HasCustomRotation && state.Rotation != null)
            {
                var linear = new Transform3D(state.Rotation).Linear;
                LogManager.Info(string.Format(
                    "[报告姿态保存] {0} 保存姿态: " +
                    "位置=({1:F3},{2:F3},{3:F3}), " +
                    "X=({4:F4},{5:F4},{6:F4}), " +
                    "Y=({7:F4},{8:F4},{9:F4}), " +
                    "Z=({10:F4},{11:F4},{12:F4})",
                    animatedObject.DisplayName,
                    state.Position.X, state.Position.Y, state.Position.Z,
                    linear.Get(0, 0), linear.Get(1, 0), linear.Get(2, 0),
                    linear.Get(0, 1), linear.Get(1, 1), linear.Get(2, 1),
                    linear.Get(0, 2), linear.Get(1, 2), linear.Get(2, 2)));
            }

            return state;
        }

        /// <summary>
        /// 恢复动画物体到保存的状态
        /// </summary>
        /// <param name="animatedObject">动画物体</param>
        /// <param name="state">状态快照</param>
        public static void RestoreAnimatedObjectState(ModelItem animatedObject, ModelItemTransformHelper.ObjectStateSnapshot state)
        {
            if (animatedObject == null || state == null) return;

            if (state.HasCustomRotation && state.Rotation != null)
            {
                var linear = new Transform3D(state.Rotation).Linear;
                LogManager.Info(string.Format(
                    "[报告姿态恢复] {0} 恢复目标姿态: " +
                    "位置=({1:F3},{2:F3},{3:F3}), " +
                    "X=({4:F4},{5:F4},{6:F4}), " +
                    "Y=({7:F4},{8:F4},{9:F4}), " +
                    "Z=({10:F4},{11:F4},{12:F4})",
                    animatedObject.DisplayName,
                    state.Position.X, state.Position.Y, state.Position.Z,
                    linear.Get(0, 0), linear.Get(1, 0), linear.Get(2, 0),
                    linear.Get(0, 1), linear.Get(1, 1), linear.Get(2, 1),
                    linear.Get(0, 2), linear.Get(1, 2), linear.Get(2, 2)));
            }

            var pam = PathAnimationManager.GetInstance();
            if (pam == null || !pam.ControlsAnimatedObject(animatedObject))
            {
                throw new InvalidOperationException(
                    $"恢复碰撞场景前的动画物体状态必须复用 PathAnimationManager：对象 {animatedObject.DisplayName} 不受当前动画管理器控制。");
            }

            pam.RestoreAnimatedObjectState(animatedObject);
            LogManager.Info(string.Format(
                "动画物体已通过PathAnimationManager恢复状态: {0}, customRotation={1}",
                animatedObject.DisplayName,
                state.HasCustomRotation));
        }
    }
}
