using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows.Input;
using Autodesk.Navisworks.Api;
using NavisworksTransport.Utils;
using NavisworksTransport.Commands;
using NavisworksTransport.Core;
using NavisworksTransport.Core.Animation;
using System.IO;
using System.Text;
using Microsoft.Win32;
using System.Threading.Tasks;
using System.Windows.Media.Imaging;
using NavisworksTransport.UI.WPF.Views;
using ImageFormat = System.Drawing.Imaging.ImageFormat;

namespace NavisworksTransport.UI.WPF.ViewModels
{
    /// <summary>
    /// 碰撞报告显示状态枚举
    /// </summary>
    public enum CollisionReportStatus
    {
        /// <summary>正在生成报告</summary>
        Generating,
        /// <summary>报告已生成</summary>
        Generated,
        /// <summary>生成失败</summary>
        Failed,
        /// <summary>空报告</summary>
        Empty
    }

    /// <summary>
    /// 碰撞报告项目UI模型
    /// </summary>
    public class CollisionReportItem
    {
        public int Index { get; set; }
        public string Title { get; set; }
        public string Description { get; set; }
        public string StatusText { get; set; }
        public string StatusColor { get; set; }
        public string Details { get; set; }
        public string Item1FullPath { get; set; }
        public string Item2FullPath { get; set; }
        public CollisionResult CollisionData { get; set; }
    }

    /// <summary>
    /// 碰撞报告统计信息UI模型
    /// </summary>
    public class CollisionReportStatistics
    {
        public int TotalCollisions { get; set; }
        public int AnimationCollisions { get; set; }
        public int NewCollisions { get; set; }
        public int ActiveCollisions { get; set; }
        public int ReviewedCollisions { get; set; }
        public int ApprovedCollisions { get; set; }
        public int ResolvedCollisions { get; set; }
        public string GenerationTime { get; set; }
        public string ReportType { get; set; }
    }

    /// <summary>
    /// 碰撞报告对话框ViewModel
    /// </summary>
    public class CollisionReportViewModel : ViewModelBase
    {
        #region 私有字段

        private CollisionReportStatus _reportStatus;
        private string _reportTitle;
        private CollisionReportStatistics _statistics;
        private ObservableCollection<CollisionReportItem> _animationCollisions;
        private string _progressMessage;
        private int _progressPercentage;
        private bool _isGenerating;
        private bool _hasCollisions;
        private string _summaryMessage;
        private string _recommendationMessage;
        private string _movingObjectInfo;
        private ObservableCollection<string> _collidedObjectsList;
        private int _uniqueCollidedObjectsCount;
        private string _pathName;
        private int _frameRate;
        private double _duration;
        private double _detectionTolerance;
        private string _testName;
        private DateTime? _testTime;
        private CollisionReportResult _currentReport;
        private ObservableCollection<ExcludedObjectRecord> _excludedObjects;
        
        // 保存运动物体原始状态，用于碰撞查看后恢复
        private ModelItemTransformHelper.ObjectStateSnapshot _savedAnimatedObjectState;
        private ModelItem _currentAnimatedObject;

        #endregion

        #region 公共属性

        /// <summary>
        /// 报告状态
        /// </summary>
        public CollisionReportStatus ReportStatus
        {
            get => _reportStatus;
            set => SetProperty(ref _reportStatus, value);
        }

        /// <summary>
        /// 报告标题
        /// </summary>
        public string ReportTitle
        {
            get => _reportTitle;
            set => SetProperty(ref _reportTitle, value);
        }

        /// <summary>
        /// 统计信息
        /// </summary>
        public CollisionReportStatistics Statistics
        {
            get => _statistics;
            set => SetProperty(ref _statistics, value);
        }

        /// <summary>
        /// 动画过程碰撞列表
        /// </summary>
        public ObservableCollection<CollisionReportItem> AnimationCollisions
        {
            get => _animationCollisions;
            set => SetProperty(ref _animationCollisions, value);
        }


        /// <summary>
        /// 进度消息
        /// </summary>
        public string ProgressMessage
        {
            get => _progressMessage;
            set => SetProperty(ref _progressMessage, value);
        }

        /// <summary>
        /// 进度百分比
        /// </summary>
        public int ProgressPercentage
        {
            get => _progressPercentage;
            set => SetProperty(ref _progressPercentage, value);
        }

        /// <summary>
        /// 是否正在生成报告
        /// </summary>
        public bool IsGenerating
        {
            get => _isGenerating;
            set
            {
                if (SetProperty(ref _isGenerating, value))
                {
                    // 刷新命令状态
                    System.Windows.Input.CommandManager.InvalidateRequerySuggested();
                }
            }
        }

        /// <summary>
        /// 是否有碰撞
        /// </summary>
        public bool HasCollisions
        {
            get => _hasCollisions;
            set
            {
                if (SetProperty(ref _hasCollisions, value))
                {
                    // 刷新命令状态
                    System.Windows.Input.CommandManager.InvalidateRequerySuggested();
                }
            }
        }

        /// <summary>
        /// 总结消息
        /// </summary>
        public string SummaryMessage
        {
            get => _summaryMessage;
            set => SetProperty(ref _summaryMessage, value);
        }

        /// <summary>
        /// 建议消息
        /// </summary>
        public string RecommendationMessage
        {
            get => _recommendationMessage;
            set => SetProperty(ref _recommendationMessage, value);
        }

        /// <summary>
        /// 运动构件信息
        /// </summary>
        public string MovingObjectInfo
        {
            get => _movingObjectInfo;
            set => SetProperty(ref _movingObjectInfo, value);
        }

        /// <summary>
        /// 被撞物体清单
        /// </summary>
        public ObservableCollection<string> CollidedObjectsList
        {
            get => _collidedObjectsList;
            set => SetProperty(ref _collidedObjectsList, value);
        }

        /// <summary>
        /// 去重后的被撞物体总数
        /// </summary>
        public int UniqueCollidedObjectsCount
        {
            get => _uniqueCollidedObjectsCount;
            set => SetProperty(ref _uniqueCollidedObjectsCount, value);
        }

        /// <summary>
        /// 路径名称
        /// </summary>
        public string PathName
        {
            get => _pathName;
            set => SetProperty(ref _pathName, value);
        }

        /// <summary>
        /// 测试名称（来自检测记录）
        /// </summary>
        public string TestName
        {
            get => _testName;
            set => SetProperty(ref _testName, value);
        }

        /// <summary>
        /// 测试时间（来自检测记录）
        /// </summary>
        public DateTime? TestTime
        {
            get => _testTime;
            set => SetProperty(ref _testTime, value);
        }

        /// <summary>
        /// 测试时间显示字符串
        /// </summary>
        public string TestTimeDisplay => _testTime?.ToString("yyyy-MM-dd HH:mm:ss") ?? "未知时间";

        /// <summary>
        /// 动画帧率
        /// </summary>
        public int FrameRate
        {
            get => _frameRate;
            set => SetProperty(ref _frameRate, value);
        }

        /// <summary>
        /// 动画时长
        /// </summary>
        public double Duration
        {
            get => _duration;
            set => SetProperty(ref _duration, value);
        }

        /// <summary>
        /// 检测容差
        /// </summary>
        public double DetectionTolerance
        {
            get => _detectionTolerance;
            set => SetProperty(ref _detectionTolerance, value);
        }

        /// <summary>
        /// 当前报告结果
        /// </summary>
        public CollisionReportResult CurrentReport
        {
            get => _currentReport;
            set => SetProperty(ref _currentReport, value);
        }

        /// <summary>
        /// 截图预览图像源（兼容旧版本，返回当前选中的截图）
        /// </summary>
        public BitmapImage ScreenshotPreviewSource => GetScreenshotBitmap(SelectedScreenshot);

        /// <summary>
        /// 截图列表
        /// </summary>
        private ObservableCollection<CollisionReportScreenshot> _screenshots = new ObservableCollection<CollisionReportScreenshot>();
        public ObservableCollection<CollisionReportScreenshot> Screenshots
        {
            get => _screenshots;
            set
            {
                if (SetProperty(ref _screenshots, value))
                {
                    OnPropertyChanged(nameof(HasScreenshots));
                    OnPropertyChanged(nameof(ScreenshotPreviewSource));
                }
            }
        }

        /// <summary>
        /// 当前选中的截图
        /// </summary>
        private CollisionReportScreenshot _selectedScreenshot;
        public CollisionReportScreenshot SelectedScreenshot
        {
            get => _selectedScreenshot;
            set
            {
                if (SetProperty(ref _selectedScreenshot, value))
                {
                    OnPropertyChanged(nameof(ScreenshotPreviewSource));
                }
            }
        }

        /// <summary>
        /// 是否有截图
        /// </summary>
        public bool HasScreenshots => Screenshots?.Count > 0;

        /// <summary>
        /// 截图数量
        /// </summary>
        public int ScreenshotCount => Screenshots?.Count ?? 0;

        /// <summary>
        /// 排除对象列表
        /// </summary>
        public ObservableCollection<ExcludedObjectRecord> ExcludedObjects
        {
            get => _excludedObjects;
            set
            {
                if (SetProperty(ref _excludedObjects, value))
                {
                    OnPropertyChanged(nameof(HasExcludedObjects));
                    OnPropertyChanged(nameof(ExcludedObjectsCount));
                }
            }
        }

        /// <summary>
        /// 是否有排除对象
        /// </summary>
        public bool HasExcludedObjects => ExcludedObjects?.Count > 0;

        /// <summary>
        /// 排除对象数量
        /// </summary>
        public int ExcludedObjectsCount => ExcludedObjects?.Count ?? 0;

        /// <summary>
        /// 获取截图的BitmapImage
        /// </summary>
        private BitmapImage GetScreenshotBitmap(CollisionReportScreenshot screenshot)
        {
            if (screenshot == null || string.IsNullOrEmpty(screenshot.FilePath) || !File.Exists(screenshot.FilePath))
            {
                return null;
            }

            try
            {
                var bitmap = new BitmapImage();
                bitmap.BeginInit();
                bitmap.CacheOption = BitmapCacheOption.OnLoad;
                bitmap.UriSource = new Uri(screenshot.FilePath);
                bitmap.EndInit();
                bitmap.Freeze();
                return bitmap;
            }
            catch (Exception ex)
            {
                LogManager.Error($"加载截图预览失败: {ex.Message}");
                return null;
            }
        }

        #endregion

        #region 命令属性

        /// <summary>
        /// 导出报告命令
        /// </summary>
        public ICommand ExportReportCommand { get; }

        /// <summary>
        /// 关闭窗口命令
        /// </summary>
        public ICommand CloseCommand { get; }

        /// <summary>
        /// 添加截图命令
        /// </summary>
        public ICommand AddScreenshotCommand { get; }

        /// <summary>
        /// 删除截图命令
        /// </summary>
        public ICommand DeleteScreenshotCommand { get; }

        /// <summary>
        /// 选择截图命令
        /// </summary>
        public ICommand SelectScreenshotCommand { get; }

        /// <summary>
        /// 截图设置命令
        /// </summary>
        public ICommand ScreenshotSettingsCommand { get; }

        /// <summary>
        /// 高亮碰撞对象命令
        /// </summary>
        public ICommand HighlightCollisionCommand { get; }

        #endregion

        #region 截图设置属性

        // 默认截图设置（0表示未初始化，将在构造函数中设置为当前视窗尺寸）
        private int _screenshotWidth = 0;
        private int _screenshotHeight = 0;
        private ImageFormat _screenshotFormat = ImageFormat.Png;

        /// <summary>
        /// 截图宽度
        /// </summary>
        public int ScreenshotWidthSetting
        {
            get => _screenshotWidth;
            set => SetProperty(ref _screenshotWidth, value);
        }

        /// <summary>
        /// 截图高度
        /// </summary>
        public int ScreenshotHeightSetting
        {
            get => _screenshotHeight;
            set => SetProperty(ref _screenshotHeight, value);
        }

        /// <summary>
        /// 截图格式
        /// </summary>
        public ImageFormat ScreenshotFormatSetting
        {
            get => _screenshotFormat;
            set => SetProperty(ref _screenshotFormat, value);
        }

        #endregion

        #region 构造函数

        public CollisionReportViewModel()
        {
            // 初始化集合
            AnimationCollisions = new ObservableCollection<CollisionReportItem>();
            CollidedObjectsList = new ObservableCollection<string>();
            ExcludedObjects = new ObservableCollection<ExcludedObjectRecord>();

            Statistics = new CollisionReportStatistics();

            // 初始化命令
            ExportReportCommand = new RelayCommand(async () => await ExportReportAsync(), () => !IsGenerating);
            CloseCommand = new RelayCommand(CloseWindow);
            HighlightCollisionCommand = new RelayCommand<CollisionReportItem>(HighlightCollision, item => item?.CollisionData != null);
            AddScreenshotCommand = new RelayCommand(ExecuteAddScreenshot, CanExecuteAddScreenshot);
            DeleteScreenshotCommand = new RelayCommand<CollisionReportScreenshot>(ExecuteDeleteScreenshot, s => s != null);
            SelectScreenshotCommand = new RelayCommand<CollisionReportScreenshot>(ExecuteSelectScreenshot);
            ScreenshotSettingsCommand = new RelayCommand(ExecuteScreenshotSettings);

            // 初始化状态
            ReportStatus = CollisionReportStatus.Generating;
            ReportTitle = "NavisworksTransport - 碰撞检测报告";
            IsGenerating = false;
            HasCollisions = false;
        }
        
        /// <summary>
        /// 初始化截图设置为当前视窗尺寸
        /// </summary>
        private void InitializeScreenshotSettings()
        {
            var generator = new Core.NavigationMapGenerator();
            var viewportSize = generator.GetCurrentViewportSize();
            
            _screenshotWidth = viewportSize.Width;
            _screenshotHeight = viewportSize.Height;
            LogManager.Info($"截图设置已初始化为当前视窗尺寸: {_screenshotWidth}x{_screenshotHeight}");
        }

        #endregion

        #region 公共方法

        /// <summary>
        /// 初始化报告数据
        /// </summary>
        /// <param name="reportResult">报告结果</param>
        public void InitializeReport(CollisionReportResult reportResult)
        {
            if (reportResult == null)
            {
                SetEmptyReport();
                return;
            }

            // 保存当前报告结果
            CurrentReport = reportResult;
            
            // 初始化截图设置（此时文档已准备好）
            if (ScreenshotWidthSetting == 0 || ScreenshotHeightSetting == 0)
            {
                InitializeScreenshotSettings();
            }

            try
            {
                IsGenerating = true;
                ReportStatus = CollisionReportStatus.Generating;
                ProgressMessage = "正在解析报告数据...";
                ProgressPercentage = 0;

                // 清空现有数据
                AnimationCollisions.Clear();
                CollidedObjectsList.Clear();
                Screenshots.Clear();
                ExcludedObjects.Clear();

                // 加载截图列表
                if (reportResult.Screenshots?.Count > 0)
                {
                    foreach (var screenshot in reportResult.Screenshots.OrderBy(s => s.SortOrder))
                    {
                        Screenshots.Add(screenshot);
                    }
                    // 默认选中第一张
                    SelectedScreenshot = Screenshots.FirstOrDefault();
                    LogManager.Info($"碰撞报告加载了 {Screenshots.Count} 张截图");
                }

                // 设置运动构件信息
                MovingObjectInfo = reportResult.MovingObjectInfo;

                // 设置被撞物体清单和计数
                UniqueCollidedObjectsCount = reportResult.UniqueCollidedObjectsCount;
                if (reportResult.CollidedObjectsList != null)
                {
                    foreach (var objName in reportResult.CollidedObjectsList)
                    {
                        CollidedObjectsList.Add(objName);
                    }
                }

                // 加载排除对象列表
                if (reportResult.ExcludedObjects?.Count > 0)
                {
                    foreach (var excludedObj in reportResult.ExcludedObjects)
                    {
                        ExcludedObjects.Add(excludedObj);
                    }
                    LogManager.Info($"碰撞报告加载了 {ExcludedObjects.Count} 个排除对象");
                }

                // 设置动画参数
                PathName = reportResult.PathName;
                FrameRate = reportResult.FrameRate;
                Duration = reportResult.Duration;
                DetectionTolerance = reportResult.DetectionTolerance;

                // 🔥 从数据库查询测试名称和时间
                LoadTestInfoFromDatabase(reportResult.ResultId);

                // 更新统计信息
                UpdateStatistics(reportResult);

                // 分类并添加碰撞项
                ProcessCollisionData(reportResult.AllCollisions);

                // 生成总结和建议
                GenerateSummaryAndRecommendations(reportResult);

                // 更新状态
                HasCollisions = reportResult.TotalCollisions > 0;
                ReportStatus = HasCollisions ? CollisionReportStatus.Generated : CollisionReportStatus.Empty;
                
                ProgressMessage = "报告生成完成";
                ProgressPercentage = 100;

                LogManager.Info($"碰撞报告ViewModel初始化完成，发现 {reportResult.TotalCollisions} 个碰撞");
            }
            catch (Exception ex)
            {
                LogManager.Error($"初始化碰撞报告失败: {ex.Message}");
                SetFailedReport(ex.Message);
            }
            finally
            {
                IsGenerating = false;
            }
        }

        /// <summary>
        /// 更新进度
        /// </summary>
        /// <param name="percentage">进度百分比</param>
        /// <param name="message">进度消息</param>
        public void UpdateProgress(int percentage, string message)
        {
            SafeExecute(() =>
            {
                ProgressPercentage = Math.Max(0, Math.Min(100, percentage));
                ProgressMessage = message ?? "";
            }, "更新报告生成进度", true);
        }

        #endregion

        #region 私有方法

        /// <summary>
        /// 从数据库加载测试信息（测试名称和时间）
        /// </summary>
        private void LoadTestInfoFromDatabase(int resultId)
        {
            try
            {
                if (resultId <= 0)
                {
                    LogManager.Debug("[LoadTestInfoFromDatabase] ResultId无效，跳过查询");
                    return;
                }

                var pathDatabase = PathPlanningManager.Instance?.GetPathDatabase();
                if (pathDatabase == null)
                {
                    LogManager.Warning("[LoadTestInfoFromDatabase] PathDatabase不可用");
                    return;
                }

                // 使用ResultId查询检测记录
                var record = pathDatabase.GetDetectionResultById(resultId);
                if (record != null)
                {
                    TestName = record.TestName ?? "未命名测试";
                    TestTime = record.TestTime;
                    LogManager.Info($"[LoadTestInfoFromDatabase] 加载测试信息: Name={TestName}, Time={TestTimeDisplay}");
                }
                else
                {
                    LogManager.Warning($"[LoadTestInfoFromDatabase] 未找到检测记录: ResultId={resultId}");
                    TestName = "未知测试";
                    TestTime = null;
                }
            }
            catch (Exception ex)
            {
                LogManager.Error($"[LoadTestInfoFromDatabase] 加载测试信息失败: {ex.Message}");
                TestName = "未知测试";
                TestTime = null;
            }
        }

        /// <summary>
        /// 更新统计信息
        /// </summary>
        private void UpdateStatistics(CollisionReportResult reportResult)
        {
            Statistics = new CollisionReportStatistics
            {
                TotalCollisions = reportResult.TotalCollisions,
                AnimationCollisions = reportResult.AnimationCollisions,
                GenerationTime = $"{reportResult.GenerationTimeMs}ms",
                ReportType = "综合碰撞报告"
            };

            // 计算状态统计
            if (reportResult.AllCollisions?.Count > 0)
            {
                Statistics.NewCollisions = reportResult.AllCollisions.Count(c => c.Status == Autodesk.Navisworks.Api.Clash.ClashResultStatus.New);
                Statistics.ActiveCollisions = reportResult.AllCollisions.Count(c => c.Status == Autodesk.Navisworks.Api.Clash.ClashResultStatus.Active);
                Statistics.ReviewedCollisions = reportResult.AllCollisions.Count(c => c.Status == Autodesk.Navisworks.Api.Clash.ClashResultStatus.Reviewed);
                Statistics.ApprovedCollisions = reportResult.AllCollisions.Count(c => c.Status == Autodesk.Navisworks.Api.Clash.ClashResultStatus.Approved);
                Statistics.ResolvedCollisions = reportResult.AllCollisions.Count(c => c.Status == Autodesk.Navisworks.Api.Clash.ClashResultStatus.Resolved);
            }
        }

        /// <summary>
        /// 处理碰撞数据
        /// </summary>
        private void ProcessCollisionData(List<CollisionResult> collisions)
        {
            if (collisions == null || collisions.Count == 0)
                return;

            var collisionItems = new List<CollisionReportItem>();
            int index = 1;

            foreach (var collision in collisions)
            {
                var item = CreateCollisionReportItem(collision, index++);
                collisionItems.Add(item);
            }

            // 更新UI集合（按序号排序保持顺序）
            SafeExecute(() =>
            {
                foreach (var item in collisionItems.OrderBy(i => i.Index))
                    AnimationCollisions.Add(item);

            }, "更新碰撞报告项目列表", true);
        }

        /// <summary>
        /// 创建碰撞报告项目
        /// </summary>
        private CollisionReportItem CreateCollisionReportItem(CollisionResult collision, int index)
        {
            // 获取元素名称和全路径
            var item1Name = ModelItemAnalysisHelper.GetSafeDisplayName(collision.Item1);
            var item2Name = ModelItemAnalysisHelper.GetSafeDisplayName(collision.Item2);
            var item1Path = GetModelItemFullPath(collision.Item1);
            var item2Path = GetModelItemFullPath(collision.Item2);

            var title = $"{item1Name} ↔ {item2Name}";

            var item = new CollisionReportItem
            {
                Index = index,
                Title = string.IsNullOrEmpty(title.Trim().Replace("↔", "").Trim()) ? "未命名碰撞" : title,
                StatusText = GetStatusDisplayText(collision.Status),
                StatusColor = GetStatusColor(collision.Status),
                Details = $"位置: ({collision.Center.X:F2}, {collision.Center.Y:F2}, {collision.Center.Z:F2})",
                Item1FullPath = $"🚛 运动物体: {item1Path}",
                Item2FullPath = $"💥 被撞对象: {item2Path}",
                CollisionData = collision
            };

            return item;
        }

        /// <summary>
        /// 获取ModelItem的完整层级路径
        /// </summary>
        private string GetModelItemFullPath(ModelItem item)
        {
            if (item == null) return "未知对象";
            
            try
            {
                var pathParts = new List<string>();
                var current = item;
                int levels = 0;
                
                while (current != null && levels < 20)
                {
                    var name = ModelItemAnalysisHelper.GetSafeDisplayName(current);
                    if (!string.IsNullOrEmpty(name) && name != "未命名对象")
                    {
                        pathParts.Insert(0, name);
                    }
                    current = current.Parent;
                    levels++;
                }
                
                return pathParts.Count > 0 ? string.Join(" > ", pathParts) : "未知对象";
            }
            catch
            {
                return ModelItemAnalysisHelper.GetSafeDisplayName(item);
            }
        }


        /// <summary>
        /// 获取状态显示文本
        /// </summary>
        private string GetStatusDisplayText(Autodesk.Navisworks.Api.Clash.ClashResultStatus status)
        {
            switch (status)
            {
                case Autodesk.Navisworks.Api.Clash.ClashResultStatus.New:
                    return "新发现";
                case Autodesk.Navisworks.Api.Clash.ClashResultStatus.Active:
                    return "活跃";
                case Autodesk.Navisworks.Api.Clash.ClashResultStatus.Reviewed:
                    return "已审阅";
                case Autodesk.Navisworks.Api.Clash.ClashResultStatus.Approved:
                    return "已批准";
                case Autodesk.Navisworks.Api.Clash.ClashResultStatus.Resolved:
                    return "已解决";
                default:
                    return "未知";
            }
        }

        /// <summary>
        /// 获取状态颜色
        /// </summary>
        private string GetStatusColor(Autodesk.Navisworks.Api.Clash.ClashResultStatus status)
        {
            switch (status)
            {
                case Autodesk.Navisworks.Api.Clash.ClashResultStatus.New:
                    return "#FF6B6B";        // 红色 - 新问题
                case Autodesk.Navisworks.Api.Clash.ClashResultStatus.Active:
                    return "#FFA500";        // 橙色 - 活跃
                case Autodesk.Navisworks.Api.Clash.ClashResultStatus.Reviewed:
                    return "#87CEEB";        // 天蓝色 - 已审阅
                case Autodesk.Navisworks.Api.Clash.ClashResultStatus.Approved:
                    return "#98FB98";        // 浅绿色 - 已批准
                case Autodesk.Navisworks.Api.Clash.ClashResultStatus.Resolved:
                    return "#90EE90";        // 绿色 - 已解决
                default:
                    return "#D3D3D3";        // 灰色 - 未知
            }
        }

        /// <summary>
        /// 生成总结和建议
        /// </summary>
        private void GenerateSummaryAndRecommendations(CollisionReportResult reportResult)
        {
            if (reportResult.TotalCollisions == 0)
            {
                SummaryMessage = "✅ 未发现碰撞问题，路径规划良好。";
                RecommendationMessage = "当前路径设计合理，无需调整。建议定期进行碰撞检测以确保持续的安全性。";
            }
            else
            {
                SummaryMessage = $"⚠️ 发现 {reportResult.TotalCollisions} 个碰撞问题，需要采取措施处理。";
                
                var recommendations = new List<string>
                {
                    "1. 调整路径规划，避开碰撞区域",
                    "2. 检查物体尺寸和安全边距设置",
                    "3. 考虑增加临时障碍物标记",
                    "4. 重新评估物流流程设计",
                    "5. 建议进行更详细的碰撞检测分析"
                };

                RecommendationMessage = string.Join("\n", recommendations);
            }
        }


        /// <summary>
        /// 设置空报告状态
        /// </summary>
        private void SetEmptyReport()
        {
            ReportStatus = CollisionReportStatus.Empty;
            IsGenerating = false;
            HasCollisions = false;
            SummaryMessage = "📄 暂无碰撞数据";
            RecommendationMessage = "请先运行碰撞检测或动画播放以生成碰撞数据。";
            Statistics = new CollisionReportStatistics { ReportType = "空报告" };
        }

        /// <summary>
        /// 设置失败报告状态
        /// </summary>
        private void SetFailedReport(string errorMessage)
        {
            ReportStatus = CollisionReportStatus.Failed;
            IsGenerating = false;
            HasCollisions = false;
            SummaryMessage = "❌ 报告生成失败";
            RecommendationMessage = $"错误信息: {errorMessage}";
            Statistics = new CollisionReportStatistics { ReportType = "生成失败" };
        }

        #endregion

        #region 命令方法

        /// <summary>
        /// 导出报告
        /// </summary>
        private async Task ExportReportAsync()
        {
            try
            {
                var saveFileDialog = new SaveFileDialog
                {
                    Title = "导出碰撞报告",
                    Filter = "HTML报告 (*.html)|*.html|碰撞报告 (*.txt)|*.txt|所有文件 (*.*)|*.*",
                    DefaultExt = "html",
                    FileName = PathHelper.GenerateCollisionReportFileName(CurrentReport?.PathName ?? PathName, "html")
                };

                if (saveFileDialog.ShowDialog() == true)
                {
                    await Task.Run(() =>
                    {
                        var content = GenerateExportContent(Path.GetExtension(saveFileDialog.FileName).ToLower(), saveFileDialog.FileName);
                        File.WriteAllText(saveFileDialog.FileName, content, Encoding.UTF8);
                    });

                    LogManager.Info($"碰撞报告已导出到: {saveFileDialog.FileName}");
                    
                    // 这里可以显示导出成功的提示
                }
            }
            catch (Exception ex)
            {
                LogManager.Error($"导出碰撞报告失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 自动导出报告到默认目录（关闭窗口时调用）
        /// </summary>
        public async Task AutoExportReportAsync()
        {
            try
            {
                if (CurrentReport == null) return;

                // 生成默认文件名和路径
                var fileName = PathHelper.GenerateCollisionReportFileName(CurrentReport.PathName, "html");
                var reportDir = PathHelper.GetReportDirectory();
                var filePath = Path.Combine(reportDir, fileName);

                await Task.Run(() =>
                {
                    var content = GenerateHtmlReport(filePath);
                    File.WriteAllText(filePath, content, Encoding.UTF8);
                });

                LogManager.Info($"报告已自动导出到: {filePath}");
            }
            catch (Exception ex)
            {
                LogManager.Error($"自动导出报告失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 生成导出内容
        /// </summary>
        private string GenerateExportContent(string fileExtension, string filePath = null)
        {
            if (fileExtension == ".html")
            {
                return GenerateHtmlReport(filePath);
            }
            else
            {
                return GenerateTextReport();
            }
        }

        /// <summary>
        /// 生成文本报告
        /// </summary>
        private string GenerateTextReport()
        {
            var report = new StringBuilder();
            var now = DateTime.Now;

            // 报告头部
            report.AppendLine("========================================");
            report.AppendLine("       NavisworksTransport 碰撞检测报告");
            report.AppendLine("========================================");
            report.AppendLine($"生成时间: {now:yyyy年MM月dd日 HH:mm:ss}");
            report.AppendLine($"报告类型: {Statistics.ReportType}");
            report.AppendLine();

            // 检测记录信息
            report.AppendLine("=== 检测记录 ===");
            report.AppendLine($"测试名称: {TestName ?? "未命名"}");
            report.AppendLine($"检测时间: {TestTimeDisplay}");
            report.AppendLine($"路径名称: {PathName}");
            report.AppendLine();

            // 总体统计
            report.AppendLine("=== 总体统计 ===");
            report.AppendLine($"总碰撞数: {Statistics.TotalCollisions}");
            report.AppendLine($"碰撞构件: {UniqueCollidedObjectsCount}个");
            report.AppendLine($"检测点: {Statistics.AnimationCollisions}个");
            report.AppendLine();

            // 动画参数
            report.AppendLine("=== 动画参数 ===");
            report.AppendLine($"帧率: {FrameRate} FPS");
            report.AppendLine($"时长: {Duration:F1} 秒");
            report.AppendLine($"检测容差: {DetectionTolerance:F2} 米");
            report.AppendLine();

            // 运动构件信息
            if (!string.IsNullOrEmpty(MovingObjectInfo))
            {
                report.AppendLine($"{MovingObjectInfo}");
            }
            report.AppendLine();

            // 被撞物体清单
            if (CollidedObjectsList?.Count > 0)
            {
                report.AppendLine("=== 碰撞构件清单 ===");
                int index = 1;
                foreach (var objName in CollidedObjectsList.Take(20)) // 限制显示前20个
                {
                    report.AppendLine($"  {index}. {objName}");
                    index++;
                }
                if (CollidedObjectsList.Count > 20)
                {
                    report.AppendLine($"  ... 还有 {CollidedObjectsList.Count - 20} 个构件");
                }
                report.AppendLine();
            }

            // 详细碰撞信息
            if (HasCollisions)
            {
                AddCollisionDetailsToTextReport(report, "碰撞详情", AnimationCollisions);
            }

            // 总结和建议
            report.AppendLine("=== 总结与建议 ===");
            report.AppendLine(SummaryMessage);
            report.AppendLine();
            report.AppendLine("建议措施：");
            report.AppendLine(RecommendationMessage);
            report.AppendLine();

            report.AppendLine("========================================");
            report.AppendLine($"报告生成完成 - {now:HH:mm:ss}");
            report.AppendLine("========================================");

            return report.ToString();
        }

        /// <summary>
        /// 添加碰撞详细信息到文本报告
        /// </summary>
        private void AddCollisionDetailsToTextReport(StringBuilder report, string sectionTitle, ObservableCollection<CollisionReportItem> items)
        {
            if (items?.Count > 0)
            {
                report.AppendLine($"--- {sectionTitle} ---");
                foreach (var item in items.Take(10)) // 限制显示数量
                {
                    report.AppendLine($"• {item.Title}");
                    report.AppendLine($"  状态: {item.StatusText}");
                    report.AppendLine($"  {item.Details.Replace("\n", "\n  ")}");
                    report.AppendLine();
                }
                if (items.Count > 10)
                {
                    report.AppendLine($"... 还有 {items.Count - 10} 个{sectionTitle}未显示");
                }
                report.AppendLine();
            }
        }

        /// <summary>
        /// 生成HTML报告 - 统一使用 CollisionReportHtmlGenerator
        /// </summary>
        private string GenerateHtmlReport(string htmlFilePath = null)
        {
            // 确保 CurrentReport 的截图列表与 ViewModel 同步
            if (CurrentReport != null && Screenshots != null)
            {
                CurrentReport.Screenshots = Screenshots.ToList();
            }
            
            return CollisionReportHtmlGenerator.GenerateHtmlReport(CurrentReport, htmlFilePath);
        }

        /// <summary>
        /// 高亮碰撞对象
        /// </summary>
        private void HighlightCollision(CollisionReportItem item)
        {
            try
            {
                if (item?.CollisionData == null)
                    return;

                // 使用 ClashDetectiveResultsCategory（深红色），不是预计算高亮
                var collisions = new List<CollisionResult> { item.CollisionData };
                ModelHighlightHelper.ManageCollisionHighlightsByCategory(
                    ModelHighlightHelper.ClashDetectiveResultsCategory, 
                    collisions, 
                    clearOtherCategories: true);
                LogManager.Info($"高亮碰撞对象: {item.Title}");
            }
            catch (Exception ex)
            {
                LogManager.Error($"高亮碰撞对象失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 关闭窗口
        /// </summary>
        private void CloseWindow()
        {
            // 这个方法会由View中的代码调用
            LogManager.Info("关闭碰撞报告窗口");
        }

        /// <summary>
        /// 执行添加新截图（使用默认设置，不弹出对话框）
        /// </summary>
        private void ExecuteAddScreenshot()
        {
            try
            {
                // 构建路径相关的截图目录（与GenerateCollisionReportCommand保持一致）
                // 格式: screenshots/{RouteId前8位}_{PathName}/
                string routeId = CurrentReport.RouteId ?? "unknown";
                string pathName = CurrentReport.PathName ?? "collision";
                string pathDirName = string.Format("{0}_{1}", 
                    routeId.Length >= 8 ? routeId.Substring(0, 8) : routeId,
                    PathHelper.SanitizeFileName(pathName));
                string pathScreenshotDir = System.IO.Path.Combine(
                    PathHelper.GetScreenshotDirectory(), 
                    pathDirName);
                
                // 使用路径相关的目录生成截图
                string screenshotPath = PathHelper.GenerateSceneScreenshotToDirectory(
                    pathScreenshotDir,
                    pathName,
                    ScreenshotWidthSetting,
                    ScreenshotHeightSetting,
                    ScreenshotFormatSetting,
                    "collision"
                );
                
                if (screenshotPath != null)
                {
                    // 创建截图对象
                    var screenshot = new CollisionReportScreenshot
                    {
                        FilePath = screenshotPath,
                        Format = PathHelper.ImageFormatToExtension(ScreenshotFormatSetting).ToUpper(),
                        Width = ScreenshotWidthSetting,
                        Height = ScreenshotHeightSetting,
                        SortOrder = Screenshots.Count
                    };
                    
                    // 添加到列表
                    Screenshots.Add(screenshot);
                    SelectedScreenshot = screenshot;
                    
                    // 同步到报告数据
                    if (CurrentReport.Screenshots == null)
                        CurrentReport.Screenshots = new List<CollisionReportScreenshot>();
                    CurrentReport.Screenshots.Add(screenshot);
                    
                    // 保存到数据库
                    try
                    {
                        var pathDatabase = PathPlanningManager.Instance?.GetPathDatabase();
                        // 使用 ResultId 精确关联到当前报告记录
                        if (pathDatabase != null && CurrentReport.ResultId > 0)
                        {
                            int dbId = pathDatabase.SaveCollisionReportScreenshot(
                                CurrentReport.ResultId,
                                screenshotPath,
                                screenshot.Format,
                                screenshot.Width,
                                screenshot.Height,
                                screenshot.SortOrder
                            );
                            screenshot.DatabaseId = dbId;  // 保存数据库Id用于后续删除
                            LogManager.Info($"新截图已保存到数据库: DatabaseId={dbId}, ResultId={CurrentReport.ResultId}, Path={screenshotPath}");
                        }
                        else
                        {
                            LogManager.Warning($"无法保存截图到数据库: ResultId={CurrentReport.ResultId}, RouteId={CurrentReport.RouteId}");
                        }
                    }
                    catch (Exception dbEx)
                    {
                        LogManager.Error($"保存新截图到数据库失败: {dbEx.Message}");
                    }
                    
                    OnPropertyChanged(nameof(HasScreenshots));
                    OnPropertyChanged(nameof(ScreenshotCount));
                    
                    LogManager.Info($"已添加新截图，当前共 {Screenshots.Count} 张");
                }
            }
            catch (Exception ex)
            {
                LogManager.Error($"添加截图失败: {ex.Message}");
                System.Windows.MessageBox.Show($"添加截图失败: {ex.Message}", "错误", 
                    System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error);
            }
        }

        /// <summary>
        /// 检查是否可以添加截图
        /// </summary>
        private bool CanExecuteAddScreenshot()
        {
            return CurrentReport != null;
        }

        /// <summary>
        /// 执行截图设置 - 打开对话框修改截图参数
        /// </summary>
        private void ExecuteScreenshotSettings()
        {
            try
            {
                var dialog = new GenerateNavigationMapDialog();
                dialog.Title = "截图设置";
                
                // 设置当前值，默认优先使用当前视窗尺寸
                dialog.SetInitialValues(ScreenshotWidthSetting, ScreenshotHeightSetting, ScreenshotFormatSetting, preferCurrentViewport: true);
                
                DialogHelper.SetOwnerSafely(dialog);
                
                if (dialog.ShowDialog() == true)
                {
                    // 更新设置
                    ScreenshotWidthSetting = dialog.ImageWidth;
                    ScreenshotHeightSetting = dialog.ImageHeight;
                    ScreenshotFormatSetting = dialog.ImageFormat;
                    
                    LogManager.Info($"截图设置已更新: {ScreenshotWidthSetting}x{ScreenshotHeightSetting}, {ScreenshotFormatSetting}");
                }
            }
            catch (Exception ex)
            {
                LogManager.Error($"打开截图设置失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 执行删除截图
        /// </summary>
        private void ExecuteDeleteScreenshot(CollisionReportScreenshot screenshot)
        {
            if (screenshot == null) return;
            
            try
            {
                var result = System.Windows.MessageBox.Show(
                    "确定要删除这张截图吗？",
                    "确认删除",
                    System.Windows.MessageBoxButton.YesNo,
                    System.Windows.MessageBoxImage.Question);
                
                if (result != System.Windows.MessageBoxResult.Yes) return;
                
                // 删除物理文件（如果存在）
                if (!string.IsNullOrEmpty(screenshot.FilePath) && System.IO.File.Exists(screenshot.FilePath))
                {
                    try
                    {
                        System.IO.File.Delete(screenshot.FilePath);
                        LogManager.Debug($"已删除截图文件: {screenshot.FilePath}");
                    }
                    catch (Exception fileEx)
                    {
                        LogManager.Error($"删除截图文件失败: {fileEx.Message}");
                        // 继续删除数据库记录，不中断流程
                    }
                }
                
                // 从数据库删除（如果知道DatabaseId）
                LogManager.Info($"开始删除截图，DatabaseId={screenshot.DatabaseId}, FilePath={screenshot.FilePath}");
                if (screenshot.DatabaseId > 0)
                {
                    try
                    {
                        var pathDatabase = PathPlanningManager.Instance?.GetPathDatabase();
                        if (pathDatabase != null)
                        {
                            // 删除前查询数量
                            var beforeScreenshots = pathDatabase.GetCollisionReportScreenshots(CurrentReport.ResultId);
                            var beforeCount = beforeScreenshots?.Count ?? 0;
                            var targetExists = beforeScreenshots?.Any(s => s.Id == screenshot.DatabaseId) ?? false;
                            
                            pathDatabase.DeleteCollisionReportScreenshot(screenshot.DatabaseId);
                            
                            // 删除后验证
                            var afterScreenshots = pathDatabase.GetCollisionReportScreenshots(CurrentReport.ResultId);
                            var afterCount = afterScreenshots?.Count ?? 0;
                            var targetStillExists = afterScreenshots?.Any(s => s.Id == screenshot.DatabaseId) ?? false;
                            
                            LogManager.Info($"数据库删除验证: 删除前={beforeCount}张(目标存在:{targetExists}), 删除后={afterCount}张(目标仍存在:{targetStillExists}), 删除Id={screenshot.DatabaseId}");
                        }
                        else
                        {
                            LogManager.Error("无法获取PathDatabase，数据库删除失败");
                        }
                    }
                    catch (Exception dbEx)
                    {
                        LogManager.Error($"从数据库删除截图失败: {dbEx.Message}");
                    }
                }
                else
                {
                    LogManager.Warning($"截图DatabaseId为0，跳过数据库删除");
                }
                
                // 从列表移除
                Screenshots.Remove(screenshot);
                
                // 从报告数据移除
                CurrentReport.Screenshots?.Remove(screenshot);
                
                // 更新选中项
                if (SelectedScreenshot == screenshot)
                {
                    SelectedScreenshot = Screenshots.FirstOrDefault();
                }
                
                // 重新排序并更新数据库
                for (int i = 0; i < Screenshots.Count; i++)
                {
                    Screenshots[i].SortOrder = i;
                }
                
                OnPropertyChanged(nameof(HasScreenshots));
                OnPropertyChanged(nameof(ScreenshotCount));
                
                LogManager.Info($"已删除截图，剩余 {Screenshots.Count} 张");
            }
            catch (Exception ex)
            {
                LogManager.Error($"删除截图失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 执行选择截图
        /// </summary>
        private void ExecuteSelectScreenshot(CollisionReportScreenshot screenshot)
        {
            if (screenshot != null)
            {
                SelectedScreenshot = screenshot;
                LogManager.Debug($"选中截图: {screenshot.FilePath}");
            }
        }

        /// <summary>
        /// 高亮并聚焦到碰撞项目中的被撞对象（Item2）
        /// 同时将运动物体（Item1）移动到碰撞时的位置和朝向，还原碰撞场景
        /// </summary>
        public void HighlightAndFocusCollisionItem(CollisionReportItem collisionItem)
        {
            if (collisionItem?.CollisionData == null) return;

            try
            {
                var collisionData = collisionItem.CollisionData;
                
                // 首次查看碰撞时保存运动物体状态
            if (collisionData.Item1 != null && collisionData.HasPositionInfo && collisionData.AnimatedObjectTrackedPosition != null)
                {
                    if (_savedAnimatedObjectState == null || _currentAnimatedObject != collisionData.Item1)
                    {
                        _currentAnimatedObject = collisionData.Item1;
                        _savedAnimatedObjectState = CollisionSceneHelper.SaveAnimatedObjectState(collisionData.Item1);
                    }
                }
                
                // 🔥 关键修复：如果运动物体是虚拟物体，确保它是可见的
                if (_currentAnimatedObject != null && 
                    VirtualObjectManager.Instance.IsVirtualObjectActive && 
                    VirtualObjectManager.Instance.CurrentVirtualObject == _currentAnimatedObject)
                {
                    // 虚拟物体已存在但可能被隐藏，需要显示
                    // 使用默认尺寸 2x1x2 米（ShowVirtualObject 内部会处理尺寸更新）
                    VirtualObjectManager.Instance.ShowVirtualObject(2.0, 1.0, 2.0);
                    LogManager.Debug("[碰撞报告] 虚拟物体已确保可见");
                }
                
                // 使用通用方法移动并聚焦到碰撞位置
                CollisionSceneHelper.MoveToCollisionAndFocus(collisionData, _currentAnimatedObject);
            }
            catch (Exception ex)
            {
                LogManager.Error($"聚焦到被撞对象失败: {ex.Message}", ex);
            }
        }
        
        /// <summary>
        /// 恢复运动物体到原始状态（查看碰撞前保存的状态）
        /// </summary>
        public void RestoreAnimatedObjectToOriginalState()
        {
            CollisionSceneHelper.RestoreAnimatedObjectState(_currentAnimatedObject, _savedAnimatedObjectState);
            
            // 清除保存的状态
            _savedAnimatedObjectState = null;
            _currentAnimatedObject = null;
        }

        #endregion
    }
}
