using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Input;
using Autodesk.Navisworks.Api;
using Autodesk.Navisworks.Api.Clash;
using NavisworksTransport.Core;
using NavisworksTransport.Commands;
using NavisworksTransport.UI.WPF.Collections;
using NavisworksTransport.Utils;
using Color = Autodesk.Navisworks.Api.Color;

namespace NavisworksTransport.UI.WPF.ViewModels
{
    /// <summary>
    /// 碰撞报告数据
    /// </summary>
    public class CollisionReportData
    {
        public bool IsValid { get; set; }
        public string ErrorMessage { get; set; } = string.Empty;
        public DateTime GeneratedTime { get; set; }
        public string AnimatedObjectName { get; set; } = string.Empty;
        public string PathName { get; set; } = string.Empty;
        public int TotalTests { get; set; }
        public int TotalCollisions { get; set; }
        public List<CollisionTestInfo> Tests { get; set; } = new List<CollisionTestInfo>();
    }

    /// <summary>
    /// 碰撞测试信息
    /// </summary>
    public class CollisionTestInfo
    {
        public string TestName { get; set; } = string.Empty;
        public string TestType { get; set; } = string.Empty;
        public double Tolerance { get; set; }
        public int CollisionCount { get; set; }
        public string Status { get; set; } = string.Empty;
        public List<CollisionDetailInfo> Collisions { get; set; } = new List<CollisionDetailInfo>();
    }

    /// <summary>
    /// 碰撞详细信息
    /// </summary>
    public class CollisionDetailInfo
    {
        public string CollisionId { get; set; } = string.Empty;
        public string Object1Name { get; set; } = string.Empty;
        public string Object1Position { get; set; } = string.Empty;
        public string Object2Name { get; set; } = string.Empty;
        public string Object2Position { get; set; } = string.Empty;
        public string CollisionCenter { get; set; } = string.Empty;
        public double Distance { get; set; }
        public string Status { get; set; } = string.Empty;
    }

    /// <summary>
    /// 手工指定的碰撞检测对象
    /// </summary>
    public class ManualCollisionTargetViewModel
    {
        public ManualCollisionTargetViewModel(ModelItem modelItem, string displayName, string modelPath)
        {
            ModelItem = modelItem ?? throw new ArgumentNullException(nameof(modelItem));
            DisplayName = displayName;
            ModelPath = modelPath;
            InstanceGuid = modelItem.InstanceGuid;
        }

        public ModelItem ModelItem { get; }
        public string DisplayName { get; }
        public string ModelPath { get; }
        public Guid InstanceGuid { get; }
    }

    /// <summary>
    /// ClashDetective碰撞检测结果视图模型
    /// </summary>
    public class ClashDetectiveResultViewModel
    {
        private readonly Action _refreshCallback;

        public ClashDetectiveResultViewModel(ClashDetectiveResultRecord record, Action refreshCallback)
        {
            Record = record ?? throw new ArgumentNullException(nameof(record));
            _refreshCallback = refreshCallback ?? throw new ArgumentNullException(nameof(refreshCallback));
            ViewCommand = new RelayCommand(() => ExecuteView());
            ReportCommand = new RelayCommand(() => ExecuteReport());
            DeleteCommand = new RelayCommand(() => ExecuteDelete());
        }

        public ClashDetectiveResultRecord Record { get; }
        public string TestTimeDisplay => Record.TestTime.ToString("HH:mm:ss");
        public string CollisionCountDisplay => $"{Record.CollisionCount}个";
        public ICommand ViewCommand { get; }
        public ICommand ReportCommand { get; }
        public ICommand DeleteCommand { get; }

        private void ExecuteView()
        {
            // 高亮显示该次检测的碰撞对象
            var clashIntegration = ClashDetectiveIntegration.Instance;
            clashIntegration?.HighlightClashDetectiveResults(Record.TestName);
        }

        private void ExecuteReport()
        {
            // 打开该次检测的详细报告
            var command = GenerateCollisionReportCommand.CreateComprehensive(autoHighlight: false);
            command.ExecuteAsync();
        }

        private void ExecuteDelete()
        {
            // 删除该次检测记录
            var pathDatabase = PathPlanningManager.Instance?.GetPathDatabase();
            if (pathDatabase != null)
            {
                pathDatabase.DeleteClashDetectiveResult(Record.Id);
                // 通过回调刷新列表
                _refreshCallback?.Invoke();
            }
        }
    }

    /// <summary>
    /// 动画控制视图模型
    /// 专门处理路径动画播放和碰撞检测功能
    /// </summary>
    public class AnimationControlViewModel : ViewModelBase, IDisposable
    {
        #region 私有字段

        private readonly NavisworksTransport.Core.Animation.PathAnimationManager _pathAnimationManager;
        private readonly ClashDetectiveIntegration _clashIntegration;
        private readonly UIStateManager _uiStateManager;

        // 动画参数相关字段（从配置初始化）
        private ObservableCollection<int> _availableFrameRates;
        private int _selectedFrameRate;
        private double _animationDuration;
        private bool _canStartAnimation = true;
        private bool _canPauseAnimation = false;
        private bool _canStopAnimation = false;

        // 碰撞检测相关字段
        private bool _hasCollisionResults = false;
        private CollisionReportResult _lastGeneratedReport; // 缓存最后生成的报告

        // 碰撞检测参数字段（从配置初始化）
        private double _detectionGap; // 检测间隙(米)
        private int _animationFrameRate; // 动画帧率(FPS)


        // 当前选中路径
        private PathRouteViewModel _currentPathRoute;

        // 移动物体相关字段
        private ModelItem _selectedAnimatedObject;
        private string _selectedAnimatedObjectName = "未选择移动物体";
        private bool _hasSelectedAnimatedObject = false;
        private bool _canGenerateAnimation = false;

        // 虚拟车辆相关字段
        private bool _useSelectedObject = true;      // 默认使用选择物体方式
        private bool _useVirtualVehicle = false;     // 使用虚拟车辆
        private double _virtualVehicleLength = 1.0;  // 虚拟车辆长度（米）
        private double _virtualVehicleWidth = 1.0;   // 虚拟车辆宽度（米）
        private double _virtualVehicleHeight = 2.0;  // 虚拟车辆高度（米）

        // 手工碰撞对象相关字段
        private bool _isManualCollisionTargetEnabled = false;
        private ObservableCollection<ManualCollisionTargetViewModel> _manualCollisionTargets;
        private string _manualCollisionTargetSummary = "未指定碰撞检测对象";
        private DateTime? _manualTargetsLastSyncTime;
        private List<CollisionResult> _latestCollisionResults = new List<CollisionResult>();
        private const int ManualCollisionTargetLimit = 60;
        private const string ManualTargetsHighlightCategory = ModelHighlightHelper.ManualTargetsCategory;
        private const string CollisionResultsHighlightCategory = ModelHighlightHelper.CollisionResultsCategory;
        private static readonly Color ManualTargetHighlightColor = Color.FromByteRGB(255, 170, 0);
        private static readonly Color CollisionResultHighlightColor = Color.FromByteRGB(244, 67, 54); // Material Red（与路径终点颜色一致）

        #endregion

        #region 公共属性


        /// <summary>
        /// 可用帧率集合
        /// </summary>
        public ObservableCollection<int> AvailableFrameRates
        {
            get => _availableFrameRates;
            set => SetProperty(ref _availableFrameRates, value);
        }

        /// <summary>
        /// 选中的帧率
        /// </summary>
        public int SelectedFrameRate
        {
            get => _selectedFrameRate;
            set
            {
                if (SetProperty(ref _selectedFrameRate, value))
                {
                    // 同步更新AnimationFrameRate字段
                    _animationFrameRate = value;

                    // 帧率变化时，步长需要重新计算（步长=路径长度/(帧率*时长)）
                    OnPropertyChanged(nameof(CollisionDetectionAccuracy));
                }
            }
        }

        /// <summary>
        /// 动画持续时间（秒）
        /// </summary>
        public double AnimationDuration
        {
            get => _animationDuration;
            set
            {
                if (SetProperty(ref _animationDuration, value))
                {
                    // 动画时长变化时，步长和速度需要重新计算
                    OnPropertyChanged(nameof(CollisionDetectionAccuracy));
                    OnPropertyChanged(nameof(MovementSpeed));
                }
            }
        }


        /// <summary>
        /// 是否可以开始动画
        /// </summary>
        public bool CanStartAnimation
        {
            get => _canStartAnimation;
            set => SetProperty(ref _canStartAnimation, value);
        }

        /// <summary>
        /// 是否可以暂停动画
        /// </summary>
        public bool CanPauseAnimation
        {
            get => _canPauseAnimation;
            set => SetProperty(ref _canPauseAnimation, value);
        }

        /// <summary>
        /// 是否可以停止动画
        /// </summary>
        public bool CanStopAnimation
        {
            get => _canStopAnimation;
            set => SetProperty(ref _canStopAnimation, value);
        }


        /// <summary>
        /// 是否有碰撞检测结果
        /// </summary>
        public bool HasCollisionResults
        {
            get => _hasCollisionResults;
            set
            {
                if (SetProperty(ref _hasCollisionResults, value))
                {
                    System.Windows.Input.CommandManager.InvalidateRequerySuggested();
                }
            }
        }

        private bool _hasClashDetectiveResults;
        public bool HasClashDetectiveResults
        {
            get => _hasClashDetectiveResults;
            set
            {
                if (SetProperty(ref _hasClashDetectiveResults, value))
                {
                    System.Windows.Input.CommandManager.InvalidateRequerySuggested();
                }
            }
        }



        /// <summary>
        /// 碰撞检测精度(米) - 步长，根据路径长度、帧率和时长计算得出
        /// 如果无法计算则返回0，表示数据不完整
        /// </summary>
        public double CollisionDetectionAccuracy
        {
            get
            {
                var pathLength = GetPathLength();
                if (pathLength > 0 && _animationFrameRate > 0 && _animationDuration > 0)
                {
                    // 步长 = 路径长度 / (帧率 * 时长)
                    return Math.Round(pathLength / (_animationFrameRate * _animationDuration), 3);
                }

                // 无法计算时返回0
                // 注意：如果路径为空(pathLength==0)，这是正常的初始状态，不输出警告
                // 只有在配置参数异常时才输出警告
                if (pathLength > 0 && (_animationFrameRate <= 0 || _animationDuration <= 0))
                {
                    LogManager.Warning($"[AnimationControlViewModel] 无法计算碰撞检测精度 - 路径长度:{pathLength}m, 帧率:{_animationFrameRate}fps, 时长:{_animationDuration}s");
                }
                return 0;
            }
        }

        /// <summary>
        /// 运动速度(米/秒) - 根据路径长度和时长计算得出
        /// 如果无法计算则返回0，表示数据不完整
        /// </summary>
        public double MovementSpeed
        {
            get
            {
                var pathLength = GetPathLength();
                if (pathLength > 0 && _animationDuration > 0)
                {
                    // 速度 = 路径长度 / 时长
                    return Math.Round(pathLength / _animationDuration, 2);
                }

                // 无法计算时返回0
                // 注意：如果路径为空(pathLength==0)，这是正常的初始状态，不输出警告
                // 只有在配置参数异常时才输出警告
                if (pathLength > 0 && _animationDuration <= 0)
                {
                    LogManager.Warning($"[AnimationControlViewModel] 无法计算运动速度 - 路径长度:{pathLength}m, 时长:{_animationDuration}s");
                }
                return 0;
            }
        }
        /// <summary>
        /// 路径长度(米) - 计算得出
        /// </summary>
        public double PathLength
        {
            get
            {
                return GetPathLength();
            }
        }

        /// <summary>
        /// 检测间隙(米)
        /// </summary>
        public double DetectionGap
        {
            get => _detectionGap;
            set
            {
                // 限制精度到2位小数
                var roundedValue = Math.Round(value, 2);
                SetProperty(ref _detectionGap, roundedValue);
            }
        }

        /// <summary>
        /// 动画帧率(FPS)
        /// </summary>
        public int AnimationFrameRate
        {
            get => _animationFrameRate;
            set
            {
                if (SetProperty(ref _animationFrameRate, value))
                {
                    // 帧率变化时，步长需要重新计算
                    OnPropertyChanged(nameof(CollisionDetectionAccuracy));
                }
            }
        }


        /// <summary>
        /// 当前选中的路径
        /// </summary>
        public PathRouteViewModel CurrentPathRoute
        {
            get => _currentPathRoute;
            set
            {
                if (SetProperty(ref _currentPathRoute, value))
                {
                    // 路径改变时，步长、速度和路径长度需要重新计算
                    OnPropertyChanged(nameof(CollisionDetectionAccuracy));
                    OnPropertyChanged(nameof(MovementSpeed));
                    OnPropertyChanged(nameof(PathLength));
                    UpdateCanGenerateAnimation();

                    // 路径改变时，刷新ClashDetective结果列表
                    RefreshClashDetectiveResultsList();
                }
            }
        }

        /// <summary>
        /// 选中的移动物体
        /// </summary>
        public ModelItem SelectedAnimatedObject
        {
            get => _selectedAnimatedObject;
            set
            {
                if (SetProperty(ref _selectedAnimatedObject, value))
                {
                    UpdateAnimatedObjectInfo();
                    UpdateCanGenerateAnimation();

                    // 预计算排除列表（异步）
                    _ = PrecomputeCollisionExclusionsAsync(value);
                }
            }
        }

        /// <summary>
        /// 选中的移动物体名称
        /// </summary>
        public string SelectedAnimatedObjectName
        {
            get => _selectedAnimatedObjectName;
            set => SetProperty(ref _selectedAnimatedObjectName, value);
        }

        /// <summary>
        /// 是否已选择移动物体
        /// </summary>
        public bool HasSelectedAnimatedObject
        {
            get => _hasSelectedAnimatedObject;
            set => SetProperty(ref _hasSelectedAnimatedObject, value);
        }

        /// <summary>
        /// 是否可以生成动画
        /// </summary>
        public bool CanGenerateAnimation
        {
            get => _canGenerateAnimation;
            set => SetProperty(ref _canGenerateAnimation, value);
        }

        #region 虚拟车辆属性

        /// <summary>
        /// 是否使用选择的模型物体
        /// </summary>
        public bool UseSelectedObject
        {
            get => _useSelectedObject;
            set
            {
                if (SetProperty(ref _useSelectedObject, value))
                {
                    if (value)
                    {
                        _useVirtualVehicle = false;
                        OnPropertyChanged(nameof(UseVirtualVehicle));

                        // ✨ 模式切换清理：切换到手动选择模式时，移除存在的虚拟车辆并清理数据
                        try
                        {
                            VirtualVehicleManager.Instance.RemoveVirtualVehicle();
                            _pathAnimationManager?.ClearAnimationResults(); // 清理虚拟车辆留下的动画数据
                            LogManager.Info("已切换到手动选择模式，自动隐藏虚拟车辆并清理动画数据");
                        }
                        catch (Exception ex)
                        {
                            LogManager.Warning($"隐藏虚拟车辆失败: {ex.Message}");
                        }
                    }
                    UpdateCanGenerateAnimation();
                }
            }
        }

        /// <summary>
        /// 是否使用虚拟车辆
        /// </summary>
        public bool UseVirtualVehicle
        {
            get => _useVirtualVehicle;
            set
            {
                if (SetProperty(ref _useVirtualVehicle, value))
                {
                    if (value)
                    {
                        _useSelectedObject = false;
                        OnPropertyChanged(nameof(UseSelectedObject));

                        // ✨ 模式切换清理：切换到虚拟车辆模式时，重置之前手动选择物体的动画状态（恢复到CAD位置）
                        try
                        {
                            // 只有在当前动画对象不是虚拟车辆时才执行重置
                            if (_pathAnimationManager != null &&
                                _pathAnimationManager.AnimatedObject != null &&
                                !VirtualVehicleManager.Instance.IsVirtualVehicleActive)
                            {
                                _pathAnimationManager.RestoreObjectToCADPosition();
                                _pathAnimationManager.ClearAnimationResults(); // 清理手动选择物体留下的动画数据
                                LogManager.Info("已切换到虚拟车辆模式，将之前的手动选择物体归位并清理动画数据");
                            }

                            // ✨ 统一逻辑：启用虚拟车辆时立即创建并对齐到起点
                            if (VirtualVehicleManager.Instance.IsVirtualVehicleActive == false)
                            {
                                LogManager.Info("正在创建并初始化虚拟车辆到起点...");
                                var vModel = VirtualVehicleManager.Instance.CreateVirtualVehicle(
                                    VirtualVehicleLength, VirtualVehicleWidth, VirtualVehicleHeight);

                                if (vModel != null && CurrentPathRoute != null && CurrentPathRoute.Points != null)
                                {
                                    var points = CurrentPathRoute.Points.Select(p => new Point3D(p.X, p.Y, p.Z)).ToList();
                                    _pathAnimationManager?.SyncToPathStart(vModel, points);
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            LogManager.Warning($"重置手动选择物体状态失败: {ex.Message}");
                        }
                    }
                    UpdateCanGenerateAnimation();
                }
            }
        }

        /// <summary>
        /// 虚拟车辆长度（米）- 只读，从路径编辑同步
        /// </summary>
        public double VirtualVehicleLength
        {
            get => _virtualVehicleLength;
            private set => SetProperty(ref _virtualVehicleLength, value);
        }

        /// <summary>
        /// 虚拟车辆宽度（米）- 只读，从路径编辑同步
        /// </summary>
        public double VirtualVehicleWidth
        {
            get => _virtualVehicleWidth;
            private set => SetProperty(ref _virtualVehicleWidth, value);
        }

        /// <summary>
        /// 虚拟车辆高度（米）- 只读，从路径编辑同步
        /// </summary>
        public double VirtualVehicleHeight
        {
            get => _virtualVehicleHeight;
            private set => SetProperty(ref _virtualVehicleHeight, value);
        }

        /// <summary>
        /// 设置虚拟车辆参数（由主ViewModel调用）
        /// </summary>
        public void SetVirtualVehicleParameters(double length, double width, double height)
        {
            VirtualVehicleLength = length;
            VirtualVehicleWidth = width;
            VirtualVehicleHeight = height;

            LogManager.Info($"[AnimationControlViewModel] 虚拟车辆参数已更新: {length:F1}m × {width:F1}m × {height:F1}m");

            // 如果当前使用虚拟车辆模式，更新生成动画的可用状态
            if (UseVirtualVehicle)
            {
                UpdateCanGenerateAnimation();
            }
        }

        #endregion

        #region 手工碰撞对象属性

        public bool IsManualCollisionTargetEnabled
        {
            get => _isManualCollisionTargetEnabled;
            set
            {
                if (SetProperty(ref _isManualCollisionTargetEnabled, value))
                {
                    HandleManualCollisionModeChanged();
                }
            }
        }

        public ObservableCollection<ManualCollisionTargetViewModel> ManualCollisionTargets => _manualCollisionTargets;

        public string ManualCollisionTargetSummary
        {
            get => _manualCollisionTargetSummary;
            set => SetProperty(ref _manualCollisionTargetSummary, value);
        }

        public bool HasManualCollisionTargets => _manualCollisionTargets?.Count > 0;

        public bool IsManualTargetModeActive => IsManualCollisionTargetEnabled && HasManualCollisionTargets;

        #endregion

        #region ClashDetective结果管理

        private ObservableCollection<ClashDetectiveResultViewModel> _clashDetectiveResults = new ObservableCollection<ClashDetectiveResultViewModel>();

        public ObservableCollection<ClashDetectiveResultViewModel> ClashDetectiveResults => _clashDetectiveResults;

        public ICommand RefreshClashDetectiveResultsCommand { get; private set; }

        #endregion

        #region 媒体控制属性

        /// <summary>
        /// 时间轴位置（0-总帧数）
        /// </summary>
        public double TimelinePosition
        {
            get => _pathAnimationManager?.CurrentFrame ?? 0;
            set
            {
                if (_pathAnimationManager != null)
                {
                    _pathAnimationManager.SeekToFrame((int)Math.Round(value));
                }
                OnPropertyChanged();
            }
        }

        /// <summary>
        /// 时间轴持续时间（总帧数）
        /// </summary>
        public double TimelineDuration => _pathAnimationManager?.TotalFrames - 1 ?? 0;

        /// <summary>
        /// 当前时间显示（格式化）
        /// </summary>
        public string CurrentTimeDisplay
        {
            get
            {
                if (_pathAnimationManager == null) return "00:00";

                var currentSeconds = (_pathAnimationManager.CurrentFrame / (double)(_pathAnimationManager.TotalFrames - 1)) * _animationDuration;
                return FormatTime(currentSeconds);
            }
        }

        /// <summary>
        /// 总时长显示（格式化）
        /// </summary>
        public string TotalTimeDisplay => FormatTime(_animationDuration);

        /// <summary>
        /// 帧信息显示
        /// </summary>
        public string FrameInfoDisplay
        {
            get
            {
                if (_pathAnimationManager == null) return "0/0";
                return $"{_pathAnimationManager.CurrentFrame + 1}/{_pathAnimationManager.TotalFrames}";
            }
        }

        /// <summary>
        /// 是否正在正向播放
        /// </summary>
        public bool IsPlayingForward => _pathAnimationManager?.PlaybackDirection == 1 &&
                                       _pathAnimationManager?.CurrentState == NavisworksTransport.Core.Animation.AnimationState.Playing;

        /// <summary>
        /// 是否正在反向播放
        /// </summary>
        public bool IsPlayingReverse => _pathAnimationManager?.PlaybackDirection == -1 &&
                                       _pathAnimationManager?.CurrentState == NavisworksTransport.Core.Animation.AnimationState.Playing;

        #endregion


        #endregion

        #region 命令

        // 原有命令
        public ICommand StartAnimationCommand { get; private set; }
        public ICommand PauseAnimationCommand { get; private set; }
        public ICommand StopAnimationCommand { get; private set; }
        public ICommand ViewCollisionReportCommand { get; private set; }
        public ICommand SelectAnimatedObjectCommand { get; private set; }
        public ICommand ClearAnimatedObjectCommand { get; private set; }
        public ICommand GenerateAnimationCommand { get; private set; }
        public ICommand ApplyManualTargetsFromSelectionCommand { get; private set; }
        public ICommand ClearManualTargetsCommand { get; private set; }
        public ICommand RemoveManualTargetCommand { get; private set; }
        public ICommand HighlightManualTargetsCommand { get; private set; }
        public ICommand ClearManualHighlightsCommand { get; private set; }
        public ICommand HighlightCollisionResultsCommand { get; private set; }
        public ICommand ClearCollisionHighlightsCommand { get; private set; }
        public ICommand HighlightClashDetectiveResultsCommand { get; private set; }
        public ICommand ClearClashDetectiveHighlightsCommand { get; private set; }

        // 媒体控制命令
        public ICommand PlayForwardCommand { get; private set; }
        public ICommand PlayReverseCommand { get; private set; }
        public ICommand StepForwardCommand { get; private set; }
        public ICommand StepBackwardCommand { get; private set; }
        public ICommand FastForwardCommand { get; private set; }
        public ICommand FastBackwardCommand { get; private set; }
        public ICommand SeekToStartCommand { get; private set; }
        public ICommand SeekToEndCommand { get; private set; }

        #endregion

        #region 构造函数

        public AnimationControlViewModel() : this(null)
        {
            // 调用带参数的构造函数，传入null
        }

        /// <summary>
        /// 带主ViewModel参数的构造函数，支持统一状态栏
        /// </summary>
        /// <param name="mainViewModel">主ViewModel，用于统一状态栏</param>
        public AnimationControlViewModel(LogisticsControlViewModel mainViewModel) : base()
        {
            try
            {
                // 设置主ViewModel引用到基类
                SetMainViewModel(mainViewModel);

                // 初始化管理器 - 使用单例模式确保与GenerateCollisionReportCommand使用同一实例
                _pathAnimationManager = NavisworksTransport.Core.Animation.PathAnimationManager.GetInstance();
                _clashIntegration = ClashDetectiveIntegration.Instance;
                _uiStateManager = UIStateManager.Instance;

                // 订阅PathAnimationManager事件
                _pathAnimationManager.ProgressChanged += OnAnimationProgressChanged;
                _pathAnimationManager.StateChanged += OnAnimationStateChanged;

                // 初始化集合
                AvailableFrameRates = new ThreadSafeObservableCollection<int>();
                _manualCollisionTargets = new ObservableCollection<ManualCollisionTargetViewModel>();
                _manualCollisionTargets.CollectionChanged += OnManualCollisionTargetsChanged;
                UpdateManualCollisionTargetSummary();

                // 初始化设置
                InitializeAnimationSettings();

                // 初始化命令
                InitializeCommands();

                // 订阅碰撞检测事件
                _clashIntegration.CollisionDetected += OnCollisionDetected;
                _clashIntegration.ClashDetectiveResultSaved += OnClashDetectiveResultSaved;

                // 订阅文档状态事件
                DocumentStateManager.Instance.DocumentInvalidated += OnDocumentInvalidated;
                DocumentStateManager.Instance.DocumentReady += OnDocumentReady;

                LogManager.Info("AnimationControlViewModel初始化完成 - 支持统一状态栏");
            }
            catch (Exception ex)
            {
                LogManager.Error($"AnimationControlViewModel初始化失败: {ex.Message}", ex);
                UpdateMainStatus("初始化失败，请检查日志");
                throw;
            }
        }

        #endregion

        #region 初始化方法

        /// <summary>
        /// 初始化动画设置
        /// </summary>
        private void InitializeAnimationSettings()
        {
            // 从配置加载动画参数
            var config = NavisworksTransport.Core.Config.ConfigManager.Instance.Current;

            // 初始化可用帧率
            AvailableFrameRates.Clear();
            var frameRates = new[] { 15, 24, 30, 60 };
            foreach (var rate in frameRates)
            {
                AvailableFrameRates.Add(rate);
            }

            // 从配置读取帧率
            SelectedFrameRate = config.Animation.FrameRate;

            // 从配置读取动画持续时间
            AnimationDuration = config.Animation.DurationSeconds;

            // 设置初始状态 - 默认状态未激活，等待有效动画
            CanPauseAnimation = false;
            CanStopAnimation = false;

            // 初始化碰撞检测状态
            HasCollisionResults = false;
            UpdateMainStatus("碰撞检测就绪");

            // 从配置读取碰撞检测参数
            DetectionGap = config.Animation.DetectionGapMeters;
            AnimationFrameRate = config.Animation.FrameRate;

            // 设置动画按钮的初始状态
            UpdateAnimationButtonStates();

            LogManager.Info($"动画设置初始化完成 - 帧率:{SelectedFrameRate}fps, 持续时间:{AnimationDuration}秒, 检测间隙:{DetectionGap}米");
        }

        /// <summary>
        /// 初始化命令
        /// </summary>
        private void InitializeCommands()
        {
            StartAnimationCommand = new RelayCommand(async () => await ExecuteStartAnimationAsync(), () => CanStartAnimation);
            PauseAnimationCommand = new RelayCommand(async () => await ExecutePauseAnimationAsync(), () => CanPauseAnimation);
            StopAnimationCommand = new RelayCommand(async () => await ExecuteStopAnimationAsync(), () => CanStopAnimation);
            ViewCollisionReportCommand = new RelayCommand(async () => await ExecuteViewCollisionReport(), () => HasCollisionResults);
            SelectAnimatedObjectCommand = new RelayCommand(ExecuteSelectAnimatedObject);
            ClearAnimatedObjectCommand = new RelayCommand(ExecuteClearAnimatedObject, () => HasSelectedAnimatedObject);
            GenerateAnimationCommand = new RelayCommand(ExecuteGenerateAnimation, () => CanGenerateAnimation);
            ApplyManualTargetsFromSelectionCommand = new RelayCommand(ExecuteApplyManualTargetsFromSelection);
            ClearManualTargetsCommand = new RelayCommand(ExecuteClearManualTargets, () => HasManualCollisionTargets);
            RemoveManualTargetCommand = new RelayCommand<ManualCollisionTargetViewModel>(ExecuteRemoveManualTarget, target => target != null);
            HighlightManualTargetsCommand = new RelayCommand(ExecuteHighlightManualTargets, () => HasManualCollisionTargets);
            ClearManualHighlightsCommand = new RelayCommand(ExecuteClearManualHighlights, () => HasManualCollisionTargets);
            HighlightCollisionResultsCommand = new RelayCommand(ExecuteHighlightCollisionResults, () => HasCollisionResults);
            ClearCollisionHighlightsCommand = new RelayCommand(ExecuteClearCollisionHighlights, () => HasCollisionResults);
            HighlightClashDetectiveResultsCommand = new RelayCommand(ExecuteHighlightClashDetectiveResults, () => HasClashDetectiveResults);
            ClearClashDetectiveHighlightsCommand = new RelayCommand(ExecuteClearClashDetectiveHighlights, () => HasClashDetectiveResults);
            RefreshClashDetectiveResultsCommand = new RelayCommand(ExecuteRefreshClashDetectiveResults);
            PlayForwardCommand = new RelayCommand(ExecutePlayForward, CanExecuteMediaCommands);
            PlayReverseCommand = new RelayCommand(ExecutePlayReverse, CanExecuteMediaCommands);
            StepForwardCommand = new RelayCommand(ExecuteStepForward, CanExecuteMediaCommands);
            StepBackwardCommand = new RelayCommand(ExecuteStepBackward, CanExecuteMediaCommands);
            FastForwardCommand = new RelayCommand(ExecuteFastForward, CanExecuteMediaCommands);
            FastBackwardCommand = new RelayCommand(ExecuteFastBackward, CanExecuteMediaCommands);
            SeekToStartCommand = new RelayCommand(ExecuteSeekToStart, CanExecuteMediaCommands);
            SeekToEndCommand = new RelayCommand(ExecuteSeekToEnd, CanExecuteMediaCommands);

            LogManager.Info("动画控制命令初始化完成");
        }


        #endregion

        #region 命令实现

        /// <summary>
        /// 开始动画命令
        /// </summary>
        private async Task ExecuteStartAnimationAsync()
        {
            if (!CanStartAnimation || CurrentPathRoute == null || CurrentPathRoute.Points.Count < 2)
            {
                await _uiStateManager.ExecuteUIUpdateAsync(() =>
                {
                    UpdateMainStatus("请先选择包含至少2个点的路径");
                });
                return;
            }

            try
            {
                // 根据PathAnimationManager的状态决定操作
                if (_pathAnimationManager.CurrentState == NavisworksTransport.Core.Animation.AnimationState.Paused)
                {
                    // 从暂停状态恢复
                    _pathAnimationManager.ResumeAnimation();
                    LogManager.Info("从暂停状态恢复动画播放");
                    return; // 恢复动画后直接返回，不再执行StartAnimation
                }
                else if (_pathAnimationManager.IsAnimating)
                {
                    LogManager.Warning("动画已在播放中");
                    await _uiStateManager.ExecuteUIUpdateAsync(() =>
                    {
                        UpdateMainStatus("动画已在播放中");
                        CanStartAnimation = true;
                        CanPauseAnimation = false;
                        CanStopAnimation = false;
                    });
                    return;
                }

                // 开始播放物体移动动画
                // 清理之前的碰撞缓存
                _pathAnimationManager?.ClearExclusionCache();
                LogManager.Info("已清理UI层碰撞检测缓存");

                // 清理之前的碰撞高亮
                ModelHighlightHelper.ClearCollisionHighlights();
                LogManager.Info("已清理之前的碰撞高亮");

                // 首先重置进度（开始全新动画时）

                _pathAnimationManager.StartAnimation();

                LogManager.Info($"开始物体移动动画播放: {CurrentPathRoute.Name}, 帧率: {SelectedFrameRate}fps");
            }
            catch (Exception ex)
            {
                await _uiStateManager.ExecuteUIUpdateAsync(() =>
                {
                    UpdateMainStatus($"开始动画出错: {ex.Message}");
                    LogManager.Error($"开始动画异常: {ex.Message}", ex);

                    // 恢复按钮状态
                    CanStartAnimation = true;
                    CanPauseAnimation = false;
                    CanStopAnimation = false;
                });
            }
        }

        /// <summary>
        /// 暂停动画命令
        /// </summary>
        private async Task ExecutePauseAnimationAsync()
        {
            try
            {
                // 调用PathAnimationManager暂停动画
                // UI状态会通过OnAnimationStateChanged事件自动更新
                _pathAnimationManager.PauseAnimation();

                LogManager.Info("暂停动画播放");
            }
            catch (Exception ex)
            {
                LogManager.Error($"暂停动画异常: {ex.Message}", ex);

                // 错误时手动恢复UI状态
                await _uiStateManager.ExecuteUIUpdateAsync(() =>
                {
                    UpdateMainStatus("暂停动画失败");
                });
            }
        }

        /// <summary>
        /// 停止动画命令
        /// </summary>
        private async Task ExecuteStopAnimationAsync()
        {
            try
            {
                await _uiStateManager.ExecuteUIUpdateAsync(() =>
                {
                    UpdateMainStatus("动画已停止");

                    CanStartAnimation = true;
                    CanPauseAnimation = false;
                    CanStopAnimation = false;

                    LogManager.Info("停止动画播放");
                });

                // 停止当前动画
                _pathAnimationManager.CancelAnimation();
            }
            catch (Exception ex)
            {
                LogManager.Error($"停止动画异常: {ex.Message}", ex);
            }
        }


        /// <summary>
        /// 查看碰撞报告命令（显示已缓存的报告）
        /// </summary>
        private async Task ExecuteViewCollisionReport()
        {
            if (!HasCollisionResults)
            {
                UpdateMainStatus("尚无碰撞检测结果可查看");
                return;
            }

            try
            {
                // 检查是否有已缓存的报告
                if (_lastGeneratedReport == null)
                {
                    UpdateMainStatus("报告尚未生成，请等待碰撞检测完成");
                    LogManager.Warning("尝试查看报告但缓存为空");
                    return;
                }

                UpdateMainStatus("正在显示碰撞报告...", -1, true);
                LogManager.Info("开始显示已缓存的碰撞报告");

                // 在UI线程上显示缓存的报告
                await _uiStateManager.ExecuteUIUpdateAsync(() =>
                {
                    try
                    {
                        // 使用WPF碰撞报告对话框直接显示缓存的报告
                        var reportDialog = NavisworksTransport.UI.WPF.Views.CollisionReportDialog.ShowReport(_lastGeneratedReport);

                        if (reportDialog != null)
                        {
                            UpdateMainStatus("碰撞报告已显示");
                            LogManager.Info("成功显示缓存的碰撞报告");
                        }
                        else
                        {
                            UpdateMainStatus("显示报告对话框失败");
                            LogManager.Error("CollisionReportDialog.ShowReport返回null");
                        }
                    }
                    catch (Exception dialogEx)
                    {
                        UpdateMainStatus($"显示报告失败: {dialogEx.Message}");
                        LogManager.Error($"显示WPF报告对话框失败: {dialogEx.Message}");
                    }
                });
            }
            catch (Exception ex)
            {
                UpdateMainStatus("查看碰撞报告出错");
                LogManager.Error($"查看碰撞报告异常: {ex.Message}", ex);
            }
        }

        #region 媒体控制命令实现

        /// <summary>
        /// 检查媒体控制命令是否可执行
        /// </summary>
        private bool CanExecuteMediaCommands()
        {
            return _pathAnimationManager != null &&
                   _pathAnimationManager.CurrentState != NavisworksTransport.Core.Animation.AnimationState.Idle &&
                   _pathAnimationManager.TotalFrames > 0;
        }

        /// <summary>
        /// 执行正向播放命令
        /// </summary>
        private void ExecutePlayForward()
        {
            try
            {
                _pathAnimationManager?.PlayForward();
                UpdateMediaControlProperties();
                LogManager.Info("执行正向播放命令");
            }
            catch (Exception ex)
            {
                LogManager.Error($"正向播放命令执行失败: {ex.Message}");
                UpdateMainStatus("正向播放失败");
            }
        }

        /// <summary>
        /// 执行反向播放命令
        /// </summary>
        private void ExecutePlayReverse()
        {
            try
            {
                _pathAnimationManager?.PlayReverse();
                UpdateMediaControlProperties();
                LogManager.Info("执行反向播放命令");
            }
            catch (Exception ex)
            {
                LogManager.Error($"反向播放命令执行失败: {ex.Message}");
                UpdateMainStatus("反向播放失败");
            }
        }

        /// <summary>
        /// 执行单帧前进命令
        /// </summary>
        private void ExecuteStepForward()
        {
            try
            {
                _pathAnimationManager?.StepForward();
                UpdateMediaControlProperties();
                LogManager.Debug("执行单帧前进命令");
            }
            catch (Exception ex)
            {
                LogManager.Error($"单帧前进命令执行失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 执行单帧后退命令
        /// </summary>
        private void ExecuteStepBackward()
        {
            try
            {
                _pathAnimationManager?.StepBackward();
                UpdateMediaControlProperties();
                LogManager.Debug("执行单帧后退命令");
            }
            catch (Exception ex)
            {
                LogManager.Error($"单帧后退命令执行失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 执行快进10帧命令
        /// </summary>
        private void ExecuteFastForward()
        {
            try
            {
                _pathAnimationManager?.FastForward();
                UpdateMediaControlProperties();
                LogManager.Debug("执行快进10帧命令");
            }
            catch (Exception ex)
            {
                LogManager.Error($"快进命令执行失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 执行快退10帧命令
        /// </summary>
        private void ExecuteFastBackward()
        {
            try
            {
                _pathAnimationManager?.FastBackward();
                UpdateMediaControlProperties();
                LogManager.Debug("执行快退10帧命令");
            }
            catch (Exception ex)
            {
                LogManager.Error($"快退命令执行失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 执行跳转到开头命令
        /// </summary>
        private void ExecuteSeekToStart()
        {
            try
            {
                _pathAnimationManager?.SeekToFrame(0);
                UpdateMediaControlProperties();
                LogManager.Info("跳转到动画开头");
            }
            catch (Exception ex)
            {
                LogManager.Error($"跳转到开头失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 执行跳转到结尾命令
        /// </summary>
        private void ExecuteSeekToEnd()
        {
            try
            {
                int lastFrame = (_pathAnimationManager?.TotalFrames ?? 1) - 1;
                _pathAnimationManager?.SeekToFrame(lastFrame);
                UpdateMediaControlProperties();
                LogManager.Info("跳转到动画结尾");
            }
            catch (Exception ex)
            {
                LogManager.Error($"跳转到结尾失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 执行选择移动物体命令
        /// </summary>
        private void ExecuteSelectAnimatedObject()
        {
            try
            {
                var doc = Autodesk.Navisworks.Api.Application.ActiveDocument;
                if (doc == null || doc.CurrentSelection.IsEmpty)
                {
                    LogManager.Warning("请先在场景中选择一个物体");
                    return;
                }

                var newObject = doc.CurrentSelection.SelectedItems.First;
                if (newObject == null) return;

                // 1. 如果有旧物体，先归位并清理旧动画
                if (_selectedAnimatedObject != null && !ReferenceEquals(_selectedAnimatedObject, newObject))
                {
                    _pathAnimationManager?.RestoreObjectToCADPosition();
                }
                _pathAnimationManager?.ClearAnimationResults();

                // 2. 设置新物体
                SelectedAnimatedObject = newObject;
                LogManager.Info($"已选择移动物体: {SelectedAnimatedObject.DisplayName}");

                // 3. 立即移动到起点（如果路径存在）
                if (CurrentPathRoute != null && CurrentPathRoute.Points != null && _pathAnimationManager != null)
                {
                    var points = CurrentPathRoute.Points.Select(p => new Point3D(p.X, p.Y, p.Z)).ToList();
                    _pathAnimationManager.SyncToPathStart(newObject, points);
                }
            }
            catch (Exception ex)
            {
                LogManager.Error($"选择物体失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 更新媒体控制相关属性
        /// </summary>
        private void UpdateMediaControlProperties()
        {
            OnPropertyChanged(nameof(TimelinePosition));
            OnPropertyChanged(nameof(TimelineDuration));
            OnPropertyChanged(nameof(CurrentTimeDisplay));
            OnPropertyChanged(nameof(FrameInfoDisplay));
            OnPropertyChanged(nameof(IsPlayingForward));
            OnPropertyChanged(nameof(IsPlayingReverse));
        }

        /// <summary>
        /// 格式化时间显示
        /// </summary>
        private string FormatTime(double seconds)
        {
            var timeSpan = TimeSpan.FromSeconds(Math.Max(0, seconds));
            return $"{timeSpan.Minutes:D2}:{timeSpan.Seconds:D2}";
        }

        #endregion

        #endregion

        #region 辅助方法

        /// <summary>
        /// 设置当前路径
        /// </summary>
        public void SetCurrentPath(PathRouteViewModel pathRoute)
        {
            CurrentPathRoute = pathRoute;

            // 添加调试日志
            if (pathRoute != null)
            {
                LogManager.Info($"[AnimationControlViewModel] 设置当前路径: 名称='{pathRoute.Name}', ID='{pathRoute.Id}', 点数={pathRoute.Points?.Count ?? 0}");
            }
            else
            {
                LogManager.Info("[AnimationControlViewModel] 清空当前路径");
            }

            // 路径改变时清除已生成的动画（如果有的话）
            if (_pathAnimationManager != null &&
                (_pathAnimationManager.CurrentState == NavisworksTransport.Core.Animation.AnimationState.Ready ||
                 _pathAnimationManager.CurrentState == NavisworksTransport.Core.Animation.AnimationState.Finished))
            {
                try
                {
                    _pathAnimationManager.CancelAnimation(); // 这会将状态设置为Stopped，需要重新生成动画
                    LogManager.Info("路径更改，已清除之前生成的动画");
                }
                catch (Exception ex)
                {
                    LogManager.Warning($"清除之前动画时出现警告: {ex.Message}");
                }
            }

            // 路径改变时，步长、速度和路径长度需要重新计算
            OnPropertyChanged(nameof(CollisionDetectionAccuracy));
            OnPropertyChanged(nameof(MovementSpeed));
            OnPropertyChanged(nameof(PathLength));

            // 按钮状态更新
            UpdateAnimationButtonStates();

            // 更新碰撞状态
            if (pathRoute == null)
            {
                UpdateMainStatus("请选择路径");
            }
            else if (pathRoute.Points.Count < 2)
            {
                UpdateMainStatus("路径点数不足");
            }
            else
            {
                UpdateMainStatus("碰撞检测就绪");
            }

            LogManager.Info($"AnimationControlViewModel当前路径更新: {pathRoute?.Name ?? "无"}, 点数: {pathRoute?.Points.Count ?? 0}");
        }

        /// <summary>
        /// 处理动画进度变化事件
        /// 使用Dispatcher更新UI
        /// </summary>
        private void OnAnimationProgressChanged(object sender, double progressPercent)
        {
            System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
            {
                // 更新时间轴相关属性
                OnPropertyChanged(nameof(TimelinePosition));
                OnPropertyChanged(nameof(CurrentTimeDisplay));
                OnPropertyChanged(nameof(FrameInfoDisplay));
            }));
        }

        /// <summary>
        /// 处理动画状态变化事件
        /// </summary>
        private void OnAnimationStateChanged(object sender, NavisworksTransport.Core.Animation.AnimationState state)
        {
            System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
            {
                switch (state)
                {
                    case NavisworksTransport.Core.Animation.AnimationState.Playing:
                        CanStartAnimation = false;
                        CanPauseAnimation = true;
                        CanStopAnimation = true;
                        UpdateMainStatus("动画播放中");
                        UpdateMediaControlProperties(); // 更新媒体控制属性
                        break;
                    case NavisworksTransport.Core.Animation.AnimationState.Paused:
                        CanStartAnimation = true;  // 暂停状态下可以继续
                        CanPauseAnimation = false;
                        CanStopAnimation = true;
                        UpdateMainStatus("动画已暂停");
                        UpdateMediaControlProperties(); // 更新媒体控制属性
                        break;
                    case NavisworksTransport.Core.Animation.AnimationState.Finished:
                        CanStartAnimation = true;
                        CanPauseAnimation = false;
                        CanStopAnimation = false;
                        UpdateMainStatus("动画已完成");
                        UpdateMediaControlProperties(); // 更新媒体控制属性
                        // 检查并高亮ClashDetective结果
                        CheckAndHighlightClashDetectiveResults();
                        break;
                    case NavisworksTransport.Core.Animation.AnimationState.Stopped:
                        CanStartAnimation = true;
                        CanPauseAnimation = false;
                        CanStopAnimation = false;
                        UpdateMainStatus("动画已停止");
                        UpdateMediaControlProperties(); // 更新媒体控制属性
                        // 检查并高亮ClashDetective结果
                        CheckAndHighlightClashDetectiveResults();
                        break;
                    default:
                        UpdateMainStatus($"动画状态: {state}");
                        UpdateMediaControlProperties(); // 更新媒体控制属性
                        break;
                }
            }));
        }

        /// <summary>
        /// 检查并高亮ClashDetective结果
        /// </summary>
        private void CheckAndHighlightClashDetectiveResults()
        {
            try
            {
                // 检查是否有当前测试的ClashDetective结果
                var clashResults = _clashIntegration?.GetCurrentTestResults();

                if (clashResults != null && clashResults.Count > 0)
                {
                    // 有ClashDetective结果，高亮显示
                    _clashIntegration?.HighlightClashDetectiveResults(_clashIntegration.CurrentTestName);
                    HasClashDetectiveResults = true;
                    LogManager.Info($"动画结束，已高亮ClashDetective检测结果：{clashResults.Count}个碰撞");
                }
                // 如果没有ClashDetective结果，不做处理（可能第一次运行会自动计算，或者没有碰撞）
            }
            catch (Exception ex)
            {
                LogManager.Error($"检查并高亮ClashDetective结果失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 处理碰撞检测事件 - 自动生成报告并保存数据库
        /// </summary>
        private async void OnCollisionDetected(object sender, CollisionDetectedEventArgs e)
        {
            _latestCollisionResults = e?.Results?.Where(r => r != null).ToList() ?? new List<CollisionResult>();
            HasCollisionResults = _latestCollisionResults.Count > 0;

            if (!HasCollisionResults)
            {
                ModelHighlightHelper.ClearCollisionHighlights();
            }

            var collisionCount = _latestCollisionResults.Count;

            if (collisionCount > 0)
            {
                try
                {
                    UpdateMainStatus($"发现 {collisionCount} 个碰撞点，正在生成报告...", -1, true);
                    LogManager.Info($"碰撞检测完成，发现 {collisionCount} 个碰撞，开始自动生成报告");

                    // 自动生成碰撞报告
                    var generateReportCommand = NavisworksTransport.Commands.GenerateCollisionReportCommand.CreateComprehensive();
                    var result = await generateReportCommand.ExecuteAsync();

                    if (result.IsSuccess && result is PathPlanningResult<CollisionReportResult> reportResult)
                    {
                        // 缓存报告结果，供后续查看使用
                        _lastGeneratedReport = reportResult.Data;

                        // 保存到数据库
                        await SaveCollisionReportToDatabase(reportResult.Data);

                        UpdateMainStatus($"✅ 碰撞报告已生成并保存：{collisionCount} 个碰撞");
                        LogManager.Info("碰撞报告已自动生成并保存到数据库");

                        // 高亮ClashDetective结果
                        _clashIntegration?.HighlightClashDetectiveResults(_clashIntegration.CurrentTestName);
                        HasClashDetectiveResults = true;
                        LogManager.Info("已自动高亮ClashDetective检测结果");
                    }
                    else
                    {
                        UpdateMainStatus($"发现 {collisionCount} 个碰撞点（报告生成失败）");
                        LogManager.Error($"自动生成碰撞报告失败: {result.ErrorMessage}");
                    }
                }
                catch (Exception ex)
                {
                    LogManager.Error($"处理碰撞检测事件失败: {ex.Message}", ex);
                    UpdateMainStatus($"发现 {collisionCount} 个碰撞点（报告生成异常）");
                }
            }
            else
            {
                UpdateMainStatus("未发现碰撞");
                _lastGeneratedReport = null;
            }
        }

        /// <summary>
        /// ClashDetective结果保存事件处理
        /// </summary>
        private void OnClashDetectiveResultSaved(object sender, ClashDetectiveResultSavedEventArgs e)
        {
            try
            {
                // 刷新ClashDetective结果列表
                RefreshClashDetectiveResultsList();
                LogManager.Info($"ClashDetective结果已保存，列表已刷新: 路径={e.PathName}, 测试={e.TestName}, 碰撞数={e.CollisionCount}");
            }
            catch (Exception ex)
            {
                LogManager.Error($"处理ClashDetective结果保存事件失败: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// 保存碰撞报告到数据库
        /// </summary>
        private async Task SaveCollisionReportToDatabase(CollisionReportResult reportResult)
        {
            try
            {
                var pathPlanningManager = PathPlanningManager.Instance;
                var pathDatabase = pathPlanningManager?.GetPathDatabase();

                if (pathDatabase != null && reportResult != null)
                {
                    // 获取路由ID
                    string routeId = CurrentPathRoute?.Id ?? "";

                    // 从报告中获取所有需要的数据
                    await Task.Run(() =>
                    {
                        pathDatabase.SaveCollisionReport(
                            routeId,
                            reportResult.PathName,
                            SelectedAnimatedObjectName ?? "未知对象",
                            reportResult.UniqueCollidedObjectsCount,
                            reportResult.FrameRate,
                            reportResult.Duration,
                            reportResult.DetectionGap,
                            reportResult.AnimationCollisions,
                            reportResult.TotalCollisions
                        );
                    });

                    LogManager.Info($"碰撞报告已保存到数据库 - 路径:{reportResult.PathName}, " +
                                  $"碰撞构件:{reportResult.UniqueCollidedObjectsCount}, " +
                                  $"动画碰撞:{reportResult.AnimationCollisions}, " +
                                  $"ClashDetective:{reportResult.TotalCollisions}");
                }
                else
                {
                    LogManager.Warning("无法获取PathDatabase实例或报告数据为空，碰撞报告未保存到数据库");
                }
            }
            catch (Exception ex)
            {
                LogManager.Error($"保存碰撞报告到数据库失败: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// 执行清除移动物体命令
        /// 清除移动物体选择、停止当前动画并更新按钮状态
        /// </summary>
        private void ExecuteClearAnimatedObject()
        {
            try
            {
                if (_pathAnimationManager != null)
                {
                    // 1. 归位并清理
                    _pathAnimationManager.RestoreObjectToCADPosition();
                    _pathAnimationManager.ClearAnimationResults();
                    LogManager.Info("已清除PathAnimationManager中的动画数据并归位物体");
                }

                // 2. 重置属性
                SelectedAnimatedObject = null;
                UpdateAnimatedObjectInfo();
                UpdateCanGenerateAnimation();

                // 3. 清理高亮
                ModelHighlightHelper.ClearCollisionHighlights();

                LogManager.Info("移动物体已完全清除并归位");
                UpdateMainStatus("已清除物体选择并恢复位置");
            }
            catch (Exception ex)
            {
                LogManager.Error($"清除失败: {ex.Message}");
                UpdateMainStatus($"清除失败: {ex.Message}");
            }
        }

        #region 手工碰撞对象命令

        private void ExecuteApplyManualTargetsFromSelection()
        {
            try
            {
                var doc = Autodesk.Navisworks.Api.Application.ActiveDocument;
                var selectedItems = doc?.CurrentSelection?.SelectedItems;

                if (selectedItems == null || selectedItems.Count == 0)
                {
                    UpdateMainStatus("请在Navisworks中选择需要检测的对象");
                    LogManager.Warning("[手工碰撞] 未选择任何对象");
                    return;
                }

                var toAdd = new List<ManualCollisionTargetViewModel>();
                foreach (ModelItem item in selectedItems)
                {
                    if (item == null)
                        continue;

                    if (!ModelItemAnalysisHelper.IsModelItemValid(item) || !HasGeometryRecursive(item))
                        continue;

                    if (ManualTargetExists(item))
                        continue;

                    var displayName = ModelItemAnalysisHelper.GetSafeDisplayName(item);
                    var modelPath = BuildModelPath(item);
                    toAdd.Add(new ManualCollisionTargetViewModel(item, displayName, modelPath));
                }

                if (toAdd.Count == 0)
                {
                    if (_manualCollisionTargets.Count >= ManualCollisionTargetLimit)
                    {
                        UpdateMainStatus($"手工目标数量已达上限({ManualCollisionTargetLimit})");
                    }
                    else
                    {
                        UpdateMainStatus("选中的对象已在列表中或不包含几何体");
                    }
                    return;
                }

                int availableSlots = ManualCollisionTargetLimit - _manualCollisionTargets.Count;
                if (availableSlots <= 0)
                {
                    UpdateMainStatus($"手工目标数量已达上限({ManualCollisionTargetLimit})");
                    return;
                }

                var addedCount = Math.Min(availableSlots, toAdd.Count);
                foreach (var entry in toAdd.Take(addedCount))
                {
                    _manualCollisionTargets.Add(entry);
                }

                _manualTargetsLastSyncTime = DateTime.Now;
                UpdateManualCollisionTargetSummary();
                RefreshManualTargetHighlights();
                SyncManualCollisionTargetsToAnimationManager();

                UpdateMainStatus($"已添加 {addedCount} 个碰撞检测对象");
                LogManager.Info($"[手工碰撞] 添加 {addedCount} 个对象，目前共 {_manualCollisionTargets.Count} 个");
            }
            catch (Exception ex)
            {
                LogManager.Error($"[手工碰撞] 同步选中对象失败: {ex.Message}");
                UpdateMainStatus("同步手工对象失败");
            }
        }

        private void ExecuteClearManualTargets()
        {
            if (_manualCollisionTargets.Count == 0)
                return;

            _manualCollisionTargets.Clear();
            _manualTargetsLastSyncTime = null;
            ModelHighlightHelper.ClearCategory(ManualTargetsHighlightCategory);
            SyncManualCollisionTargetsToAnimationManager();
            UpdateManualCollisionTargetSummary();
            UpdateMainStatus("已清空手工碰撞对象");
            LogManager.Info("[手工碰撞] 手工对象列表已清空");
        }

        private void ExecuteRemoveManualTarget(ManualCollisionTargetViewModel target)
        {
            if (target == null)
                return;

            if (_manualCollisionTargets.Remove(target))
            {
                UpdateMainStatus($"已移除 {target.DisplayName}");
                LogManager.Info($"[手工碰撞] 移除对象 {target.DisplayName}");

                if (_manualCollisionTargets.Count == 0)
                {
                    ModelHighlightHelper.ClearCategory(ManualTargetsHighlightCategory);
                }
                else
                {
                    RefreshManualTargetHighlights();
                }
            }
        }

        private void ExecuteHighlightManualTargets()
        {
            if (_manualCollisionTargets.Count == 0)
                return;

            RefreshManualTargetHighlights(forceHighlight: true);
            UpdateMainStatus("已高亮手工指定对象");
        }

        private void ExecuteClearManualHighlights()
        {
            ModelHighlightHelper.ClearCategory(ManualTargetsHighlightCategory);
            UpdateMainStatus("已清除手工对象高亮");
        }

        #endregion

        #region 碰撞结果高亮命令

        private void ExecuteHighlightCollisionResults()
        {
            if (_latestCollisionResults == null || _latestCollisionResults.Count == 0)
            {
                UpdateMainStatus("没有可高亮的碰撞结果对象");
                return;
            }

            _clashIntegration?.HighlightCollisions(_latestCollisionResults, CollisionResultHighlightColor, false);
            UpdateMainStatus($"已高亮 {_latestCollisionResults.Count} 个碰撞结果");
            LogManager.Info($"[碰撞结果高亮] 已高亮 {_latestCollisionResults.Count} 个结果");
        }

        private void ExecuteClearCollisionHighlights()
        {
            ModelHighlightHelper.ClearCategory(CollisionResultsHighlightCategory);
            UpdateMainStatus("已清除碰撞结果高亮");
        }

        private void ExecuteHighlightClashDetectiveResults()
        {
            _clashIntegration?.HighlightClashDetectiveResults(_clashIntegration.CurrentTestName);
            UpdateMainStatus("已高亮ClashDetective检测结果");
        }

        private void ExecuteClearClashDetectiveHighlights()
        {
            _clashIntegration?.ClearClashDetectiveHighlights();
            UpdateMainStatus("已清除ClashDetective高亮");
        }

        /// <summary>
        /// 刷新ClashDetective结果列表
        /// </summary>
        private void RefreshClashDetectiveResultsList()
        {
            try
            {
                var pathName = CurrentPathRoute?.Name;
                if (string.IsNullOrEmpty(pathName))
                {
                    _clashDetectiveResults.Clear();
                    HasClashDetectiveResults = false;
                    return;
                }

                var pathDatabase = PathPlanningManager.Instance?.GetPathDatabase();
                if (pathDatabase == null)
                {
                    _clashDetectiveResults.Clear();
                    HasClashDetectiveResults = false;
                    return;
                }

                var records = pathDatabase.GetClashDetectiveResultsByPath(pathName);
                _clashDetectiveResults.Clear();

                foreach (var record in records)
                {
                    _clashDetectiveResults.Add(new ClashDetectiveResultViewModel(record, RefreshClashDetectiveResultsList));
                }

                // 更新HasClashDetectiveResults属性
                HasClashDetectiveResults = _clashDetectiveResults.Count > 0;

                UpdateMainStatus($"已刷新ClashDetective结果列表：{_clashDetectiveResults.Count}条记录");
                LogManager.Info($"ClashDetective结果列表已刷新：{_clashDetectiveResults.Count}条记录");
            }
            catch (Exception ex)
            {
                LogManager.Error($"刷新ClashDetective结果列表失败: {ex.Message}");
                _clashDetectiveResults.Clear();
                HasClashDetectiveResults = false;
            }
        }

        private void ExecuteRefreshClashDetectiveResults()
        {
            RefreshClashDetectiveResultsList();
        }

        #endregion

        /// <summary>
        /// 异步预计算碰撞排除列表
        /// </summary>
        /// <param name="animationObject">动画对象</param>
        private async Task PrecomputeCollisionExclusionsAsync(ModelItem animationObject)
        {
            try
            {
                if (animationObject == null)
                {
                    return;
                }

                LogManager.Info($"[缓存预计算] 开始为新选择的动画对象预计算: {animationObject.DisplayName}");

                // 在UI线程中更新开始状态
                await System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
                {
                    UpdateMainStatus("正在分析动画对象...", -1, true);
                }));

                // 在UI线程中执行Navisworks API操作（线程安全）
                bool success;
                try
                {
                    success = _pathAnimationManager.PrecomputeCollisionExclusions(animationObject);
                }
                catch (Exception ex)
                {
                    LogManager.Error($"[缓存预计算] 预计算失败: {ex.Message}", ex);
                    success = false;
                }

                // 异步更新UI状态
                await System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
                {
                    if (success)
                    {
                        var cacheStats = _pathAnimationManager.GetCacheStats();
                        UpdateMainStatus("动画对象分析完成");
                        LogManager.Info($"[缓存预计算] 预计算成功 - {cacheStats}");
                    }
                    else
                    {
                        UpdateMainStatus("动画对象分析失败，无法生成动画");
                        LogManager.Error("[缓存预计算] 预计算失败: 无法构建碰撞排除列表");
                    }
                }));
            }
            catch (Exception ex)
            {
                LogManager.Error($"[缓存预计算] 异步预计算过程异常: {ex.Message}", ex);
                await System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
                {
                    UpdateMainStatus("动画对象分析异常");
                }));
            }
        }

        #endregion

        #region 手工碰撞对象辅助方法

        private void OnManualCollisionTargetsChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            UpdateManualCollisionTargetSummary();
            OnPropertyChanged(nameof(HasManualCollisionTargets));
            OnPropertyChanged(nameof(IsManualTargetModeActive));
            System.Windows.Input.CommandManager.InvalidateRequerySuggested();
            RefreshManualTargetHighlights();
            SyncManualCollisionTargetsToAnimationManager();
        }

        private void UpdateManualCollisionTargetSummary()
        {
            if (_manualCollisionTargets == null || _manualCollisionTargets.Count == 0)
            {
                ManualCollisionTargetSummary = "未指定碰撞检测对象";
                return;
            }

            var syncPart = _manualTargetsLastSyncTime.HasValue
                ? $" • 最近同步 {_manualTargetsLastSyncTime.Value:HH:mm:ss}"
                : string.Empty;
            ManualCollisionTargetSummary = $"{_manualCollisionTargets.Count} 个对象{syncPart}";
        }

        private string BuildModelPath(ModelItem item)
        {
            try
            {
                var segments = new List<string>();
                var current = item;
                int guard = 0;

                while (current != null && guard < 15)
                {
                    var name = ModelItemAnalysisHelper.GetSafeDisplayName(current);
                    if (!string.IsNullOrWhiteSpace(name))
                    {
                        segments.Add(name.Trim());
                    }
                    current = current.Parent;
                    guard++;
                }

                segments.Reverse();
                return string.Join(" / ", segments);
            }
            catch
            {
                return "路径获取失败";
            }
        }

        private List<ModelItem> GetValidManualCollisionTargets(bool pruneInvalidEntries = false)
        {
            var validItems = new List<ModelItem>();
            if (_manualCollisionTargets == null)
            {
                return validItems;
            }

            var invalidItems = new List<ManualCollisionTargetViewModel>();
            foreach (var entry in _manualCollisionTargets)
            {
                if (entry?.ModelItem != null &&
                    ModelItemAnalysisHelper.IsModelItemValid(entry.ModelItem) &&
                    HasGeometryRecursive(entry.ModelItem))
                {
                    validItems.Add(entry.ModelItem);
                }
                else if (pruneInvalidEntries && entry != null)
                {
                    invalidItems.Add(entry);
                }
            }

            if (pruneInvalidEntries && invalidItems.Count > 0)
            {
                foreach (var invalid in invalidItems)
                {
                    _manualCollisionTargets.Remove(invalid);
                }

                if (invalidItems.Count > 0)
                {
                    UpdateMainStatus("部分手工碰撞对象已失效，已自动清理");
                }
            }

            return validItems;
        }

        private void SyncManualCollisionTargetsToAnimationManager(bool pruneInvalidEntries = false)
        {
            if (_pathAnimationManager == null)
                return;

            var targets = GetValidManualCollisionTargets(pruneInvalidEntries);
            if (IsManualCollisionTargetEnabled && targets.Count > 0)
            {
                _pathAnimationManager.SetManualCollisionTargets(targets, true);
            }
            else
            {
                _pathAnimationManager.SetManualCollisionTargets(null, false);
            }
        }

        private bool ManualTargetExists(ModelItem item)
        {
            if (item == null)
            {
                return false;
            }

            if (_manualCollisionTargets == null || _manualCollisionTargets.Count == 0)
            {
                return false;
            }

            Guid itemGuid = item.InstanceGuid;
            foreach (var target in _manualCollisionTargets)
            {
                if (target == null)
                    continue;

                if (itemGuid != Guid.Empty && target.InstanceGuid != Guid.Empty)
                {
                    if (target.InstanceGuid == itemGuid)
                        return true;
                }
                else if (ReferenceEquals(target.ModelItem, item))
                {
                    return true;
                }
            }

            return false;
        }

        private void RefreshManualTargetHighlights(bool forceHighlight = false)
        {
            try
            {
                if (_clashIntegration == null)
                    return;

                var validItems = GetValidManualCollisionTargets();
                if (validItems.Count == 0)
                {
                    ModelHighlightHelper.ClearCategory(ManualTargetsHighlightCategory);
                    return;
                }

                if (IsManualTargetModeActive || forceHighlight)
                {
                    ModelHighlightHelper.HighlightItems(ManualTargetsHighlightCategory, validItems, ManualTargetHighlightColor);
                }
                else
                {
                    ModelHighlightHelper.ClearCategory(ManualTargetsHighlightCategory);
                }
            }
            catch (Exception ex)
            {
                LogManager.Warning($"[手工碰撞] 更新高亮失败: {ex.Message}");
            }
        }

        private void HandleManualCollisionModeChanged()
        {
            RefreshManualTargetHighlights();
            SyncManualCollisionTargetsToAnimationManager(true);

            if (IsManualCollisionTargetEnabled && !HasManualCollisionTargets)
            {
                UpdateMainStatus("手工模式已启用，请先选择碰撞检测对象");
            }
            else if (!IsManualCollisionTargetEnabled)
            {
                UpdateMainStatus("已切换回默认碰撞检测对象范围");
            }
        }

        #endregion

        #region 动画辅助方法

        /// <summary>
        /// 执行生成动画命令（同步执行，因为Navisworks API需要STA线程）
        /// </summary>
        private void ExecuteGenerateAnimation()
        {
            try
            {
                if (!CanGenerateAnimation)
                {
                    UpdateMainStatus("无法生成动画：缺少必要条件");
                    LogManager.Warning("尝试生成动画但条件不满足");
                    return;
                }

                UpdateMainStatus("正在生成动画...", -1, true);
                LogManager.Info($"开始生成动画 - 模式: {(UseVirtualVehicle ? "虚拟车辆" : "选择物体")}");

                var cacheStartTime = DateTime.Now;

                var manualModeEnabled = IsManualCollisionTargetEnabled;
                List<ModelItem> manualTargets = null;

                if (manualModeEnabled)
                {
                    manualTargets = GetValidManualCollisionTargets(pruneInvalidEntries: true);
                    if (manualTargets.Count == 0)
                    {
                        UpdateMainStatus("手工模式已启用，但没有可用的碰撞对象");
                        LogManager.Warning("[动画生成] 手工模式启用但没有有效对象");
                        return;
                    }
                }

                // 构建碰撞检测缓存（两种模式都需要几何对象缓存）
                UpdateMainStatus("正在构建碰撞检测缓存...", -1, true);
                LogManager.Info("[动画生成] 开始构建碰撞检测缓存");

                try
                {
                    if (!manualModeEnabled)
                    {
                        ClashDetectiveIntegration.ClearAllCaches();

                        UpdateMainStatus("正在缓存几何对象列表...", -1, true);
                        ClashDetectiveIntegration.BuildNonHidddenGeometryItemsCache();

                        UpdateMainStatus("正在缓存通道对象...", -1, true);
                        var clashIntegration = ClashDetectiveIntegration.Instance;
                        clashIntegration.BuildChannelObjectsCache();

                        var cacheElapsed = (DateTime.Now - cacheStartTime).TotalMilliseconds;
                        LogManager.Info($"[动画生成] 碰撞检测缓存构建完成，耗时: {cacheElapsed:F1}ms");

                        if (!UseVirtualVehicle)
                        {
                            UpdateMainStatus("正在分析动画对象...", -1, true);
                            var success = _pathAnimationManager.PrecomputeCollisionExclusions(SelectedAnimatedObject);

                            if (!success)
                            {
                                var msg = "[动画生成] 动画对象分析失败，无法继续生成动画";
                                LogManager.Error(msg);
                                UpdateMainStatus("生成失败：对象分析错误");
                                return;
                            }
                        }
                    }
                    else
                    {
                        UpdateMainStatus("使用手工碰撞对象，跳过几何缓存构建", -1, true);
                        LogManager.Info("[动画生成] 手工碰撞对象模式，已跳过几何体/通道缓存和空间索引构建");
                    }
                }
                catch (Exception cacheEx)
                {
                    LogManager.Error($"[动画生成] 缓存构建失败: {cacheEx.Message}");
                    UpdateMainStatus($"生成失败：{cacheEx.Message}");
                    return;
                }

                UpdateMainStatus("正在生成路径动画...", -1, true);

                // 设置动画参数到PathAnimationManager
                _pathAnimationManager.SetAnimationFrameRate(_animationFrameRate);
                _pathAnimationManager.SetCollisionDetectionAccuracy(CollisionDetectionAccuracy);
                _pathAnimationManager.SetMovementSpeed(MovementSpeed);
                _pathAnimationManager.SetDetectionGap(_detectionGap);

                // 将PathRouteViewModel的点转换为Point3D列表
                var pathPoints = CurrentPathRoute.Points.Select(p => new Point3D(p.X, p.Y, p.Z)).ToList();

                ModelItem animatedObject;

                if (UseVirtualVehicle)
                {
                    // 使用虚拟车辆：优先获取已存在的实例
                    animatedObject = VirtualVehicleManager.Instance.CurrentVirtualVehicle;

                    if (animatedObject == null)
                    {
                        LogManager.Info("[ExecuteGenerateAnimation] 虚拟车辆不存在，正在创建...");
                        UpdateMainStatus("正在创建虚拟车辆...", -1, true);

                        animatedObject = Core.VirtualVehicleManager.Instance.CreateVirtualVehicle(
                            VirtualVehicleLength,
                            VirtualVehicleWidth,
                            VirtualVehicleHeight
                        );
                    }

                    if (animatedObject == null)
                    {
                        LogManager.Error("[动画生成] 虚拟车辆创建失败");
                        UpdateMainStatus("生成失败：无法创建虚拟车辆");
                        return;
                    }

                    LogManager.Info($"使用虚拟车辆: {animatedObject.DisplayName}");
                }
                else
                {
                    animatedObject = SelectedAnimatedObject;
                }

                if (manualModeEnabled)
                {
                    _pathAnimationManager.SetManualCollisionTargets(manualTargets, true);
                }
                else
                {
                    _pathAnimationManager.SetManualCollisionTargets(null, false);
                }

                // 【统一使用CreateAnimation，完全复用现有逻辑】
                LogManager.Info($"[ExecuteGenerateAnimation] 准备创建动画: 路径名称='{CurrentPathRoute.Name}', ID='{CurrentPathRoute.Id}', " +
                               $"动画对象='{animatedObject.DisplayName}'");

                // 从PathPlanningManager获取PathRoute对象
                var pathPlanningManager = PathPlanningManager.Instance;
                var pathRoute = pathPlanningManager.GetAllRoutes().FirstOrDefault(r => r.Id == CurrentPathRoute.Id);

                if (pathRoute == null)
                {
                    LogManager.Error($"无法找到路径对象，ID: {CurrentPathRoute.Id}");
                    UpdateMainStatus("生成失败：找不到路径数据");
                    return;
                }

                // 先设置路径到动画管理器
                _pathAnimationManager.SetRoute(pathRoute);

                _pathAnimationManager.CreateAnimation(animatedObject, pathPoints, AnimationDuration, CurrentPathRoute.Name, CurrentPathRoute.Id);

                var totalElapsed = (DateTime.Now - cacheStartTime).TotalMilliseconds;
                LogManager.Info($"[动画生成] 动画生成完成，总耗时: {totalElapsed:F1}ms");
                LogManager.Info($"动画生成成功: 物体={animatedObject.DisplayName}, 路径={CurrentPathRoute.Name}");

                if (UseVirtualVehicle)
                {
                    LogManager.Info($"虚拟车辆尺寸: {VirtualVehicleLength:F1}×{VirtualVehicleWidth:F1}×{VirtualVehicleHeight:F1}m");
                }

                if (IsManualCollisionTargetEnabled)
                {
                    RefreshManualTargetHighlights(forceHighlight: true);
                }

                // 更新状态
                UpdateAnimationButtonStates();
                UpdateMainStatus("动画生成成功");
            }
            catch (Exception ex)
            {
                UpdateMainStatus("动画生成失败");
                LogManager.Error($"生成动画时发生错误: {ex.Message}");

                LogManager.Error($"动画生成失败，详细错误信息：{ex}");
            }
        }


        /// <summary>
        /// 更新移动物体信息
        /// </summary>
        private void UpdateAnimatedObjectInfo()
        {
            if (SelectedAnimatedObject != null)
            {
                SelectedAnimatedObjectName = SelectedAnimatedObject.DisplayName ?? "未命名物体";
                HasSelectedAnimatedObject = true;
            }
            else
            {
                SelectedAnimatedObjectName = "未选择移动物体";
                HasSelectedAnimatedObject = false;
            }
        }

        /// <summary>
        /// 递归检查ModelItem是否包含几何体
        /// </summary>
        private bool HasGeometryRecursive(ModelItem item)
        {
            if (item == null) return false;

            // 如果当前项有几何体，直接返回true
            if (item.HasGeometry) return true;

            // 递归检查子项
            foreach (ModelItem child in item.Children)
            {
                if (HasGeometryRecursive(child))
                    return true;
            }

            return false;
        }

        /// <summary>
        /// 更新是否可以生成动画的状态
        /// </summary>
        private void UpdateCanGenerateAnimation()
        {
            var hasPath = CurrentPathRoute != null && CurrentPathRoute.Points.Count >= 2;

            bool hasValidObject;
            if (UseVirtualVehicle)
            {
                // 使用虚拟车辆时，只需要有效的车辆尺寸
                hasValidObject = VirtualVehicleLength > 0 &&
                                VirtualVehicleWidth > 0 &&
                                VirtualVehicleHeight > 0;
            }
            else
            {
                // 使用选择物体时，需要已选择物体
                hasValidObject = SelectedAnimatedObject != null;
            }

            CanGenerateAnimation = hasValidObject && hasPath;

            // 更新状态提示
            if (IsManualCollisionTargetEnabled && !HasManualCollisionTargets)
            {
                UpdateMainStatus("手工模式已启用，请先选择碰撞检测对象");
            }
            else if (!hasPath && !hasValidObject)
            {
                UpdateMainStatus(UseVirtualVehicle ? "请选择动画路径" : "请选择移动物体和动画路径");
            }
            else if (!hasValidObject)
            {
                UpdateMainStatus(UseVirtualVehicle ? "虚拟车辆参数无效" : "请选择移动物体");
            }
            else if (!hasPath)
            {
                UpdateMainStatus("请选择有效的动画路径");
            }
            else
            {
                UpdateMainStatus("可以生成动画");
            }

            // 同时更新动画按钮状态，因为对象或路径的变化会影响"开始动画"按钮的可用性
            UpdateAnimationButtonStates();
        }


        /// <summary>
        /// 计算当前路径的总长度
        /// </summary>
        private double GetPathLength()
        {
            if (CurrentPathRoute == null || CurrentPathRoute.Points.Count < 2)
            {
                return 0.0;
            }

            double totalLength = 0.0;
            var points = CurrentPathRoute.Points;

            for (int i = 0; i < points.Count - 1; i++)
            {
                var p1 = points[i];
                var p2 = points[i + 1];

                // 计算两点之间的欧几里得距离（模型单位）
                double dx = p2.X - p1.X;
                double dy = p2.Y - p1.Y;
                double dz = p2.Z - p1.Z;

                double segmentLengthInModelUnits = Math.Sqrt(dx * dx + dy * dy + dz * dz);

                // 转换为米单位
                double segmentLengthInMeters = NavisworksTransport.Utils.UnitsConverter.ConvertToMeters(segmentLengthInModelUnits);
                totalLength += segmentLengthInMeters;
            }

            return totalLength;
        }

        /// <summary>
        /// 统一更新动画按钮状态逻辑
        /// 根据当前的路径、动画对象和动画管理器状态来决定按钮的可用性
        /// </summary>
        private void UpdateAnimationButtonStates()
        {
            try
            {
                // 检查是否有有效的动画可以播放
                var hasValidPath = CurrentPathRoute != null && CurrentPathRoute.Points.Count >= 2;
                var hasValidAnimatedObject = SelectedAnimatedObject != null;
                var hasValidAnimation = hasValidPath && hasValidAnimatedObject;

                // 检查动画管理器当前状态
                var animationState = _pathAnimationManager?.CurrentState ?? NavisworksTransport.Core.Animation.AnimationState.Stopped;
                var isAnimating = _pathAnimationManager?.IsAnimating ?? false;

                // 检查动画是否已经生成（Ready状态表示动画已生成但未播放）
                var isAnimationReady = animationState == NavisworksTransport.Core.Animation.AnimationState.Ready ||
                                      animationState == NavisworksTransport.Core.Animation.AnimationState.Finished;

                // 根据动画状态和条件更新按钮状态
                switch (animationState)
                {
                    case NavisworksTransport.Core.Animation.AnimationState.Playing:
                        // 播放中：开始按钮禁用，暂停和停止按钮可用
                        CanStartAnimation = false;
                        CanPauseAnimation = true;
                        CanStopAnimation = true;
                        UpdateMainStatus("动画播放中");
                        break;

                    case NavisworksTransport.Core.Animation.AnimationState.Paused:
                        // 暂停中：开始按钮可用（显示为继续），暂停按钮禁用，停止按钮可用
                        CanStartAnimation = hasValidAnimation && isAnimationReady;
                        CanPauseAnimation = false;
                        CanStopAnimation = true;
                        UpdateMainStatus("动画已暂停");
                        break;

                    default:
                        // 停止或其他状态：需要同时满足有效动画条件和动画已生成条件
                        CanStartAnimation = hasValidAnimation && isAnimationReady;
                        CanPauseAnimation = false;
                        CanStopAnimation = false;

                        // 更新状态文本
                        if (IsManualCollisionTargetEnabled && !HasManualCollisionTargets)
                        {
                            UpdateMainStatus("手工模式已启用，请先选择碰撞检测对象");
                        }
                        else if (!hasValidPath && !hasValidAnimatedObject)
                        {
                            UpdateMainStatus("请选择路径和移动物体");
                        }
                        else if (!hasValidPath)
                        {
                            UpdateMainStatus("请选择有效路径（至少2个点）");
                        }
                        else if (!hasValidAnimatedObject)
                        {
                            UpdateMainStatus("请选择移动物体");
                        }
                        else if (!isAnimationReady)
                        {
                            UpdateMainStatus("请点击'生成动画'");
                        }
                        else
                        {
                            UpdateMainStatus("动画就绪");
                        }
                        break;
                }

                LogManager.Debug($"按钮状态已更新: CanStart={CanStartAnimation}, CanPause={CanPauseAnimation}, CanStop={CanStopAnimation}");
            }
            catch (Exception ex)
            {
                LogManager.Error($"更新动画按钮状态时发生错误: {ex.Message}", ex);
            }
        }


        /// <summary>
        /// 生成碰撞检测报告数据
        /// </summary>
        private CollisionReportData GenerateCollisionReport()
        {
            try
            {
                LogManager.Info("开始从Clash Detective获取碰撞检测结果");

                var doc = Autodesk.Navisworks.Api.Application.ActiveDocument;
                var documentClash = doc.GetClash();

                if (documentClash == null)
                {
                    LogManager.Warning("无法获取Clash Detective文档");
                    return new CollisionReportData { IsValid = false, ErrorMessage = "Clash Detective不可用" };
                }

                var reportData = new CollisionReportData
                {
                    IsValid = true,
                    GeneratedTime = DateTime.Now,
                    AnimatedObjectName = SelectedAnimatedObject?.DisplayName ?? "未知对象",
                    PathName = CurrentPathRoute?.Name ?? "未知路径"
                };

                // 获取所有动画相关的碰撞测试（包括新的分组测试）
                var animationTests = documentClash.TestsData.Tests.Cast<ClashTest>()
                    .Where(t => t.DisplayName.Contains("物流碰撞检测") ||
                               t.DisplayName.Contains("物流碰撞"))
                    .ToList();

                LogManager.Info($"找到 {animationTests.Count} 个物流碰撞测试");

                foreach (var test in animationTests)
                {
                    // 递归统计测试中的碰撞总数（包括分组内的）
                    var totalCollisionCount = GetTotalClashResultCountForReport(test);

                    var testInfo = new CollisionTestInfo
                    {
                        TestName = test.DisplayName,
                        TestType = test.TestType.ToString(),
                        Tolerance = test.Tolerance,
                        CollisionCount = totalCollisionCount,
                        Status = test.Status.ToString()
                    };

                    // 递归获取每个碰撞的详细信息（包括分组内的）
                    var allClashResults = GetAllClashResultsFromTest(test);
                    foreach (var clashResult in allClashResults)
                    {
                        var collision = new CollisionDetailInfo
                        {
                            CollisionId = clashResult.Guid.ToString(),
                            Distance = clashResult.Distance,
                            Status = clashResult.Status.ToString()
                        };

                        // 获取碰撞对象信息
                        if (clashResult.CompositeItem1 != null)
                        {
                            collision.Object1Name = clashResult.CompositeItem1.DisplayName;
                            var point = clashResult.CompositeItem1.BoundingBox();
                            collision.Object1Position = $"({point.Center.X:F2}, {point.Center.Y:F2}, {point.Center.Z:F2})";
                        }

                        if (clashResult.CompositeItem2 != null)
                        {
                            collision.Object2Name = clashResult.CompositeItem2.DisplayName;
                            var point = clashResult.CompositeItem2.BoundingBox();
                            collision.Object2Position = $"({point.Center.X:F2}, {point.Center.Y:F2}, {point.Center.Z:F2})";
                        }

                        // 获取碰撞中心点
                        if (clashResult.Center != null)
                        {
                            collision.CollisionCenter = $"({clashResult.Center.X:F2}, {clashResult.Center.Y:F2}, {clashResult.Center.Z:F2})";
                        }

                        testInfo.Collisions.Add(collision);
                    }

                    reportData.Tests.Add(testInfo);
                }

                // 统计总体信息
                reportData.TotalTests = reportData.Tests.Count;
                reportData.TotalCollisions = reportData.Tests.Sum(t => t.CollisionCount);

                LogManager.Info($"碰撞报告生成完成：{reportData.TotalTests}个测试，{reportData.TotalCollisions}个碰撞");
                return reportData;
            }
            catch (Exception ex)
            {
                LogManager.Error($"生成碰撞报告异常: {ex.Message}");
                return new CollisionReportData { IsValid = false, ErrorMessage = ex.Message };
            }
        }

        /// <summary>
        /// 显示碰撞报告
        /// </summary>
        private async Task ShowCollisionReport(CollisionReportData reportData)
        {
            try
            {
                // 更新UI摘要信息
                await _uiStateManager.ExecuteUIUpdateAsync(() =>
                {
                    if (reportData.IsValid)
                    {
                        // 🔧 修复：显示动画过程缓存的碰撞数量，而非测试数量
                        var animationCollisionCount = _clashIntegration?.AnimationCollisionCount ?? 0;
                        var summary = $"动画碰撞: {animationCollisionCount}个 | Clash Detective权威结果: {reportData.TotalCollisions}个";
                        UpdateMainStatus("碰撞报告已生成");
                    }
                    else
                    {
                        UpdateMainStatus($"报告生成失败：{reportData.ErrorMessage}");
                    }
                });

                // 如果报告有效且有碰撞数据，用户可通过"查看碰撞报告"按钮查看详细信息
                if (reportData.IsValid && reportData.TotalCollisions > 0)
                {
                    LogManager.Info($"碰撞检测完成，发现 {reportData.TotalCollisions} 个碰撞问题。用户可通过报告按钮查看详细信息");
                }
                else if (reportData.IsValid && reportData.TotalCollisions == 0)
                {
                    // 没有碰撞时显示简单提示
                    LogManager.Info("未发现碰撞问题，路径规划良好");
                    System.Windows.MessageBox.Show(
                        "未发现碰撞问题，路径规划良好！",
                        "碰撞检测结果",
                        System.Windows.MessageBoxButton.OK,
                        System.Windows.MessageBoxImage.Information);
                }
                else
                {
                    // 报告无效时的错误处理
                    LogManager.Error($"碰撞报告数据无效: {reportData.ErrorMessage}");
                    System.Windows.MessageBox.Show(
                        $"碰撞报告生成失败：{reportData.ErrorMessage}",
                        "错误",
                        System.Windows.MessageBoxButton.OK,
                        System.Windows.MessageBoxImage.Error);
                }
            }
            catch (Exception ex)
            {
                LogManager.Error($"显示碰撞报告异常: {ex.Message}");
                System.Windows.MessageBox.Show(
                    $"显示碰撞报告时发生异常：{ex.Message}",
                    "错误",
                    System.Windows.MessageBoxButton.OK,
                    System.Windows.MessageBoxImage.Error);
            }
        }

        #endregion


        #region 文档管理

        /// <summary>
        /// 获取单例实例
        /// </summary>
        private static AnimationControlViewModel _instance;
        public static AnimationControlViewModel Instance
        {
            get { return _instance; }
            set { _instance = value; }
        }

        /// <summary>
        /// 文档失效时的处理
        /// </summary>
        private void OnDocumentInvalidated(object sender, EventArgs e)
        {
            try
            {
                LogManager.Info("[AnimationControlViewModel] 文档失效，重置状态");
                Reset();
            }
            catch (Exception ex)
            {
                LogManager.Error($"[AnimationControlViewModel] 处理文档失效失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 文档就绪时的处理
        /// </summary>
        private void OnDocumentReady(object sender, EventArgs e)
        {
            try
            {
                LogManager.Info("[AnimationControlViewModel] 文档就绪，启用功能");

                // 重新启用UI
                CanStartAnimation = true;
                CanGenerateAnimation = true;

                UpdateMainStatus("文档已加载，就绪");
            }
            catch (Exception ex)
            {
                LogManager.Error($"[AnimationControlViewModel] 处理文档就绪失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 重置视图模型状态
        /// </summary>
        public void Reset()
        {
            try
            {
                LogManager.Info("[AnimationControlViewModel] 重置状态");

                // 停止动画
                if (_pathAnimationManager != null && _pathAnimationManager.IsAnimating)
                {
                    _pathAnimationManager.CancelAnimation();
                }

                // 清空选中对象
                SelectedAnimatedObject = null;
                SelectedAnimatedObjectName = string.Empty;
                CurrentPathRoute = null;

                // 禁用按钮
                CanStartAnimation = false;
                CanPauseAnimation = false;
                CanStopAnimation = false;
                CanGenerateAnimation = false;
                HasSelectedAnimatedObject = false;

                // 清空碰撞结果
                HasCollisionResults = false;
                HasClashDetectiveResults = false;
                _latestCollisionResults.Clear();
                ModelHighlightHelper.ClearCollisionHighlights();

                UpdateMainStatus("已重置");
            }
            catch (Exception ex)
            {
                LogManager.Error($"[AnimationControlViewModel] 重置失败: {ex.Message}");
            }
        }

        #endregion

        #region 资源清理

        private bool _disposed = false;

        /// <summary>
        /// 清理资源
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// 清理资源
        /// </summary>
        protected virtual void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                if (disposing)
                {
                    try
                    {
                        LogManager.Info("开始清理AnimationControlViewModel资源");

                        // 1. 取消事件订阅（在停止动画之前，避免事件处理中访问已释放的对象）

                        // 取消DocumentStateManager事件订阅
                        try
                        {
                            DocumentStateManager.Instance.DocumentInvalidated -= OnDocumentInvalidated;
                            DocumentStateManager.Instance.DocumentReady -= OnDocumentReady;
                            LogManager.Debug("DocumentStateManager事件订阅取消完成");
                        }
                        catch (Exception docEx)
                        {
                            LogManager.Warning($"取消DocumentStateManager事件订阅时出现警告: {docEx.Message}");
                        }

                        if (_pathAnimationManager != null)
                        {
                            try
                            {
                                _pathAnimationManager.ProgressChanged -= OnAnimationProgressChanged;
                                _pathAnimationManager.StateChanged -= OnAnimationStateChanged;
                                LogManager.Debug("PathAnimationManager事件订阅取消完成");
                            }
                            catch (Exception eventEx)
                            {
                                LogManager.Warning($"取消PathAnimationManager事件订阅时出现警告: {eventEx.Message}");
                            }
                        }

                        if (_clashIntegration != null)
                        {
                            try
                            {
                                _clashIntegration.CollisionDetected -= OnCollisionDetected;
                                _clashIntegration.ClashDetectiveResultSaved -= OnClashDetectiveResultSaved;
                                LogManager.Debug("碰撞检测事件订阅取消完成");
                            }
                            catch (Exception eventEx)
                            {
                                LogManager.Warning($"取消碰撞检测事件订阅时出现警告: {eventEx.Message}");
                            }
                        }

                        if (_manualCollisionTargets != null)
                        {
                            _manualCollisionTargets.CollectionChanged -= OnManualCollisionTargetsChanged;
                            _manualCollisionTargets.Clear();
                        }


                        // 2. 不再清理PathAnimationManager - 现在使用单例模式，由应用程序生命周期管理
                        // 注意：PathAnimationManager.GetInstance()返回的是单例实例，
                        // 不应该在这里Dispose，否则会影响其他使用该单例的地方
                        if (_pathAnimationManager != null)
                        {
                            try
                            {
                                // 只清理事件订阅和停止动画，不调用Dispose，也不重置位置(避免访问已释放对象)
                                _pathAnimationManager.ShutdownAnimation();
                                LogManager.Debug("PathAnimationManager已执行关闭清理");
                            }
                            catch (Exception resetEx)
                            {
                                LogManager.Warning($"执行PathAnimationManager关闭清理时出现警告: {resetEx.Message}");
                            }
                        }

                        // 3. 清理PathAnimationManager缓存（缓存功能已迁移到PathAnimationManager）
                        // PathAnimationManager的Dispose已经包含了ClearExclusionCache的调用

                        LogManager.Info("AnimationControlViewModel资源清理完成");
                    }
                    catch (Exception ex)
                    {
                        LogManager.Error($"AnimationControlViewModel资源清理过程中发生异常: {ex.Message}");
                        // 即使清理过程中发生异常，也不应该抛出，因为这会干扰应用程序的正常关闭
                    }
                }

                _disposed = true;
            }
        }

        /// <summary>
        /// 递归统计测试中的碰撞结果总数（包括分组内的结果）- 用于报告
        /// </summary>
        private int GetTotalClashResultCountForReport(ClashTest test)
        {
            if (test == null) return 0;

            int totalCount = 0;
            foreach (var child in test.Children)
            {
                if (child is ClashResult)
                {
                    totalCount++;
                }
                else if (child is ClashResultGroup group)
                {
                    // 递归统计分组内的结果
                    totalCount += CountClashResultsInGroupForReport(group);
                }
            }

            return totalCount;
        }

        /// <summary>
        /// 递归统计分组内的碰撞结果数量 - 用于报告
        /// </summary>
        private int CountClashResultsInGroupForReport(ClashResultGroup group)
        {
            if (group == null) return 0;

            int count = 0;
            foreach (var child in group.Children)
            {
                if (child is ClashResult)
                {
                    count++;
                }
                else if (child is ClashResultGroup nestedGroup)
                {
                    // 递归处理嵌套分组
                    count += CountClashResultsInGroupForReport(nestedGroup);
                }
            }

            return count;
        }

        /// <summary>
        /// 递归获取测试中的所有碰撞结果（包括分组内的）- 用于报告
        /// </summary>
        private List<ClashResult> GetAllClashResultsFromTest(ClashTest test)
        {
            var results = new List<ClashResult>();
            if (test == null) return results;

            foreach (var child in test.Children)
            {
                if (child is ClashResult result)
                {
                    results.Add(result);
                }
                else if (child is ClashResultGroup group)
                {
                    // 递归获取分组内的结果
                    results.AddRange(GetAllClashResultsFromGroup(group));
                }
            }

            return results;
        }

        /// <summary>
        /// 递归获取分组内的所有碰撞结果 - 用于报告
        /// </summary>
        private List<ClashResult> GetAllClashResultsFromGroup(ClashResultGroup group)
        {
            var results = new List<ClashResult>();
            if (group == null) return results;

            foreach (var child in group.Children)
            {
                if (child is ClashResult result)
                {
                    results.Add(result);
                }
                else if (child is ClashResultGroup nestedGroup)
                {
                    // 递归处理嵌套分组
                    results.AddRange(GetAllClashResultsFromGroup(nestedGroup));
                }
            }

            return results;
        }

        #endregion
    }
}