using System;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using System.Windows.Threading;
using Autodesk.Navisworks.Api;
using Autodesk.Navisworks.Api.Plugins;
using ComApiBridge = Autodesk.Navisworks.Api.ComApi.ComApiBridge;
using NavisworksTransport.UI.WPF.Collections;
using NavisworksTransport.Core;
using NavisworksTransport.Core.Config;
using NavisworksTransport.Utils;
using NavisworksTransport.Utils.CoordinateSystem;
using NavisworksTransport.Commands;

namespace NavisworksTransport.UI.WPF.ViewModels
{
    /// <summary>
    /// 系统管理ViewModel - 处理插件系统管理功能
    /// </summary>
    public class SystemManagementViewModel : ViewModelBase, IDisposable
    {
        #region 私有字段

        private readonly UIStateManager _uiStateManager;
        private readonly HashSet<string> _documentRotationHintShown = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
        private readonly HashSet<string> _documentRotationHintPending = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

        // 日志管理字段
        private ObservableCollection<string> _logLevels;
        private string _selectedLogLevel = "Info";

        private string _pluginVersion = "v1.0";
        private string _navisworksVersion = "2026";
        private string _memoryUsage = "0 MB";
        private string _runningTime = "00:00:00";
        
        // 数据管理字段
        private string _databaseVersion = "--";
        private string _pathCount = "--";
        private string _collisionRecordCount = "--";
        private bool _autoBackupEnabled = true;
        private int _selectedBackupKeepCount = 10;
        private string _lastBackupInfo = "暂无备份记录";
        
        // 🔧 修复：添加释放状态标志
        private bool _disposed = false;

        // 系统信息刷新定时器
        private DispatcherTimer _systemInfoTimer;

        #endregion

        #region 公共属性

        /// <summary>
        /// 日志级别集合
        /// </summary>
        public ObservableCollection<string> LogLevels
        {
            get => _logLevels;
            set => SetProperty(ref _logLevels, value);
        }

        /// <summary>
        /// 选中的日志级别
        /// </summary>
        public string SelectedLogLevel
        {
            get => _selectedLogLevel;
            set
            {
                if (SetProperty(ref _selectedLogLevel, value))
                {
                    // 将字符串转换为LogLevel枚举并设置
                    if (Enum.TryParse<LogLevel>(value, out var level))
                    {
                        LogManager.SetLogLevel(level);
                        LogManager.Info($"日志级别已更改为: {value}");
                        UpdateMainStatus($"日志级别已设置为: {value}");
                    }
                }
            }
        }

        /// <summary>
        /// 插件版本
        /// </summary>
        public string PluginVersion
        {
            get => _pluginVersion;
            set => SetProperty(ref _pluginVersion, value);
        }

        /// <summary>
        /// Navisworks版本
        /// </summary>
        public string NavisworksVersion
        {
            get => _navisworksVersion;
            set => SetProperty(ref _navisworksVersion, value);
        }

        /// <summary>
        /// 内存使用情况
        /// </summary>
        public string MemoryUsage
        {
            get => _memoryUsage;
            set => SetProperty(ref _memoryUsage, value);
        }

        /// <summary>
        /// 运行时间
        /// </summary>
        public string RunningTime
        {
            get => _runningTime;
            set => SetProperty(ref _runningTime, value);
        }

        // 数据管理属性
        public string DatabaseVersion
        {
            get => _databaseVersion;
            set => SetProperty(ref _databaseVersion, value);
        }

        public string PathCount
        {
            get => _pathCount;
            set => SetProperty(ref _pathCount, value);
        }

        public string DetectionRecordCount
        {
            get => _collisionRecordCount;
            set => SetProperty(ref _collisionRecordCount, value);
        }

        public bool AutoBackupEnabled
        {
            get => _autoBackupEnabled;
            set => SetProperty(ref _autoBackupEnabled, value);
        }

        public ObservableCollection<int> BackupKeepCountOptions { get; } = new ObservableCollection<int> { 5, 10, 20, 50 };

        public int SelectedBackupKeepCount
        {
            get => _selectedBackupKeepCount;
            set => SetProperty(ref _selectedBackupKeepCount, value);
        }

        public string LastBackupInfo
        {
            get => _lastBackupInfo;
            set => SetProperty(ref _lastBackupInfo, value);
        }

        #endregion

        #region 命令

        public ICommand ViewLogCommand { get; private set; }
        public ICommand OpenSettingsCommand { get; private set; }
        public ICommand GeneratePerformanceReportCommand { get; private set; }
        public ICommand DiagnosticCommand { get; private set; }

        // 数据管理命令
        public ICommand BackupDataCommand { get; private set; }
        public ICommand RestoreDataCommand { get; private set; }
        public ICommand RepairDatabaseCommand { get; private set; }
        public ICommand ClearAllDataCommand { get; private set; }

        // 功能测试命令
        public ICommand TestVoxelGridSDFCommand { get; private set; }
        public ICommand TestVoxelPathFindingCommand { get; private set; }
        public ICommand ReadTransformTestCommand { get; private set; }
        public ICommand CoordinateSystemExplorerCommand { get; private set; }
        public ICommand CaptureRealObjectTransformCommand { get; private set; }
        public ICommand TestFaceInferCommand { get; private set; }


        // 坐标系设置
        public ObservableCollection<string> CoordinateSystemOptions { get; private set; }
        
        private string _selectedCoordinateSystem = "AutoDetect";
        public string SelectedCoordinateSystem
        {
            get => _selectedCoordinateSystem;
            set
            {
                if (SetProperty(ref _selectedCoordinateSystem, value))
                {
                    OnCoordinateSystemChanged(value);
                }
            }
        }
        
        private string _currentCoordinateSystemInfo = "当前坐标系: 未初始化";
        public string CurrentCoordinateSystemInfo
        {
            get => _currentCoordinateSystemInfo;
            set => SetProperty(ref _currentCoordinateSystemInfo, value);
        }

        #endregion

        #region 构造函数

        public SystemManagementViewModel() : base()
        {
            try
            {
                // 获取UI状态管理器实例
                _uiStateManager = UIStateManager.Instance;
                
                // 验证关键组件是否正常初始化
                if (_uiStateManager == null)
                {
                    LogManager.Error("UIStateManager初始化失败");
                    throw new InvalidOperationException("UIStateManager初始化失败");
                }

                // 初始化日志级别集合
                LogLevels = new ThreadSafeObservableCollection<string>();

                // 初始化命令
                InitializeCommands();

                // 初始化系统管理设置
                _ = InitializeSystemManagementSettingsAsync();
                
                // 订阅文档切换事件，以便重新检测坐标系
                SubscribeToDocumentEvents();

                LogManager.Info("SystemManagementViewModel构造函数执行完成");
            }
            catch (Exception ex)
            {
                LogManager.Error($"SystemManagementViewModel构造函数异常: {ex.Message}", ex);
                
                // 在构造函数中尽量保证对象处于可用状态
                UpdateMainStatus("初始化失败，请检查日志");
                throw;
            }
        }

        /// <summary>
        /// 带主ViewModel参数的构造函数，支持统一状态栏
        /// </summary>
        /// <param name="mainViewModel">主ViewModel，用于统一状态栏</param>
        public SystemManagementViewModel(LogisticsControlViewModel mainViewModel) : base()
        {
            try
            {
                // 设置主ViewModel引用到基类
                SetMainViewModel(mainViewModel);
                
                // 获取UI状态管理器实例
                _uiStateManager = UIStateManager.Instance;
                
                // 验证关键组件是否正常初始化
                if (_uiStateManager == null)
                {
                    LogManager.Error("UIStateManager初始化失败");
                    throw new InvalidOperationException("UIStateManager初始化失败");
                }

                // 初始化日志级别集合
                LogLevels = new ThreadSafeObservableCollection<string>();

                // 初始化命令
                InitializeCommands();

                // 初始化系统管理设置
                _ = InitializeSystemManagementSettingsAsync();

                LogManager.Info("SystemManagementViewModel构造函数执行完成 - 支持统一状态栏");
            }
            catch (Exception ex)
            {
                LogManager.Error($"SystemManagementViewModel构造函数异常: {ex.Message}", ex);
                
                // 在构造函数中尽量保证对象处于可用状态
                UpdateMainStatus("初始化失败，请检查日志");
                throw;
            }
        }

        #endregion

        #region 初始化

        /// <summary>
        /// 初始化命令
        /// </summary>
        private void InitializeCommands()
        {
            try
            {
                // 系统管理命令
                ViewLogCommand = new RelayCommand(() => ExecuteViewLog());
                OpenSettingsCommand = new RelayCommand(() => ExecuteOpenSettings());
                GeneratePerformanceReportCommand = new RelayCommand(() => ExecuteGeneratePerformanceReport());
                DiagnosticCommand = new RelayCommand(() => ExecuteDiagnostic());

                // 数据管理命令
                BackupDataCommand = new RelayCommand(() => ExecuteBackupData());
                RestoreDataCommand = new RelayCommand(() => ExecuteRestoreData());
                RepairDatabaseCommand = new RelayCommand(() => ExecuteRepairDatabase());
                ClearAllDataCommand = new RelayCommand(() => ExecuteClearAllData());

                // 功能测试命令
                TestVoxelGridSDFCommand = new RelayCommand(() => ExecuteTestVoxelGridSDF());
                TestVoxelPathFindingCommand = new RelayCommand(() => ExecuteTestVoxelPathFinding());
                ReadTransformTestCommand = new RelayCommand(() => ExecuteReadTransformTest());
                CoordinateSystemExplorerCommand = new RelayCommand(() => ExecuteCoordinateSystemExplorer());
                CaptureRealObjectTransformCommand = new RelayCommand(() => ExecuteCaptureRealObjectTransform());
                TestFaceInferCommand = new RelayCommand(() => ExecuteTestFaceInfer());


                // 初始化坐标系选项
                CoordinateSystemOptions = new ObservableCollection<string> { "AutoDetect", "ZUp", "YUp" };
                
                // 从配置加载当前坐标系设置
                var configType = ConfigManager.Instance.Current.CoordinateSystem?.Type ?? "AutoDetect";
                _selectedCoordinateSystem = configType;
                
                // 订阅文档事件（用于自动检测坐标系）
                SubscribeToDocumentEvents();
                
                // 检查当前是否已有活动文档，如果有立即检测
                if (Autodesk.Navisworks.Api.Application.ActiveDocument != null)
                {
                    InitializeCoordinateSystem();
                }
                else
                {
                    // 没有活动文档，显示等待状态
                    CurrentCoordinateSystemInfo = "当前坐标系: 等待文档加载...";
                }
                
                LogManager.Info("系统管理命令初始化完成");
            }
            catch (Exception ex)
            {
                LogManager.Error($"初始化命令失败: {ex.Message}", ex);
                throw;
            }
        }

        /// <summary>
        /// 获取路径规划管理器实例
        /// </summary>
        /// <returns>路径规划管理器或null</returns>
        private PathPlanningManager GetPathPlanningManager()
        {
            try
            {
                // 使用PathPlanningManager的静态方法获取活动实例
                var pathManager = PathPlanningManager.GetActivePathManager();
                if (pathManager != null)
                {
                    LogManager.Info("成功获取到活动的PathPlanningManager实例");
                    return pathManager;
                }
                else
                {
                    LogManager.Warning("当前没有活动的PathPlanningManager实例");
                    return null;
                }
            }
            catch (Exception ex)
            {
                LogManager.Error($"获取PathPlanningManager失败: {ex.Message}", ex);
                return null;
            }
        }

        /// <summary>
        /// 初始化坐标系
        /// </summary>
        private void InitializeCoordinateSystem()
        {
            try
            {
                // 解析配置类型
                if (!Enum.TryParse<CoordinateSystemType>(_selectedCoordinateSystem, out var configType))
                {
                    configType = CoordinateSystemType.AutoDetect;
                }
                
                // 初始化坐标系管理器
                CoordinateSystemManager.Instance.Initialize(configType);
                
                // 更新显示信息
                UpdateCoordinateSystemInfo();
                ShowRootModelRotationHintIfNeeded();
                
                LogManager.Info($"坐标系初始化完成: {configType}");
            }
            catch (Exception ex)
            {
                LogManager.Error($"坐标系初始化失败: {ex.Message}");
            }
        }
        
        /// <summary>
        /// 坐标系选择改变时调用
        /// </summary>
        private void OnCoordinateSystemChanged(string newValue)
        {
            try
            {
                if (!Enum.TryParse<CoordinateSystemType>(newValue, out var type))
                {
                    type = CoordinateSystemType.AutoDetect;
                }
                
                // 设置新坐标系
                CoordinateSystemManager.Instance.SetCoordinateSystem(type);
                
                // 更新显示信息
                UpdateCoordinateSystemInfo();
                
                // 更新配置
                ConfigManager.Instance.Current.CoordinateSystem.Type = newValue;
                
                UpdateMainStatus($"坐标系已切换为: {newValue}");
                LogManager.Info($"坐标系已手动切换为: {newValue}");
            }
            catch (Exception ex)
            {
                LogManager.Error($"切换坐标系失败: {ex.Message}");
                UpdateMainStatus($"切换坐标系失败: {ex.Message}");
            }
        }
        
        /// <summary>
        /// 更新坐标系显示信息
        /// </summary>
        private void UpdateCoordinateSystemInfo()
        {
            var info = CoordinateSystemManager.Instance.GetCurrentInfo();
            CurrentCoordinateSystemInfo = $"当前坐标系: {info}";
        }

        private string GetCurrentDocumentKey()
        {
            return FragmentDefaultUpContext.GetCurrentDocumentKey();
        }

        private void ShowRootModelRotationHintIfNeeded()
        {
            string documentKey = GetCurrentDocumentKey();
            if (string.IsNullOrWhiteSpace(documentKey) ||
                _documentRotationHintShown.Contains(documentKey) ||
                _documentRotationHintPending.Contains(documentKey))
            {
                return;
            }

            var doc = Autodesk.Navisworks.Api.Application.ActiveDocument;
            if (doc == null || doc.IsClear || doc.Models == null || doc.Models.Count == 0)
            {
                return;
            }

            if (!TryGetRootModelRotationHint(doc, out string hintMessage))
            {
                return;
            }

            _documentRotationHintPending.Add(documentKey);
            _ = Task.Run(async () =>
            {
                try
                {
                    await Task.Delay(1500).ConfigureAwait(false);
                    _uiStateManager?.QueueUIUpdate(() =>
                    {
                        try
                        {
                            string currentDocumentKey = GetCurrentDocumentKey();
                            if (!string.Equals(documentKey, currentDocumentKey, StringComparison.OrdinalIgnoreCase))
                            {
                                _documentRotationHintPending.Remove(documentKey);
                                return;
                            }

                            if (_documentRotationHintShown.Contains(documentKey))
                            {
                                _documentRotationHintPending.Remove(documentKey);
                                return;
                            }

                            _documentRotationHintShown.Add(documentKey);
                            _documentRotationHintPending.Remove(documentKey);
                            LogManager.Info($"[模型整体旋转提示] {hintMessage}");
                            DialogHelper.ShowAutoClosingMessageBox(
                                hintMessage,
                                "坐标系提示",
                                System.Windows.MessageBoxImage.Information,
                                autoCloseMilliseconds: 4000);
                        }
                        catch (Exception ex)
                        {
                            _documentRotationHintPending.Remove(documentKey);
                            LogManager.Warning($"[模型整体旋转提示] 延后弹出失败: {ex.Message}");
                        }
                    });
                }
                catch (Exception ex)
                {
                    _documentRotationHintPending.Remove(documentKey);
                    LogManager.Warning($"[模型整体旋转提示] 延后任务失败: {ex.Message}");
                }
            });
        }

        private static bool TryGetRootModelRotationHint(Document doc, out string hintMessage)
        {
            hintMessage = null;
            if (doc == null || doc.Models == null || doc.Models.Count == 0)
            {
                return false;
            }

            const double minAngleDegrees = 1.0;

            for (int i = 0; i < doc.Models.Count; i++)
            {
                Model model = doc.Models[i];
                ModelItem rootItem = model?.RootItem;
                if (rootItem == null)
                {
                    continue;
                }

                Transform3DComponents components = rootItem.Transform.Factor();
                var axisAngle = components.Rotation.ToAxisAndAngle();
                double angleDegrees = Math.Abs(axisAngle.Angle) * 180.0 / Math.PI;
                if (angleDegrees < minAngleDegrees)
                {
                    continue;
                }

                hintMessage =
                    $"检测到根模型存在整体旋转（约 {angleDegrees:F1}°），模型可能经过坐标系转换；如后续真实物体姿态异常，请检查坐标系设置。";
                return true;
            }

            return false;
        }

        #region 文档事件处理

        /// <summary>
        /// 订阅文档切换事件
        /// </summary>
        private void SubscribeToDocumentEvents()
        {
            try
            {
                // 订阅文档切换后事件（文档已完全加载）
                Autodesk.Navisworks.Api.Application.ActiveDocumentChanged += OnActiveDocumentChanged;
                
                // 同时订阅模型集合变化事件（SDI架构下的真正文档变化）
                if (Autodesk.Navisworks.Api.Application.ActiveDocument != null)
                {
                    Autodesk.Navisworks.Api.Application.ActiveDocument.Models.CollectionChanged += OnModelsCollectionChanged;
                }
                
                LogManager.Info("[系统管理] 已订阅文档相关事件");
            }
            catch (Exception ex)
            {
                LogManager.Error($"[系统管理] 订阅文档事件失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 取消订阅文档事件
        /// </summary>
        private void UnsubscribeFromDocumentEvents()
        {
            try
            {
                // 取消订阅文档切换事件
                Autodesk.Navisworks.Api.Application.ActiveDocumentChanged -= OnActiveDocumentChanged;
                
                // 取消订阅模型集合变化事件
                if (Autodesk.Navisworks.Api.Application.ActiveDocument != null)
                {
                    Autodesk.Navisworks.Api.Application.ActiveDocument.Models.CollectionChanged -= OnModelsCollectionChanged;
                }
                
                LogManager.Info("[系统管理] 已取消订阅文档相关事件");
            }
            catch (Exception ex)
            {
                LogManager.Warning($"[系统管理] 取消订阅文档事件时出现警告: {ex.Message}");
            }
        }

        /// <summary>
        /// 文档切换事件处理
        /// </summary>
        private void OnActiveDocumentChanged(object sender, EventArgs e)
        {
            try
            {
                LogManager.Info("[系统管理] 检测到文档切换");
                
                // 订阅新文档的 Models.CollectionChanged
                if (Autodesk.Navisworks.Api.Application.ActiveDocument != null)
                {
                    try
                    {
                        Autodesk.Navisworks.Api.Application.ActiveDocument.Models.CollectionChanged += OnModelsCollectionChanged;
                        LogManager.Info("[系统管理] 已订阅新文档的模型集合变化事件");
                    }
                    catch (Exception ex)
                    {
                        LogManager.Warning($"[系统管理] 订阅模型集合变化事件失败: {ex.Message}");
                    }
                }
                
                // 执行坐标系检测
                HandleDocumentChange();
            }
            catch (Exception ex)
            {
                LogManager.Error($"[系统管理] 文档切换处理失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 模型集合变化事件处理（SDI架构下的真正文档变化）
        /// </summary>
        private void OnModelsCollectionChanged(object sender, EventArgs e)
        {
            try
            {
                LogManager.Info("[系统管理] 检测到模型集合变化");
                HandleDocumentChange();
            }
            catch (Exception ex)
            {
                LogManager.Error($"[系统管理] 模型集合变化处理失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 处理文档变化，重新检测坐标系
        /// </summary>
        private void HandleDocumentChange()
        {
            // 检查文档是否已完全加载
            var doc = Autodesk.Navisworks.Api.Application.ActiveDocument;
            if (doc == null || string.IsNullOrEmpty(doc.FileName))
            {
                LogManager.Debug("[系统管理] 文档尚未完全加载，跳过坐标系检测");
                return;
            }

            // 如果配置为自动检测，重新检测坐标系
            if (_selectedCoordinateSystem == "AutoDetect")
            {
                // 在 UI 线程执行
                _ = _uiStateManager.ExecuteUIUpdateAsync(() =>
                {
                    try
                    {
                        InitializeCoordinateSystem();
                        UpdateMainStatus("坐标系已根据新文档重新检测");
                    }
                    catch (Exception ex)
                    {
                        LogManager.Error($"[系统管理] 坐标系检测失败: {ex.Message}");
                    }
                });
            }
        }

        #endregion

        /// <summary>
        /// 初始化系统管理设置
        /// </summary>
        private async Task InitializeSystemManagementSettingsAsync()
        {
            await SafeExecuteAsync(async () =>
            {
                await _uiStateManager.ExecuteUIUpdateAsync(() =>
                {
                    // 初始化日志级别
                    LogLevels.Clear();
                    LogLevels.Add("Debug");
                    LogLevels.Add("Info");
                    LogLevels.Add("Warning");
                    LogLevels.Add("Error");

                    // 获取当前日志级别
                    var currentLevel = LogManager.GetLogLevel();
                    SelectedLogLevel = currentLevel.ToString();

                    // 初始化系统信息 - 使用动态获取
                    var systemInfo = VersionInfo.GetSystemInfo();
                    PluginVersion = systemInfo.PluginVersion;
                    NavisworksVersion = systemInfo.NavisworksVersion;
                    MemoryUsage = systemInfo.MemoryUsage;
                    RunningTime = systemInfo.RunningTime;
                    
                    // 初始化数据库状态（如果数据库已连接）
                    RefreshDatabaseStatus();
                    
                    // 启动系统信息定时刷新
                    StartSystemInfoTimer();
                    
                    UpdateMainStatus("系统管理初始化完成");
                });

                LogManager.Info("系统管理设置初始化完成");
            }, "初始化系统管理设置");
        }

        #endregion

        #region 命令实现


        /// <summary>
        /// 查看日志
        /// </summary>
        private void ExecuteViewLog()
        {
            SafeExecute(() =>
            {
                try
                {
                    // 创建并显示日志查看器对话框
                    var logViewerDialog = new NavisworksTransport.UI.WPF.Views.LogViewerDialog();
                    
                    // 设置窗口所有者
                    DialogHelper.SetOwnerSafely(logViewerDialog);
                    
                    // 显示对话框（使用Show而不是ShowDialog以避免阻塞）
                    logViewerDialog.Show();
                    
                    UpdateMainStatus("日志查看器已打开");
                    LogManager.Info("通过系统管理打开日志查看器");
                }
                catch (Exception ex)
                {
                    UpdateMainStatus("打开日志查看器失败");
                    LogManager.Error($"打开日志查看器失败: {ex.Message}", ex);
                    
                    // 显示错误消息给用户
                    System.Windows.MessageBox.Show($"打开日志查看器失败: {ex.Message}", "错误", 
                                                  System.Windows.MessageBoxButton.OK, 
                                                  System.Windows.MessageBoxImage.Error);
                }
            }, "查看日志");
        }

        /// <summary>
        /// 打开设置
        /// </summary>
        private void ExecuteOpenSettings()
        {
            SafeExecute(() =>
            {
                try
                {
                    // 使用模态配置编辑器，确保键盘输入不会被 Navisworks 主窗口截获
                    var dialog = NavisworksTransport.UI.WPF.Views.ConfigEditorDialog.ShowEditor();
                    
                    if (dialog != null)
                    {
                        UpdateMainStatus("配置编辑器已关闭");
                        LogManager.Info("配置编辑器：已打开并关闭（模态）");
                    }
                    else
                    {
                        UpdateMainStatus("配置编辑器已在运行");
                        LogManager.Info("配置编辑器：窗口已存在并已激活");
                    }
                }
                catch (Exception ex)
                {
                    UpdateMainStatus("打开配置编辑器失败");
                    LogManager.Error($"打开配置编辑器失败: {ex.Message}", ex);

                    System.Windows.MessageBox.Show($"打开配置编辑器失败: {ex.Message}", "错误",
                                                  System.Windows.MessageBoxButton.OK,
                                                  System.Windows.MessageBoxImage.Error);
                }
            }, "打开设置");
        }

        /// <summary>
        /// 生成性能报告 (已优化为Idle事件监听)
        /// </summary>
        private void ExecuteGeneratePerformanceReport()
        {
            SafeExecute(() =>
            {
                UpdateMainStatus("正在生成性能报告...");
                
                // 使用Idle事件监听替代Thread.Sleep(1500)
                const string taskId = "SystemManagement_GenerateReport";
                var startTime = DateTime.Now;
                
                IdleEventManager.Instance.RegisterOnceTask(
                    taskId,
                    () => (DateTime.Now - startTime).TotalMilliseconds >= 1500, // 1.5秒后条件满足
                    () =>
                    {
                        try
                        {
                            // 检查释放状态，避免在释放后更新UI
                            if (_disposed)
                            {
                                LogManager.Info("SystemManagementViewModel已释放，跳过性能报告UI更新");
                                return;
                            }
                            
                            UpdateMainStatus("性能报告生成完成");
                            // 性能信息更新已合并到统一状态栏
                        }
                        catch (Exception ex)
                        {
                            LogManager.Error($"性能报告UI更新失败: {ex.Message}");
                        }
                    },
                    8 // 高优先级
                );
                
                LogManager.Info("生成性能报告 (使用Idle事件监听)");
            }, "生成性能报告");
        }

        /// <summary>
        /// 执行环境诊断
        /// </summary>
        private void ExecuteDiagnostic()
        {
            SafeExecute(() =>
            {
                try
                {
                    LogManager.Info("开始环境诊断");
                    
                    // 直接调用本地的环境诊断方法
                    string diagnosticReport = DiagnoseEnvironment();
                    
                    // 显示诊断结果对话框
                    System.Windows.MessageBox.Show(
                        diagnosticReport, 
                        "环境诊断结果", 
                        System.Windows.MessageBoxButton.OK, 
                        System.Windows.MessageBoxImage.Information);
                    
                    LogManager.Info("环境诊断完成");
                }
                catch (Exception ex)
                {
                    LogManager.Error($"环境诊断失败: {ex.Message}", ex);
                    System.Windows.MessageBox.Show(
                        $"环境诊断失败: {ex.Message}", 
                        "错误", 
                        System.Windows.MessageBoxButton.OK, 
                        System.Windows.MessageBoxImage.Error);
                }
            }, "环境诊断");
        }

        /// <summary>
        /// 环境诊断方法 - 快速检查API是否可用
        /// </summary>
        /// <returns>诊断报告</returns>
        private string DiagnoseEnvironment()
        {
            var report = new System.Text.StringBuilder();

            try
            {
                // 1. 线程状态
                var apartmentState = System.Threading.Thread.CurrentThread.GetApartmentState();
                report.AppendLine($"线程状态: {apartmentState} {(apartmentState == System.Threading.ApartmentState.STA ? "✓" : "✗")}");

                // 2. API可用性
                try
                {
                    var app = Autodesk.Navisworks.Api.Application.ActiveDocument;
                    report.AppendLine("API可用性: 可用 ✓");
                }
                catch (Exception apiEx)
                {
                    report.AppendLine($"API可用性: 异常 - {apiEx.Message} ✗");
                }

                // 3. 文档状态
                try
                {
                    var document = Autodesk.Navisworks.Api.Application.ActiveDocument;
                    if (document != null)
                    {
                        report.AppendLine($"活动文档: {document.FileName ?? "未命名"} ✓");
                        report.AppendLine($"模型数量: {document.Models?.Count ?? 0}");
                    }
                    else
                    {
                        report.AppendLine("活动文档: 无 ✗");
                    }
                }
                catch (Exception docEx)
                {
                    report.AppendLine($"活动文档: 异常 - {docEx.Message} ✗");
                }

                // 4. 内存状态
                long memoryMB = GC.GetTotalMemory(false) / 1024 / 1024;
                report.AppendLine($"当前内存: {memoryMB} MB");

                // 5. 系统信息
                report.AppendLine($"插件版本: {PluginVersion}");
                report.AppendLine($"Navisworks版本: {NavisworksVersion}");
                report.AppendLine("系统状态: 正常");

                string result = report.ToString();
                LogManager.Info($"[SystemManagement] 环境诊断报告:\n{result}");
                return result;
            }
            catch (Exception ex)
            {
                string error = $"诊断过程出错: {ex.Message}";
                report.AppendLine(error);
                LogManager.Error($"[SystemManagement] {error}");
                return report.ToString();
            }
        }

        #region 数据管理方法

        /// <summary>
        /// 刷新数据库状态信息
        /// </summary>
        private void RefreshDatabaseStatus()
        {
            try
            {
                var pathDatabase = PathPlanningManager.Instance?.GetPathDatabase();
                if (pathDatabase != null)
                {
                    // 获取数据库信息
                    var dbInfo = pathDatabase.Backup.GetDatabaseInfo();
                    DatabaseVersion = dbInfo.VersionFormatted;
                    PathCount = dbInfo.PathRoutesCount.ToString();
                    DetectionRecordCount = dbInfo.DetectionRecordsCount.ToString();
                    LogManager.Debug($"数据库状态: 版本{dbInfo.VersionFormatted}, 路径{dbInfo.PathRoutesCount}, 点{dbInfo.PathPointsCount}, 边{dbInfo.PathEdgesCount}, 碰撞{dbInfo.DetectionRecordsCount}");
                }
                else
                {
                    DatabaseVersion = "未创建";
                    PathCount = "--";
                    DetectionRecordCount = "--";
                }
            }
            catch (Exception ex)
            {
                LogManager.Error($"刷新数据库状态失败: {ex.Message}");
                DatabaseVersion = "错误";
                PathCount = "--";
                DetectionRecordCount = "--";
            }
        }

        private PathDatabase GetDatabaseForSystemManagement(string operationName)
        {
            var pathDatabase = PathPlanningManager.Instance?.GetPathDatabase();
            if (pathDatabase != null)
            {
                return pathDatabase;
            }

            System.Windows.MessageBox.Show(
                "当前文档还没有数据库文件。\n\n请先执行会产生持久化数据的操作（例如保存路径），或先恢复一个数据库备份，再使用这个功能。",
                operationName,
                System.Windows.MessageBoxButton.OK,
                System.Windows.MessageBoxImage.Information);
            UpdateMainStatus($"{operationName}未执行：当前文档没有数据库");
            LogManager.Info($"[{operationName}] 当前文档没有数据库，已阻止操作");
            RefreshDatabaseStatus();
            return null;
        }

        /// <summary>
        /// 执行数据备份
        /// </summary>
        private void ExecuteBackupData()
        {
            SafeExecute(() =>
            {
                try
                {
                    var pathDatabase = GetDatabaseForSystemManagement("备份数据");
                    if (pathDatabase == null) return;

                    UpdateMainStatus("正在备份数据库...");
                    LogManager.Info("开始数据库文件备份");

                    string backupPath = pathDatabase.Backup.BackupDatabase();

                    if (!string.IsNullOrEmpty(backupPath))
                    {
                        var info = pathDatabase.Backup.GetDatabaseInfo();
                        LastBackupInfo = $"上次备份: {DateTime.Now:yyyy-MM-dd HH:mm:ss}, 版本{info.VersionFormatted}, {info.FileSizeFormatted}";
                        System.Windows.MessageBox.Show(
                            $"数据库备份完成！\n\n" +
                            $"版本: {info.VersionFormatted}\n" +
                            $"文件: {backupPath}\n\n" +
                            $"包含数据:\n" +
                            $"- 路径: {info.PathRoutesCount} 条\n" +
                            $"- 路径点: {info.PathPointsCount} 个\n" +
                            $"- 检测记录: {info.DetectionRecordsCount} 条\n" +
                            $"- 截图: {info.ScreenshotsCount} 张",
                            "备份成功",
                            System.Windows.MessageBoxButton.OK,
                            System.Windows.MessageBoxImage.Information);
                        UpdateMainStatus("数据库备份完成");
                        LogManager.Info($"数据库备份完成: {backupPath}, 版本{info.VersionFormatted}");
                    }
                }
                catch (Exception ex)
                {
                    LogManager.Error($"数据备份失败: {ex.Message}");
                    System.Windows.MessageBox.Show(
                        $"数据备份失败: {ex.Message}",
                        "备份失败",
                        System.Windows.MessageBoxButton.OK,
                        System.Windows.MessageBoxImage.Error);
                    UpdateMainStatus("数据备份失败");
                }
            }, "数据备份");
        }

        /// <summary>
        /// 执行数据恢复
        /// </summary>
        private void ExecuteRestoreData()
        {
            SafeExecute(() =>
            {
                try
                {
                    var pathDatabase = GetDatabaseForSystemManagement("恢复数据");
                    if (pathDatabase == null) return;

                    // 选择备份文件
                    var openFileDialog = new Microsoft.Win32.OpenFileDialog
                    {
                        Title = "选择数据库备份文件",
                        Filter = "数据库备份文件 (*.db)|*.db",
                        InitialDirectory = System.IO.Path.Combine(
                            Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
                            "NavisworksTransport", "Backups")
                    };

                    if (openFileDialog.ShowDialog() != true)
                    {
                        return;
                    }

                    // 确认恢复
                    var result = System.Windows.MessageBox.Show(
                        "恢复数据将覆盖现有数据，建议先备份当前数据。\n\n是否继续？",
                        "确认恢复",
                        System.Windows.MessageBoxButton.YesNo,
                        System.Windows.MessageBoxImage.Warning);

                    if (result != System.Windows.MessageBoxResult.Yes)
                    {
                        return;
                    }

                    UpdateMainStatus("正在恢复数据库...");
                    LogManager.Info($"开始数据库恢复: {openFileDialog.FileName}");

                    pathDatabase.Backup.RestoreDatabase(openFileDialog.FileName);
                    
                    // 恢复成功
                    bool restoreSuccess = true;

                    if (restoreSuccess)
                    {
                        // 刷新数据库状态
                        RefreshDatabaseStatus();
                        
                        var info = pathDatabase.Backup.GetDatabaseInfo();
                        System.Windows.MessageBox.Show(
                            $"数据库恢复完成！\n\n" +
                            $"当前数据:\n" +
                            $"- 路径: {info.PathRoutesCount} 条\n" +
                            $"- 路径点: {info.PathPointsCount} 个\n" +
                            $"- 检测记录: {info.DetectionRecordsCount} 条\n" +
                            $"- 截图: {info.ScreenshotsCount} 张\n\n" +
                            $"请重新启动 Navisworks 以加载恢复的数据。",
                            "恢复成功",
                            System.Windows.MessageBoxButton.OK,
                            System.Windows.MessageBoxImage.Information);
                        UpdateMainStatus("数据恢复完成");
                        LogManager.Info("数据恢复完成");

                        // 刷新显示
                        RefreshDatabaseStatus();
                    }
                }
                catch (Exception ex)
                {
                    LogManager.Error($"数据恢复失败: {ex.Message}");
                    System.Windows.MessageBox.Show(
                        $"数据恢复失败: {ex.Message}",
                        "恢复失败",
                        System.Windows.MessageBoxButton.OK,
                        System.Windows.MessageBoxImage.Error);
                    UpdateMainStatus("数据恢复失败");
                }
            }, "数据恢复");
        }

        /// <summary>
        /// 执行数据库修复
        /// </summary>
        private void ExecuteRepairDatabase()
        {
            SafeExecute(() =>
            {
                try
                {
                    var pathDatabase = GetDatabaseForSystemManagement("修复数据库");
                    if (pathDatabase == null) return;

                    UpdateMainStatus("正在检查数据库...");
                    LogManager.Info("开始数据库修复检查");

                    // 获取数据库信息
                    var info = pathDatabase.Backup.GetDatabaseInfo();
                    
                    System.Windows.MessageBox.Show(
                        $"数据库检查结果:\n\n" +
                        $"版本: {info.VersionFormatted}\n" +
                        $"文件大小: {info.FileSizeFormatted}\n" +
                        $"路径数量: {info.PathRoutesCount} 条\n" +
                        $"路径点: {info.PathPointsCount} 个\n" +
                        $"路径边: {info.PathEdgesCount} 条\n" +
                        $"检测记录: {info.DetectionRecordsCount} 条\n" +
                        $"截图: {info.ScreenshotsCount} 张",
                        "检查结果",
                        System.Windows.MessageBoxButton.OK,
                        System.Windows.MessageBoxImage.Information);

                    // 刷新状态
                    RefreshDatabaseStatus();
                    UpdateMainStatus("数据库检查完成");
                }
                catch (Exception ex)
                {
                    LogManager.Error($"数据库修复失败: {ex.Message}");
                    System.Windows.MessageBox.Show(
                        $"数据库修复失败: {ex.Message}",
                        "修复失败",
                        System.Windows.MessageBoxButton.OK,
                        System.Windows.MessageBoxImage.Error);
                    UpdateMainStatus("数据库修复失败");
                }
            }, "数据库修复");
        }

        /// <summary>
        /// 执行清空所有数据
        /// </summary>
        private void ExecuteClearAllData()
        {
            SafeExecute(() =>
            {
                try
                {
                    var pathDatabase = GetDatabaseForSystemManagement("清空数据");
                    if (pathDatabase == null) return;

                    // 双重确认
                    var result1 = System.Windows.MessageBox.Show(
                        "⚠️ 警告：此操作将永久删除所有路径和检测记录！\n\n" +
                        "建议先备份数据。\n\n" +
                        "是否继续？",
                        "确认清空数据",
                        System.Windows.MessageBoxButton.YesNo,
                        System.Windows.MessageBoxImage.Warning);

                    if (result1 != System.Windows.MessageBoxResult.Yes)
                    {
                        return;
                    }

                    var result2 = System.Windows.MessageBox.Show(
                        "请再次确认：是否永久删除所有数据？\n\n" +
                        "此操作不可恢复！",
                        "最终确认",
                        System.Windows.MessageBoxButton.YesNo,
                        System.Windows.MessageBoxImage.Warning);

                    if (result2 != System.Windows.MessageBoxResult.Yes)
                    {
                        return;
                    }

                    UpdateMainStatus("正在清空数据...");
                    LogManager.Info("开始清空所有数据");

                    // 清空所有表
                    pathDatabase.ClearAllData();

                    System.Windows.MessageBox.Show(
                        "所有数据已清空！",
                        "清空完成",
                        System.Windows.MessageBoxButton.OK,
                        System.Windows.MessageBoxImage.Information);
                    UpdateMainStatus("数据已清空");
                    LogManager.Info("所有数据已清空");

                    // 刷新状态
                    RefreshDatabaseStatus();
                }
                catch (Exception ex)
                {
                    LogManager.Error($"清空数据失败: {ex.Message}");
                    System.Windows.MessageBox.Show(
                        $"清空数据失败: {ex.Message}",
                        "操作失败",
                        System.Windows.MessageBoxButton.OK,
                        System.Windows.MessageBoxImage.Error);
                    UpdateMainStatus("清空数据失败");
                }
            }, "清空数据");
        }

        #endregion

        /// <summary>
        /// 执行体素网格 SDF 测试（使用 MeshSignedDistanceGrid）
        /// </summary>
        private async void ExecuteTestVoxelGridSDF()
        {
            await SafeExecuteAsync(async () =>
            {
                try
                {
                    UpdateMainStatus("正在执行体素网格 SDF 测试...");
                    LogManager.Info("开始体素网格 SDF 测试（使用 MeshSignedDistanceGrid）");

                    // 获取当前文档
                    var document = Autodesk.Navisworks.Api.Application.ActiveDocument;
                    if (document == null)
                    {
                        System.Windows.MessageBox.Show(
                            "未找到活动文档，请先打开一个 Navisworks 模型",
                            "体素网格 SDF 测试",
                            System.Windows.MessageBoxButton.OK,
                            System.Windows.MessageBoxImage.Warning);
                        UpdateMainStatus("体素网格 SDF 测试取消：无活动文档");
                        return;
                    }

                    // 创建并执行体素网格 SDF 测试命令
                    // 使用系统配置的网格大小参数
                    double cellSizeMeters = ConfigManager.Instance.Current.PathEditing.CellSizeMeters;
                    LogManager.Info($"使用系统配置的体素大小: {cellSizeMeters}米");

                    var testCommand = new VoxelGridSDFTestCommand(
                        document,
                        cellSize: cellSizeMeters,  // 使用系统配置的体素大小
                        samplingRate: 1,           // 采样率 1（显示所有体素）
                        objectRadius: 0.6,        // 物体半径 0.6米（必须 >= 体素大小才能看到膨胀效果）
                        objectHeight: 1.8         // 物体高度 1.8米
                    );

                    var result = await testCommand.ExecuteAsync();

                    if (result.IsSuccess)
                    {
                        // 显示测试结果
                        System.Windows.MessageBox.Show(
                            $"体素网格 SDF 测试成功！\n\n{result.Message}\n\n详细信息请查看日志。",
                            "体素网格 SDF 测试结果",
                            System.Windows.MessageBoxButton.OK,
                            System.Windows.MessageBoxImage.Information);

                        UpdateMainStatus("体素网格 SDF 测试完成");
                        LogManager.Info($"体素网格 SDF 测试成功: {result.Message}");
                    }
                    else
                    {
                        System.Windows.MessageBox.Show(
                            $"体素网格 SDF 测试失败：\n{result.Message}",
                            "体素网格 SDF 测试",
                            System.Windows.MessageBoxButton.OK,
                            System.Windows.MessageBoxImage.Error);

                        UpdateMainStatus($"体素网格 SDF 测试失败: {result.Message}");
                        LogManager.Error($"体素网格 SDF 测试失败: {result.Message}");
                    }
                }
                catch (Exception ex)
                {
                    LogManager.Error($"体素网格 SDF 测试异常: {ex.Message}", ex);
                    System.Windows.MessageBox.Show(
                        $"体素网格 SDF 测试出现异常：\n{ex.Message}",
                        "错误",
                        System.Windows.MessageBoxButton.OK,
                        System.Windows.MessageBoxImage.Error);
                    UpdateMainStatus($"体素网格 SDF 测试异常: {ex.Message}");
                }
            }, "体素网格 SDF 测试");
        }

        /// <summary>
        /// 执行体素路径规划测试（3D A*）
        /// </summary>
        private async void ExecuteTestVoxelPathFinding()
        {
            await SafeExecuteAsync(async () =>
            {
                try
                {
                    UpdateMainStatus("正在执行体素路径规划测试...");
                    LogManager.Info("开始体素路径规划测试（3D A*）");

                    // 获取当前文档
                    var document = Autodesk.Navisworks.Api.Application.ActiveDocument;
                    if (document == null)
                    {
                        System.Windows.MessageBox.Show(
                            "未找到活动文档，请先打开一个 Navisworks 模型",
                            "体素路径规划测试",
                            System.Windows.MessageBoxButton.OK,
                            System.Windows.MessageBoxImage.Warning);
                        UpdateMainStatus("体素路径规划测试取消：无活动文档");
                        return;
                    }

                    // 使用系统配置的网格大小参数
                    double cellSizeMeters = ConfigManager.Instance.Current.PathEditing.CellSizeMeters;
                    LogManager.Info($"使用系统配置的体素大小: {cellSizeMeters}米");

                    // 根据可通行体素样本选择测试起点和终点
                    // 起点：体素(77, 41, 9) -> 世界(-116.35, 4.94, 50.16) - 模型中心、最高层
                    // 终点：体素(107, 11, 8) -> 世界(-67.13, -44.27, 48.52) - 偏右下、低一层
                    // 注意：VoxelToWorld返回的是体素左下角坐标，需要加上半个体素尺寸偏移到中心点
                    double voxelSizeInModelUnits = cellSizeMeters * UnitsConverter.GetMetersToUnitsConversionFactor(document.Units);
                    double halfVoxel = voxelSizeInModelUnits / 2.0;

                    // 起点：模型中心、最高层Z=9
                    var startPoint = new Autodesk.Navisworks.Api.Point3D(-200 + halfVoxel, -24.27 + halfVoxel, 42 + halfVoxel);
                    // 终点：偏右下、低一层Z=8
                    var endPoint = new Autodesk.Navisworks.Api.Point3D(-116.35 + halfVoxel, 0 + halfVoxel, 45 + halfVoxel);

                    LogManager.Info($"测试起点: ({startPoint.X:F2}, {startPoint.Y:F2}, {startPoint.Z:F2})");
                    LogManager.Info($"测试终点: ({endPoint.X:F2}, {endPoint.Y:F2}, {endPoint.Z:F2})");

                    // 创建并执行体素路径规划测试命令
                    var testCommand = new VoxelPathFindingTestCommand(
                        document,
                        cellSize: cellSizeMeters,      // 体素大小（米）
                        objectRadius: 0.6,            // 物体半径 0.6米
                        objectHeight: 1.8,            // 物体高度 1.8米
                        startPoint: startPoint,        // 起点
                        endPoint: endPoint             // 终点
                    );

                    var result = await testCommand.ExecuteAsync();

                    if (result.IsSuccess)
                    {
                        // 显示测试结果
                        System.Windows.MessageBox.Show(
                            $"体素路径规划测试成功！\n\n{result.Message}\n\n详细信息请查看日志和3D视图中的路径可视化。",
                            "体素路径规划测试结果",
                            System.Windows.MessageBoxButton.OK,
                            System.Windows.MessageBoxImage.Information);

                        UpdateMainStatus("体素路径规划测试完成");
                        LogManager.Info($"体素路径规划测试成功: {result.Message}");
                    }
                    else
                    {
                        System.Windows.MessageBox.Show(
                            $"体素路径规划测试失败：\n{result.Message}",
                            "体素路径规划测试",
                            System.Windows.MessageBoxButton.OK,
                            System.Windows.MessageBoxImage.Error);

                        UpdateMainStatus($"体素路径规划测试失败: {result.Message}");
                        LogManager.Error($"体素路径规划测试失败: {result.Message}");
                    }
                }
                catch (Exception ex)
                {
                    LogManager.Error($"体素路径规划测试异常: {ex.Message}", ex);
                    System.Windows.MessageBox.Show(
                        $"体素路径规划测试出现异常：\n{ex.Message}",
                        "错误",
                        System.Windows.MessageBoxButton.OK,
                        System.Windows.MessageBoxImage.Error);
                    UpdateMainStatus($"体素路径规划测试异常: {ex.Message}");
                }
            }, "体素路径规划测试");
        }

        /// <summary>
        /// 捕获选中的真实物体，显示原始变换信息并可视化三轴。
        /// </summary>
        private void ExecuteCaptureRealObjectTransform()
        {
            SafeExecute(() =>
            {
                var doc = Autodesk.Navisworks.Api.Application.ActiveDocument;
                if (doc == null || doc.IsClear)
                {
                    System.Windows.MessageBox.Show(
                        "没有活动的文档！请先打开一个模型。",
                        "错误",
                        System.Windows.MessageBoxButton.OK,
                        System.Windows.MessageBoxImage.Error);
                    return;
                }

                var selection = doc.CurrentSelection.SelectedItems;
                if (selection.Count == 0)
                {
                    ClearCapturedRealObjectTransformVisualization();
                    System.Windows.MessageBox.Show(
                        "请先选择一个真实物体！",
                        "提示",
                        System.Windows.MessageBoxButton.OK,
                        System.Windows.MessageBoxImage.Information);
                    return;
                }

                ModelItem item = selection[0];
                BoundingBox3D bounds = item.BoundingBox();
                Point3D boundsCenter = bounds.Center;
                TransformDiagnosticInfo selectedInfo = CreateTransformDiagnosticInfo(item, "选中节点");
                List<ModelItem> geometryDescendants = CollectGeometryDescendants(item);
                TransformDiagnosticInfo geometryInfo = geometryDescendants.Count > 0
                    ? CreateTransformDiagnosticInfo(geometryDescendants[0], "首个几何后代")
                    : null;
                FragmentOrientationAnalysis fragmentAnalysis = AnalyzeFragmentOrientations(item);

                Quaternion visualizationQuaternion = fragmentAnalysis != null && fragmentAnalysis.HasRepresentativeOrientation
                    ? fragmentAnalysis.RepresentativeRotation
                    : geometryInfo?.RotationQuaternion ?? selectedInfo.RotationQuaternion;

                double axisLength = GetTransformAxisVisualizationLength(bounds);
                RenderCapturedRealObjectTransformAxes(boundsCenter, visualizationQuaternion, axisLength);

                var info = new StringBuilder();
                info.AppendLine("=== 真实物体原始变换信息 ===");
                info.AppendLine();
                info.AppendLine($"对象: {item.DisplayName}");
                info.AppendLine($"ClassName: {item.ClassName}");
                info.AppendLine($"HasGeometry: {item.HasGeometry}");
                info.AppendLine();
                info.AppendLine("【包围盒】");
                info.AppendLine($"Min = ({bounds.Min.X:F3}, {bounds.Min.Y:F3}, {bounds.Min.Z:F3})");
                info.AppendLine($"Max = ({bounds.Max.X:F3}, {bounds.Max.Y:F3}, {bounds.Max.Z:F3})");
                info.AppendLine($"Center = ({boundsCenter.X:F3}, {boundsCenter.Y:F3}, {boundsCenter.Z:F3})");
                info.AppendLine();

                AppendTransformDiagnosticInfo(info, selectedInfo);

                info.AppendLine("【几何后代】");
                info.AppendLine($"几何后代数量 = {geometryDescendants.Count}");
                if (geometryInfo != null)
                {
                    AppendTransformDiagnosticInfo(info, geometryInfo);
                }
                else
                {
                    info.AppendLine("未找到 HasGeometry=True 的后代节点");
                    info.AppendLine();
                }

                AppendFragmentAnalysis(info, fragmentAnalysis);
                info.AppendLine();
                info.AppendLine("【可视化说明】");
                info.AppendLine($"三轴原点使用包围盒中心: ({boundsCenter.X:F3}, {boundsCenter.Y:F3}, {boundsCenter.Z:F3})");
                info.AppendLine($"轴长度 = {axisLength:F3}");
                info.AppendLine($"三轴方向来源 = {(fragmentAnalysis != null && fragmentAnalysis.HasRepresentativeOrientation ? "fragment代表姿态" : geometryInfo != null ? "首个几何后代Transform" : "选中节点Transform")}");
                info.AppendLine("红色=X轴，绿色=Y轴，蓝色=Z轴");

                string message = info.ToString();
                LogManager.Info("[真实物体原始位姿]\n" + message);

                var resultDialog = new NavisworksTransport.UI.WPF.Views.CoordinateSystemResultDialog
                {
                    Title = "真实物体原始变换信息",
                    ResultText = message
                };
                DialogHelper.SetOwnerSafely(resultDialog);
                resultDialog.ShowDialog();

                UpdateMainStatus($"已捕获真实物体原始位姿：{item.DisplayName}");
            }, "捕获真实物体原始位姿");
        }

        private void ClearCapturedRealObjectTransformVisualization()
        {
            var renderPlugin = PathPointRenderPlugin.Instance;
            if (renderPlugin == null)
            {
                return;
            }

            renderPlugin.ClearRailBaseline("system_transform_axis_x");
            renderPlugin.ClearRailBaseline("system_transform_axis_y");
            renderPlugin.ClearRailBaseline("system_transform_axis_z");
        }

        private void RenderCapturedRealObjectTransformAxes(Point3D origin, Quaternion rotationQuaternion, double axisLength)
        {
            var renderPlugin = PathPointRenderPlugin.Instance;
            if (renderPlugin == null)
            {
                return;
            }

            ClearCapturedRealObjectTransformVisualization();

            RenderTransformAxis(renderPlugin, "system_transform_axis_x", origin, Vector3.Transform(Vector3.UnitX, rotationQuaternion), axisLength, RenderStyleName.TransformAxisX);
            RenderTransformAxis(renderPlugin, "system_transform_axis_y", origin, Vector3.Transform(Vector3.UnitY, rotationQuaternion), axisLength, RenderStyleName.TransformAxisY);
            RenderTransformAxis(renderPlugin, "system_transform_axis_z", origin, Vector3.Transform(Vector3.UnitZ, rotationQuaternion), axisLength, RenderStyleName.TransformAxisZ);
        }

        private static void RenderTransformAxis(
            PathPointRenderPlugin renderPlugin,
            string pathId,
            Point3D origin,
            Vector3 direction,
            double axisLength,
            RenderStyleName renderStyleName)
        {
            if (direction.LengthSquared() < 1e-8f)
            {
                return;
            }

            Vector3 normalizedDirection = Vector3.Normalize(direction);
            Point3D endPoint = new Point3D(
                origin.X + normalizedDirection.X * (float)axisLength,
                origin.Y + normalizedDirection.Y * (float)axisLength,
                origin.Z + normalizedDirection.Z * (float)axisLength);

            renderPlugin.RenderRailBaseline(
                pathId,
                new System.Collections.Generic.List<Point3D> { origin, endPoint },
                renderStyleName);
        }

        private static double GetTransformAxisVisualizationLength(BoundingBox3D bounds)
        {
            double xSpan = bounds.Max.X - bounds.Min.X;
            double ySpan = bounds.Max.Y - bounds.Min.Y;
            double zSpan = bounds.Max.Z - bounds.Min.Z;
            double maxSpan = Math.Max(xSpan, Math.Max(ySpan, zSpan));
            double minLength = UnitsConverter.ConvertFromMeters(0.5);
            return Math.Max(minLength, maxSpan * 0.3);
        }

        private static Quaternion ToQuaternion(Rotation3D rotation)
        {
            var axisAngle = rotation.ToAxisAndAngle();
            if (axisAngle.Axis.IsZero || Math.Abs(axisAngle.Angle) < 1e-9)
            {
                return Quaternion.Identity;
            }

            return Quaternion.Normalize(Quaternion.CreateFromAxisAngle(
                new Vector3((float)axisAngle.Axis.X, (float)axisAngle.Axis.Y, (float)axisAngle.Axis.Z),
                (float)axisAngle.Angle));
        }

        private static TransformDiagnosticInfo CreateTransformDiagnosticInfo(ModelItem item, string label)
        {
            Transform3DComponents components = item.Transform.Factor();
            var axisAngle = components.Rotation.ToAxisAndAngle();
            Quaternion rotationQuaternion = ToQuaternion(components.Rotation);

            return new TransformDiagnosticInfo
            {
                Label = label,
                DisplayName = item.DisplayName,
                ClassName = item.ClassName,
                HasGeometry = item.HasGeometry,
                Translation = components.Translation,
                Scale = components.Scale,
                RotationAxis = axisAngle.Axis,
                RotationAngleRadians = axisAngle.Angle,
                RotationQuaternion = rotationQuaternion,
                HostXAxis = Vector3.Normalize(Vector3.Transform(Vector3.UnitX, rotationQuaternion)),
                HostYAxis = Vector3.Normalize(Vector3.Transform(Vector3.UnitY, rotationQuaternion)),
                HostZAxis = Vector3.Normalize(Vector3.Transform(Vector3.UnitZ, rotationQuaternion))
            };
        }

        private static void AppendTransformDiagnosticInfo(StringBuilder info, TransformDiagnosticInfo diagnostic)
        {
            info.AppendLine($"【{diagnostic.Label}】");
            info.AppendLine($"对象 = {diagnostic.DisplayName}");
            info.AppendLine($"ClassName = {diagnostic.ClassName}");
            info.AppendLine($"HasGeometry = {diagnostic.HasGeometry}");
            info.AppendLine($"Translation = ({diagnostic.Translation.X:F3}, {diagnostic.Translation.Y:F3}, {diagnostic.Translation.Z:F3})");
            info.AppendLine($"Scale = ({diagnostic.Scale.X:F3}, {diagnostic.Scale.Y:F3}, {diagnostic.Scale.Z:F3})");
            info.AppendLine($"Rotation.Axis = ({diagnostic.RotationAxis.X:F4}, {diagnostic.RotationAxis.Y:F4}, {diagnostic.RotationAxis.Z:F4})");
            info.AppendLine($"Rotation.Angle = {diagnostic.RotationAngleRadians:F6} rad ({diagnostic.RotationAngleRadians * 180.0 / Math.PI:F2}°)");
            info.AppendLine($"X轴 = ({diagnostic.HostXAxis.X:F4}, {diagnostic.HostXAxis.Y:F4}, {diagnostic.HostXAxis.Z:F4})");
            info.AppendLine($"Y轴 = ({diagnostic.HostYAxis.X:F4}, {diagnostic.HostYAxis.Y:F4}, {diagnostic.HostYAxis.Z:F4})");
            info.AppendLine($"Z轴 = ({diagnostic.HostZAxis.X:F4}, {diagnostic.HostZAxis.Y:F4}, {diagnostic.HostZAxis.Z:F4})");
            info.AppendLine();
        }

        private static List<ModelItem> CollectGeometryDescendants(ModelItem root)
        {
            var result = new List<ModelItem>();
            if (root == null)
            {
                return result;
            }

            CollectGeometryDescendantsRecursive(root, result);
            return result;
        }

        private static void CollectGeometryDescendantsRecursive(ModelItem item, List<ModelItem> result)
        {
            if (item == null)
            {
                return;
            }

            if (item.HasGeometry)
            {
                result.Add(item);
            }

            foreach (ModelItem child in item.Children)
            {
                CollectGeometryDescendantsRecursive(child, result);
            }
        }

        private static FragmentOrientationAnalysis AnalyzeFragmentOrientations(ModelItem item)
        {
            if (item == null)
            {
                return null;
            }

            Autodesk.Navisworks.Api.ModelItemCollection collection = new Autodesk.Navisworks.Api.ModelItemCollection { item };
            var comSelection = ComApiBridge.ToInwOpSelection(collection);
            List<FragmentInfo> fragments = null;
            try
            {
                fragments = GeometryHelper.GetAllFragments(comSelection);
                var validMatrices = fragments
                    .Where(f => f.TransformMatrix != null && f.TransformMatrix.Length == 16)
                    .Select(f => f.TransformMatrix)
                    .ToList();

                var analysis = new FragmentOrientationAnalysis
                {
                    FragmentCount = fragments.Count,
                    ValidTransformCount = validMatrices.Count,
                    ValidMatrices = validMatrices
                };

                if (validMatrices.Count == 0)
                {
                    return analysis;
                }

                Vector3 referenceX = NormalizeOrUnitX(GetMatrixAxis(validMatrices[0], 0));
                Vector3 referenceY = NormalizeOrUnitY(GetMatrixAxis(validMatrices[0], 1));
                Vector3 referenceZ = NormalizeOrUnitZ(GetMatrixAxis(validMatrices[0], 2));

                Vector3 sumX = referenceX;
                Vector3 sumY = referenceY;
                Vector3 sumZ = referenceZ;
                double xDotSum = 1.0;
                double yDotSum = 1.0;
                double zDotSum = 1.0;

                for (int i = 1; i < validMatrices.Count; i++)
                {
                    Vector3 axisX = NormalizeWithReference(GetMatrixAxis(validMatrices[i], 0), referenceX);
                    Vector3 axisY = NormalizeWithReference(GetMatrixAxis(validMatrices[i], 1), referenceY);
                    Vector3 axisZ = NormalizeWithReference(GetMatrixAxis(validMatrices[i], 2), referenceZ);

                    xDotSum += Math.Abs(Vector3.Dot(axisX, referenceX));
                    yDotSum += Math.Abs(Vector3.Dot(axisY, referenceY));
                    zDotSum += Math.Abs(Vector3.Dot(axisZ, referenceZ));

                    sumX += axisX;
                    sumY += axisY;
                    sumZ += axisZ;
                }

                Vector3 representativeX = NormalizeOrUnitX(sumX);
                Vector3 representativeY = sumY - Vector3.Dot(sumY, representativeX) * representativeX;
                representativeY = NormalizeOrUnitY(representativeY);
                Vector3 representativeZ = Vector3.Normalize(Vector3.Cross(representativeX, representativeY));
                if (Vector3.Dot(representativeZ, NormalizeOrUnitZ(sumZ)) < 0)
                {
                    representativeZ = -representativeZ;
                }
                representativeY = Vector3.Normalize(Vector3.Cross(representativeZ, representativeX));

                Matrix4x4 linear = new Matrix4x4(
                    representativeX.X, representativeY.X, representativeZ.X, 0f,
                    representativeX.Y, representativeY.Y, representativeZ.Y, 0f,
                    representativeX.Z, representativeY.Z, representativeZ.Z, 0f,
                    0f, 0f, 0f, 1f);

                analysis.HasRepresentativeOrientation = true;
                analysis.RepresentativeRotation = Quaternion.Normalize(Quaternion.CreateFromRotationMatrix(linear));
                analysis.RepresentativeXAxis = representativeX;
                analysis.RepresentativeYAxis = representativeY;
                analysis.RepresentativeZAxis = representativeZ;
                analysis.AverageXAxisConsistency = xDotSum / validMatrices.Count;
                analysis.AverageYAxisConsistency = yDotSum / validMatrices.Count;
                analysis.AverageZAxisConsistency = zDotSum / validMatrices.Count;
                analysis.SampleTranslation = GetMatrixTranslation(validMatrices[0]);
                return analysis;
            }
            finally
            {
                if (fragments != null)
                {
                    foreach (var fragment in fragments)
                    {
                        if (fragment?.Fragment != null)
                        {
                            try
                            {
                                Marshal.ReleaseComObject(fragment.Fragment);
                            }
                            catch
                            {
                            }
                        }
                    }
                }

                if (comSelection != null)
                {
                    try
                    {
                        Marshal.ReleaseComObject(comSelection);
                    }
                    catch
                    {
                    }
                }
            }
        }

        private static void AppendFragmentAnalysis(StringBuilder info, FragmentOrientationAnalysis analysis)
        {
            info.AppendLine("【Fragment 姿态分析】");
            if (analysis == null)
            {
                info.AppendLine("未能执行 fragment 分析");
                info.AppendLine();
                return;
            }

            info.AppendLine($"Fragment 总数 = {analysis.FragmentCount}");
            info.AppendLine($"有效变换矩阵数 = {analysis.ValidTransformCount}");
            if (!analysis.HasRepresentativeOrientation)
            {
                info.AppendLine("未得到可用的 fragment 代表姿态");
                info.AppendLine();
                return;
            }

            info.AppendLine($"示例平移 = ({analysis.SampleTranslation.X:F3}, {analysis.SampleTranslation.Y:F3}, {analysis.SampleTranslation.Z:F3})");
            info.AppendLine($"代表X轴 = ({analysis.RepresentativeXAxis.X:F4}, {analysis.RepresentativeXAxis.Y:F4}, {analysis.RepresentativeXAxis.Z:F4})");
            info.AppendLine($"代表Y轴 = ({analysis.RepresentativeYAxis.X:F4}, {analysis.RepresentativeYAxis.Y:F4}, {analysis.RepresentativeYAxis.Z:F4})");
            info.AppendLine($"代表Z轴 = ({analysis.RepresentativeZAxis.X:F4}, {analysis.RepresentativeZAxis.Y:F4}, {analysis.RepresentativeZAxis.Z:F4})");
            info.AppendLine($"X轴一致性 = {analysis.AverageXAxisConsistency:F4}");
            info.AppendLine($"Y轴一致性 = {analysis.AverageYAxisConsistency:F4}");
            info.AppendLine($"Z轴一致性 = {analysis.AverageZAxisConsistency:F4}");
            info.AppendLine();
        }

        private static Vector3 GetMatrixAxis(double[] matrix, int axisIndex)
        {
            switch (axisIndex)
            {
                case 0:
                    return new Vector3((float)matrix[0], (float)matrix[1], (float)matrix[2]);
                case 1:
                    return new Vector3((float)matrix[4], (float)matrix[5], (float)matrix[6]);
                case 2:
                    return new Vector3((float)matrix[8], (float)matrix[9], (float)matrix[10]);
                default:
                    throw new ArgumentOutOfRangeException(nameof(axisIndex));
            }
        }

        private static Vector3 GetMatrixTranslation(double[] matrix)
        {
            return new Vector3((float)matrix[12], (float)matrix[13], (float)matrix[14]);
        }

        private static Vector3 NormalizeWithReference(Vector3 axis, Vector3 reference)
        {
            Vector3 normalized = NormalizeOrFallback(axis, reference);
            return Vector3.Dot(normalized, reference) < 0 ? -normalized : normalized;
        }

        private static Vector3 NormalizeOrUnitX(Vector3 value)
        {
            return NormalizeOrFallback(value, Vector3.UnitX);
        }

        private static Vector3 NormalizeOrUnitY(Vector3 value)
        {
            return NormalizeOrFallback(value, Vector3.UnitY);
        }

        private static Vector3 NormalizeOrUnitZ(Vector3 value)
        {
            return NormalizeOrFallback(value, Vector3.UnitZ);
        }

        private static Vector3 NormalizeOrFallback(Vector3 value, Vector3 fallback)
        {
            return value.LengthSquared() < 1e-8f ? fallback : Vector3.Normalize(value);
        }

        private sealed class TransformDiagnosticInfo
        {
            public string Label { get; set; }
            public string DisplayName { get; set; }
            public string ClassName { get; set; }
            public bool HasGeometry { get; set; }
            public Vector3D Translation { get; set; }
            public Vector3D Scale { get; set; }
            public Vector3D RotationAxis { get; set; }
            public double RotationAngleRadians { get; set; }
            public Quaternion RotationQuaternion { get; set; }
            public Vector3 HostXAxis { get; set; }
            public Vector3 HostYAxis { get; set; }
            public Vector3 HostZAxis { get; set; }
        }

        private sealed class FragmentOrientationAnalysis
        {
            public int FragmentCount { get; set; }
            public int ValidTransformCount { get; set; }
            public List<double[]> ValidMatrices { get; set; }
            public bool HasRepresentativeOrientation { get; set; }
            public Quaternion RepresentativeRotation { get; set; }
            public Vector3 RepresentativeXAxis { get; set; }
            public Vector3 RepresentativeYAxis { get; set; }
            public Vector3 RepresentativeZAxis { get; set; }
            public double AverageXAxisConsistency { get; set; }
            public double AverageYAxisConsistency { get; set; }
            public double AverageZAxisConsistency { get; set; }
            public Vector3 SampleTranslation { get; set; }
        }

        /// <summary>
        /// 快速取面测试 — 激活 FaceInferToolPlugin，用户在模型上点击后显示面法向量
        /// </summary>
        private void ExecuteTestFaceInfer()
        {
            SafeExecute(() =>
            {
                var doc = Autodesk.Navisworks.Api.Application.ActiveDocument;
                if (doc == null || doc.IsClear)
                {
                    System.Windows.MessageBox.Show(
                        "没有活动的文档！请先打开一个模型。",
                        "错误",
                        System.Windows.MessageBoxButton.OK,
                        System.Windows.MessageBoxImage.Error);
                    return;
                }

                // 加载并激活 FaceInferToolPlugin
                var assemblyPath = FaceInferToolPlugin.AssemblyPath;
                Application.Plugins.AddPluginAssembly(assemblyPath);
                var record = (ToolPluginRecord)Application.Plugins.FindPlugin("FaceInferTool.NavisworksTransport");
                if (record == null)
                {
                    System.Windows.MessageBox.Show(
                        "无法找到 FaceInferTool 插件！",
                        "错误",
                        System.Windows.MessageBoxButton.OK,
                        System.Windows.MessageBoxImage.Error);
                    return;
                }
                var plugin = record.LoadPlugin();
                if (plugin == null)
                {
                    System.Windows.MessageBox.Show(
                        "FaceInferTool 插件加载失败！",
                        "错误",
                        System.Windows.MessageBoxButton.OK,
                        System.Windows.MessageBoxImage.Error);
                    return;
                }

                UpdateMainStatus("请在模型上点击一个面…");

                // 一次性事件处理器：取到面后自动取消订阅并恢复工具
                EventHandler<FaceInferResult> handler = null;
                handler = (sender, result) =>
                {
                    FaceInferToolPlugin.FaceInferred -= handler;

                    // 恢复为选择工具
                    try
                    {
                        Application.MainDocument.Tool.Value = Tool.Select;
                    }
                    catch { }

                    if (!result.IsValid)
                    {
                        UpdateMainStatus("面推断失败：未命中有效面");
                        return;
                    }

                    var info = new StringBuilder();
                    info.AppendLine("=== 面推断结果 ===");
                    info.AppendLine();
                    var namedParent = ModelItemAnalysisHelper.FindNamedParentContainer(result.ModelItem);
                    var displayName = ModelItemAnalysisHelper.GetSafeDisplayName(namedParent);
                    info.AppendLine($"构件: {displayName}");
                    info.AppendLine($"命中点: ({result.HitPoint.X:F3}, {result.HitPoint.Y:F3}, {result.HitPoint.Z:F3})");
                    info.AppendLine($"法向量: ({result.Normal.X:F6}, {result.Normal.Y:F6}, {result.Normal.Z:F6})");

                    string message = info.ToString();
                    LogManager.Info("[面推断测试]\n" + message);

                    System.Windows.Application.Current.Dispatcher.Invoke(() =>
                    {
                        var dialog = new NavisworksTransport.UI.WPF.Views.CoordinateSystemResultDialog
                        {
                            Title = "面推断结果",
                            ResultText = message
                        };
                        DialogHelper.SetOwnerSafely(dialog);
                        dialog.ShowDialog();
                    });

                    var statusName = ModelItemAnalysisHelper.GetSafeDisplayName(namedParent);
                    UpdateMainStatus($"面推断完成 — {statusName}");
                };

                FaceInferToolPlugin.FaceInferred += handler;

                Application.MainDocument.Tool.SetCustomToolPlugin(plugin);
            }, "面推断测试");
        }

        /// <summary>
        /// 读取选中对象的Transform信息，并测试旋转
        /// </summary>
        private void ExecuteReadTransformTest()
        {
            try
            {
                var doc = Autodesk.Navisworks.Api.Application.ActiveDocument;
                var selection = doc.CurrentSelection.SelectedItems;

                if (selection.Count == 0)
                {
                    System.Windows.MessageBox.Show("请先选择一个对象！", "提示", 
                        System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Information);
                    return;
                }

                var item = selection[0];
                var modelItems = new Autodesk.Navisworks.Api.ModelItemCollection { item };
                
                // === 读取初始状态 ===
                var transform1 = item.Transform;
                var components1 = transform1.Factor();
                var bbox1 = item.BoundingBox();
                var center1 = bbox1.Center;

                var info = $"=== 初始状态 ===\n";
                info += $"对象: {item.DisplayName}\n";
                info += $"包围盒中心: ({center1.X:F3}, {center1.Y:F3}, {center1.Z:F3})\n";
                info += $"Transform.Translation: ({components1.Translation.X:F3}, {components1.Translation.Y:F3}, {components1.Translation.Z:F3})\n";
                info += $"Transform.Rotation: {components1.Rotation}\n\n";

                // === 应用旋转override ===
                // 绕Z轴旋转45度（π/4弧度）
                double angle = Math.PI / 4;  // 45度
                var rotationTransform = new Autodesk.Navisworks.Api.Transform3D(
                    new Autodesk.Navisworks.Api.Rotation3D(
                        new Autodesk.Navisworks.Api.UnitVector3D(0, 0, 1), 
                        angle
                    )
                );
                
                // 应用override（false=增量模式）
                doc.Models.OverridePermanentTransform(modelItems, rotationTransform, false);
                
                info += $"=== 应用旋转后（绕Z轴45度）===\n";
                
                // === 重新读取状态 ===
                var transform2 = item.Transform;
                var components2 = transform2.Factor();
                var bbox2 = item.BoundingBox();
                var center2 = bbox2.Center;
                
                info += $"包围盒中心: ({center2.X:F3}, {center2.Y:F3}, {center2.Z:F3})\n";
                info += $"Transform.Translation: ({components2.Translation.X:F3}, {components2.Translation.Y:F3}, {components2.Translation.Z:F3})\n";
                info += $"Transform.Rotation: {components2.Rotation}\n\n";
                
                info += $"=== 对比 ===\n";
                info += $"包围盒中心变化: ({center2.X - center1.X:F3}, {center2.Y - center1.Y:F3}, {center2.Z - center1.Z:F3})\n";
                info += $"item.Transform是否变化: {!transform1.Equals(transform2)}\n";
                
                LogManager.Info(info);
                System.Windows.MessageBox.Show(info, "Transform测试", 
                    System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Information);
            }
            catch (Exception ex)
            {
                System.Windows.MessageBox.Show($"错误: {ex.Message}", "错误", 
                    System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error);
                LogManager.Error($"读取Transform失败: {ex.Message}\n{ex.StackTrace}");
            }
        }

        /// <summary>
        /// 执行坐标系检测命令
        /// </summary>
        private void ExecuteCoordinateSystemExplorer()
        {
            SafeExecute(() =>
            {
                try
                {
                    UpdateMainStatus("正在执行坐标系检测...");
                    LogManager.Info("开始坐标系检测");

                    var doc = Autodesk.Navisworks.Api.Application.ActiveDocument;
                    if (doc == null || doc.IsClear)
                    {
                        System.Windows.MessageBox.Show(
                            "没有活动的文档！请先打开一个模型。",
                            "错误",
                            System.Windows.MessageBoxButton.OK,
                            System.Windows.MessageBoxImage.Error);
                        UpdateMainStatus("坐标系检测失败：无活动文档");
                        return;
                    }

                    var sb = new StringBuilder();
                    sb.AppendLine("=== Navisworks 坐标系检测 ===\n");

                    // 1. Document 级别信息
                    sb.AppendLine("【1. Document 级别信息】");
                    sb.AppendLine($"文档名称: {doc.FileName}");
                    sb.AppendLine($"文档标题: {doc.Title}");
                    sb.AppendLine($"模型数量: {doc.Models.Count}");
                    sb.AppendLine();

                    // 2. Model 级别信息
                    sb.AppendLine("【2. Model 级别信息】");
                    int modelIndex = 0;
                    foreach (var model in doc.Models)
                    {
                        sb.AppendLine($"模型 [{modelIndex}]:");
                        
                        var rootItem = model.RootItem;
                        if (rootItem != null)
                        {
                            sb.AppendLine($"  - RootItem.DisplayName: {rootItem.DisplayName}");
                            
                            var components = rootItem.Transform.Factor();
                            sb.AppendLine($"  - Transform.Translation: ({components.Translation.X:F4}, {components.Translation.Y:F4}, {components.Translation.Z:F4})");
                            var rotation = components.Rotation;
                            // Rotation3D 使用 ToAxisAndAngle() 方法获取轴和角度
                            var axisAngle = rotation.ToAxisAndAngle();
                            sb.AppendLine($"  - Transform.Rotation.Axis: ({axisAngle.Axis.X:F4}, {axisAngle.Axis.Y:F4}, {axisAngle.Axis.Z:F4})");
                            sb.AppendLine($"  - Transform.Rotation.Angle: {axisAngle.Angle:F6} rad ({axisAngle.Angle * 180 / Math.PI:F2}°)");
                            sb.AppendLine($"  - Transform.Scale: ({components.Scale.X:F4}, {components.Scale.Y:F4}, {components.Scale.Z:F4})");
                            
                            var bbox = rootItem.BoundingBox();
                            sb.AppendLine($"  - 包围盒 Min: ({bbox.Min.X:F4}, {bbox.Min.Y:F4}, {bbox.Min.Z:F4})");
                            sb.AppendLine($"  - 包围盒 Max: ({bbox.Max.X:F4}, {bbox.Max.Y:F4}, {bbox.Max.Z:F4})");
                            
                            double xSpan = bbox.Max.X - bbox.Min.X;
                            double ySpan = bbox.Max.Y - bbox.Min.Y;
                            double zSpan = bbox.Max.Z - bbox.Min.Z;
                            sb.AppendLine($"  - 跨度: X={xSpan:F2}, Y={ySpan:F2}, Z={zSpan:F2}");
                            sb.AppendLine($"  - 坐标系推测: {(ySpan > zSpan * 2 ? "可能是 Y-Up" : "可能是 Z-Up")}");
                        }
                        sb.AppendLine();
                        modelIndex++;
                    }

                    // 3. Document 坐标系向量 (直接来自模型)
                    sb.AppendLine("【3. Document 坐标系向量 (模型原始)】");
                    var docUp = doc.UpVector;
                    var docRight = doc.RightVector;
                    var docFront = doc.FrontVector;
                    
                    if (docUp.IsZero)
                    {
                        sb.AppendLine("UpVector: (0, 0, 0) - 未定义");
                    }
                    else
                    {
                        sb.AppendLine($"UpVector: ({docUp.X:F4}, {docUp.Y:F4}, {docUp.Z:F4})");
                    }
                    
                    if (docRight.IsZero)
                    {
                        sb.AppendLine("RightVector: (0, 0, 0) - 未定义");
                    }
                    else
                    {
                        sb.AppendLine($"RightVector: ({docRight.X:F4}, {docRight.Y:F4}, {docRight.Z:F4})");
                    }
                    
                    if (docFront.IsZero)
                    {
                        sb.AppendLine("FrontVector: (0, 0, 0) - 未定义");
                    }
                    else
                    {
                        sb.AppendLine($"FrontVector: ({docFront.X:F4}, {docFront.Y:F4}, {docFront.Z:F4})");
                    }
                    sb.AppendLine();
                    
                    // 4. Viewpoint 信息 (Navisworks 处理后的)
                    sb.AppendLine("【4. Viewpoint 信息 (Navisworks 处理后)】");
                    var vp = doc.CurrentViewpoint.Value;
                    sb.AppendLine($"WorldUpVector: ({vp.WorldUpVector.X:F4}, {vp.WorldUpVector.Y:F4}, {vp.WorldUpVector.Z:F4})");
                    sb.AppendLine($"Position: ({vp.Position.X:F4}, {vp.Position.Y:F4}, {vp.Position.Z:F4})");
                    var vpRotation = vp.Rotation.ToAxisAndAngle();
                    sb.AppendLine($"Rotation.Axis: ({vpRotation.Axis.X:F4}, {vpRotation.Axis.Y:F4}, {vpRotation.Axis.Z:F4})");
                    sb.AppendLine($"Rotation.Angle: {vpRotation.Angle:F6} rad");
                    sb.AppendLine();

                    // 5. 坐标系推测总结
                    sb.AppendLine("【5. 坐标系推测总结】");
                    
                    // 方法1: 优先使用 Document.UpVector 判断（模型原始定义）
                    sb.AppendLine($"方法1 - Document.UpVector (原始):");
                    if (!docUp.IsZero)
                    {
                        sb.AppendLine($"  值: ({docUp.X:F4}, {docUp.Y:F4}, {docUp.Z:F4})");
                        
                        if (Math.Abs(docUp.Z) > 0.9)
                        {
                            sb.AppendLine($"  ✅ 判定: Z-Up 坐标系 (原始)");
                        }
                        else if (Math.Abs(docUp.Y) > 0.9)
                        {
                            sb.AppendLine($"  ✅ 判定: Y-Up 坐标系 (原始)");
                        }
                        else if (Math.Abs(docUp.X) > 0.9)
                        {
                            sb.AppendLine($"  ⚠️ 判定: X-Up 坐标系 (罕见)");
                        }
                    }
                    else
                    {
                        sb.AppendLine($"  未定义 (Zero)，需使用 Viewpoint.WorldUpVector");
                    }
                    sb.AppendLine();
                    
                    // 方法2: 使用 WorldUpVector 判断（Navisworks 处理后的，最可靠）
                    var worldUp = doc.CurrentViewpoint.Value.WorldUpVector;
                    sb.AppendLine($"方法2 - Viewpoint.WorldUpVector (推荐):");
                    sb.AppendLine($"  值: ({worldUp.X:F4}, {worldUp.Y:F4}, {worldUp.Z:F4})");
                    
                    string detectedCoordinateSystem = "Unknown";
                    if (Math.Abs(worldUp.Z) > 0.9)
                    {
                        sb.AppendLine($"  ✅ 判定: Z-Up 坐标系 (Z轴向上)");
                        sb.AppendLine($"  说明: 这是 Navisworks 默认坐标系，插件无需特殊配置");
                        detectedCoordinateSystem = "ZUp";
                    }
                    else if (Math.Abs(worldUp.Y) > 0.9)
                    {
                        sb.AppendLine($"  ✅ 判定: Y-Up 坐标系 (Y轴向上)");
                        sb.AppendLine($"  说明: 通常是 Revit 等软件导出的模型");
                        sb.AppendLine($"  建议: 在 default_config.toml 中设置坐标系为 YUp");
                        detectedCoordinateSystem = "YUp";
                    }
                    else if (Math.Abs(worldUp.X) > 0.9)
                    {
                        sb.AppendLine($"  ⚠️ 判定: X-Up 坐标系 (罕见)");
                        sb.AppendLine($"  说明: 非标准坐标系，需要手动适配");
                        detectedCoordinateSystem = "XUp";
                    }
                    else
                    {
                        sb.AppendLine($"  ❓ 判定: 无法确定（非标准向上向量）");
                    }
                    sb.AppendLine();
                    
                    // 方法3: 通过模型 Transform 旋转判断（辅助验证）
                    sb.AppendLine($"方法3 - 模型 Transform 旋转:");
                    if (doc.Models.Count > 0)
                    {
                        var rootItem = doc.Models[0].RootItem;
                        if (rootItem != null)
                        {
                            var components = rootItem.Transform.Factor();
                            var rotation = components.Rotation.ToAxisAndAngle();
                            double angleDegrees = rotation.Angle * 180 / Math.PI;
                            
                            sb.AppendLine($"  旋转轴: ({rotation.Axis.X:F4}, {rotation.Axis.Y:F4}, {rotation.Axis.Z:F4})");
                            sb.AppendLine($"  旋转角: {angleDegrees:F2}°");
                            
                            // 检查是否有 90° 或 270° 绕 X 轴旋转（Y-Up 模型的典型特征）
                            if (Math.Abs(rotation.Axis.X) > 0.9 && 
                                (Math.Abs(angleDegrees - 90) < 5 || Math.Abs(angleDegrees - 270) < 5))
                            {
                                sb.AppendLine($"  ✅ 发现 X 轴旋转 ~{angleDegrees:F0}°，这是 Y-Up 导入的典型特征");
                            }
                            else if (Math.Abs(angleDegrees) < 1)
                            {
                                sb.AppendLine($"  无显著旋转，符合 Z-Up 模型特征");
                            }
                        }
                    }
                    sb.AppendLine();
                    
                    // 方法4: 包围盒跨度分析（启发式）
                    sb.AppendLine($"方法4 - 包围盒跨度分析（启发式）:");
                    if (doc.Models.Count > 0)
                    {
                        var rootBounds = doc.Models[0].RootItem.BoundingBox();
                        double xSpan = rootBounds.Max.X - rootBounds.Min.X;
                        double ySpan = rootBounds.Max.Y - rootBounds.Min.Y;
                        double zSpan = rootBounds.Max.Z - rootBounds.Min.Z;
                        
                        sb.AppendLine($"  X 跨度: {xSpan:F2} 单位");
                        sb.AppendLine($"  Y 跨度: {ySpan:F2} 单位");
                        sb.AppendLine($"  Z 跨度: {zSpan:F2} 单位");
                        
                        // 注意：经过旋转后，Y-Up 模型在 Navisworks 中显示为 Z-Up
                        // 所以这里看到的是转换后的坐标
                        if (zSpan > ySpan * 1.5)
                        {
                            sb.AppendLine($"  Z 跨度大于 Y 跨度，显示为 Z-Up 方向");
                        }
                        else if (ySpan > zSpan * 1.5)
                        {
                            sb.AppendLine($"  Y 跨度大于 Z 跨度，可能未完全转换");
                        }
                    }
                    sb.AppendLine();

                    // 方法5: Fragment 矩阵分析（选一个水平物体后更精确）
                    sb.AppendLine($"方法5 - Fragment 矩阵分析 (选择物体后启用):");
                    var selection = doc.CurrentSelection.SelectedItems;
                    if (selection.Count > 0)
                    {
                        ModelItem selectedItem = selection[0];
                        FragmentOrientationAnalysis fragAnalysis = AnalyzeFragmentOrientations(selectedItem);
                        if (fragAnalysis != null && fragAnalysis.HasRepresentativeOrientation)
                        {
                            string hostUpAxis = FragmentDefaultUpContext.GetCurrentHostUpAxis(doc);
                            if (RealObjectReferencePoseResolver.TryDetectDefaultUpAxis(
                                    fragAnalysis.ValidMatrices,
                                    hostUpAxis,
                                    out string fragDetectedAxis,
                                    out float yAlignment,
                                    out float zAlignment))
                            {
                                sb.AppendLine($"  对象: {selectedItem.DisplayName}");
                                sb.AppendLine($"  Fragment Y 对齐度: {yAlignment:F4}");
                                sb.AppendLine($"  Fragment Z 对齐度: {zAlignment:F4}");
                                sb.AppendLine($"  判定: Fragment 默认 Up = {fragDetectedAxis} ({(zAlignment > yAlignment ? "Z更贴近" : "Y更贴近")}向上轴)");
                            }
                            else
                            {
                                sb.AppendLine($"  未能从 fragment 姿态中检测默认Up。");
                            }
                        }
                        else
                        {
                            sb.AppendLine($"  选中物体 ({selectedItem.DisplayName}) 无有效 fragment 姿态。");
                        }
                    }
                    else
                    {
                        sb.AppendLine($"  (未选择对象，跳过此方法。请先选中一个水平放置的物体)");
                    }
                    sb.AppendLine();

                    // 最终建议
                    sb.AppendLine($"【最终建议】");
                    if (detectedCoordinateSystem == "YUp")
                    {
                        sb.AppendLine($"⚠️ 检测到 Y-Up 坐标系！");
                        sb.AppendLine($"当前插件使用 Z-Up 假设，在此模型上可能出现问题。");
                        sb.AppendLine($"建议：实施坐标系动态适配功能。");
                    }
                    else if (detectedCoordinateSystem == "ZUp")
                    {
                        sb.AppendLine($"✅ 标准 Z-Up 坐标系，插件应正常工作。");
                    }

                    // 显示和记录结果
                    string result = sb.ToString();
                    LogManager.Info(result);
                    
                    // 使用可复制的对话框显示结果
                    var resultDialog = new NavisworksTransport.UI.WPF.Views.CoordinateSystemResultDialog
                    {
                        Title = "坐标系检测结果",
                        ResultText = result
                    };
                    
                    // 设置对话框所有者并显示
                    DialogHelper.SetOwnerSafely(resultDialog);
                    resultDialog.ShowDialog();

                    UpdateMainStatus("坐标系检测完成");
                    LogManager.Info("坐标系检测成功完成");
                }
                catch (Exception ex)
                {
                    LogManager.Error($"坐标系检测异常: {ex.Message}", ex);
                    System.Windows.MessageBox.Show(
                        $"坐标系检测出现异常：\n{ex.Message}",
                        "错误",
                        System.Windows.MessageBoxButton.OK,
                        System.Windows.MessageBoxImage.Error);
                    UpdateMainStatus($"坐标系检测异常: {ex.Message}");
                }
            }, "坐标系检测");
        }

        #endregion

        #region 辅助方法

        /// <summary>
        /// 安全执行异步操作
        /// </summary>
        private async Task SafeExecuteAsync(Func<Task> action, string operationName = "未知操作")
        {
            try
            {
                await action();
            }
            catch (Exception ex)
            {
                LogManager.Error($"{operationName}发生异常: {ex.Message}", ex);
                UpdateMainStatus($"{operationName}失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 安全执行同步操作
        /// </summary>
        private void SafeExecute(Action action, string operationName = "未知操作")
        {
            try
            {
                action();
            }
            catch (Exception ex)
            {
                LogManager.Error($"{operationName}发生异常: {ex.Message}", ex);
                UpdateMainStatus($"{operationName}失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 验证ViewModel状态是否正常
        /// </summary>
        public bool IsValidState()
        {
            return _uiStateManager != null && LogLevels != null;
        }

        /// <summary>
        /// 获取ViewModel状态信息
        /// </summary>
        public string GetStateInfo()
        {
            return $"UIStateManager: {(_uiStateManager != null ? "已初始化" : "未初始化")}, " +
                   $"日志级别数量: {LogLevels?.Count ?? 0}";
        }

        #endregion

        #region 清理资源和IDisposable实现

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

        /// <summary>
        /// 释放资源的具体实现
        /// </summary>
        /// <param name="disposing">是否正在释放托管资源</param>
        protected virtual void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                if (disposing)
                {
                    try
                    {
                        // 调用现有的清理逻辑
                        Cleanup();
                        LogManager.Info("SystemManagementViewModel已正确释放资源 (IDisposable)");
                    }
                    catch (Exception ex)
                    {
                        LogManager.Error($"SystemManagementViewModel释放资源时发生异常: {ex.Message}", ex);
                    }
                }
                _disposed = true;
            }
        }

        /// <summary>
        /// 启动系统信息定时刷新
        /// </summary>
        private void StartSystemInfoTimer()
        {
            try
            {
                if (_systemInfoTimer == null)
                {
                    _systemInfoTimer = new DispatcherTimer
                    {
                        Interval = TimeSpan.FromSeconds(5) // 每5秒刷新一次
                    };
                    _systemInfoTimer.Tick += (s, e) => RefreshSystemInfo();
                }
                
                _systemInfoTimer.Start();
                LogManager.Debug("系统信息定时器已启动 (5秒间隔)");
            }
            catch (Exception ex)
            {
                LogManager.Error($"启动系统信息定时器失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 停止系统信息定时刷新
        /// </summary>
        private void StopSystemInfoTimer()
        {
            try
            {
                if (_systemInfoTimer != null)
                {
                    _systemInfoTimer.Stop();
                    _systemInfoTimer.Tick -= (s, e) => { };
                    _systemInfoTimer = null;
                }
            }
            catch (Exception ex)
            {
                LogManager.Warning($"停止系统信息定时器时出现警告: {ex.Message}");
            }
        }

        /// <summary>
        /// 刷新系统信息 (内存、运行时间)
        /// </summary>
        private void RefreshSystemInfo()
        {
            try
            {
                // 使用 VersionInfo 获取最新的内存和运行时间
                MemoryUsage = VersionInfo.GetMemoryUsage();
                RunningTime = VersionInfo.GetRunningTime();
            }
            catch (Exception ex)
            {
                LogManager.Debug($"刷新系统信息时出错: {ex.Message}");
            }
        }

        public void Cleanup()
        {
            try
            {
                LogManager.Info("开始清理SystemManagementViewModel资源");
                
                // 取消订阅文档相关事件
                UnsubscribeFromDocumentEvents();
                
                // 停止性能监控Idle任务，替代DispatcherTimer清理
                try
                {
                    IdleEventManager.Instance.UnregisterTask("SystemManagement_PerformanceMonitor");
                    LogManager.Info("SystemManagementViewModel性能监控Idle任务已停止");
                }
                catch (Exception ex)
                {
                    LogManager.Warning($"停止性能监控Idle任务时出现警告: {ex.Message}");
                }
                
                // 清理可能的一次性任务
                try
                {
                    IdleEventManager.Instance.UnregisterTask("SystemManagement_CheckUpdate");
                    IdleEventManager.Instance.UnregisterTask("SystemManagement_GenerateReport");
                    LogManager.Debug("SystemManagementViewModel一次性Idle任务已清理");
                }
                catch (Exception ex)
                {
                    LogManager.Debug($"清理一次性Idle任务时出现提示: {ex.Message}");
                }
                
                // 停止系统信息定时器
                try
                {
                    StopSystemInfoTimer();
                    LogManager.Debug("SystemManagementViewModel系统信息定时器已停止");
                }
                catch (Exception ex)
                {
                    LogManager.Debug($"停止系统信息定时器时出现提示: {ex.Message}");
                }
                
                LogManager.Info("SystemManagementViewModel资源清理完成");
            }
            catch (Exception ex)
            {
                LogManager.Error($"SystemManagementViewModel清理失败: {ex.Message}");
            }
        }

        #endregion
    }
}
