using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Autodesk.Navisworks.Api;
using Autodesk.Navisworks.Api.Clash;
using NavisworksTransport.Core;
using NavisworksTransport.Core.Animation;
using NavisworksTransport.Core.Config;
using NavisworksTransport.Utils;
using NavisworksTransport.Utils.CoordinateSystem;
using NavisworksTransport.UI.WPF.Views;

namespace NavisworksTransport.Commands
{
    /// <summary>
    /// 碰撞报告参数类
    /// </summary>
    public class CollisionReportParameters
    {
        /// <summary>
        /// 报告类型
        /// </summary>
        public enum ReportType
        {
            /// <summary>动画碰撞报告</summary>
            Animation,
            /// <summary>独立碰撞检测报告</summary>
            Independent,
            /// <summary>综合报告（包含所有类型）</summary>
            Comprehensive
        }

        /// <summary>
        /// 要生成的报告类型
        /// </summary>
        public ReportType Type { get; set; } = ReportType.Comprehensive;

        /// <summary>
        /// 是否包含详细信息
        /// </summary>
        public bool IncludeDetails { get; set; } = true;

        /// <summary>
        /// 路径ID（用于视角调整）
        /// </summary>
        public string RouteId { get; set; } = string.Empty;

        /// <summary>
        /// 碰撞结果是否已经被高亮过了（用于避免重复高亮）
        /// </summary>
        public bool HasHighlighted { get; set; } = false;

        /// <summary>
        /// 是否显示报告窗口（批处理模式设为false，只生成报告不弹窗）
        /// </summary>
        public bool ShowDialog { get; set; } = true;

        public PathPlanningResult ValidateParameters()
        {
            return PathPlanningResult.Success("参数验证通过");
        }
    }

    /// <summary>
    /// 碰撞数据收集结果
    /// </summary>
    public class CollisionDataResult
    {
        public List<CollisionResult> AllCollisions { get; set; } = new List<CollisionResult>();
        public int BoundingBoxTestCount { get; set; }    // 包围盒测试数量
        public int ClashDetectiveCollisionCount { get; set; } // Clash Detective结果数量
        public int AnimationCollisions { get; set; }       // 动画过程碰撞数量
        public string MovingObjectInfo { get; set; } = string.Empty;

        // 新增：被撞物体去重统计
        public HashSet<string> UniqueCollidedObjects { get; set; } = new HashSet<string>();
    }

    /// <summary>
    /// 碰撞报告截图项
    /// </summary>
    public class CollisionReportScreenshot
    {
        /// <summary>截图唯一标识（UI用）</summary>
        public string Id { get; set; } = Guid.NewGuid().ToString("N");
        /// <summary>数据库记录Id（用于删除）</summary>
        public int DatabaseId { get; set; }
        /// <summary>截图文件路径</summary>
        public string FilePath { get; set; }
        /// <summary>图片格式 (PNG/JPG)</summary>
        public string Format { get; set; }
        /// <summary>图片宽度</summary>
        public int Width { get; set; }
        /// <summary>图片高度</summary>
        public int Height { get; set; }
        /// <summary>截图时间</summary>
        public DateTime CaptureTime { get; set; } = DateTime.Now;
        /// <summary>截图描述/备注</summary>
        public string Description { get; set; }
        /// <summary>排序顺序</summary>
        public int SortOrder { get; set; }
    }

    /// <summary>
    /// 碰撞报告结果类
    /// </summary>
    public class CollisionReportResult
    {
        public string ReportContent { get; set; }
        public int TotalCollisions { get; set; }
        public int AnimationCollisions { get; set; }    // 检测点数量
        public List<CollisionResult> AllCollisions { get; set; } = new List<CollisionResult>();
        public long GenerationTimeMs { get; set; }
        public string MovingObjectInfo { get; set; } = string.Empty;

        // 新增：被撞物体清单
        public List<string> CollidedObjectsList { get; set; } = new List<string>();
        public int UniqueCollidedObjectsCount { get; set; }

        // 新增：动画参数
        public string RouteId { get; set; }  // 路径ID，用于数据库关联
        public int ResultId { get; set; }    // 数据库记录Id，用于关联截图
        public string PathName { get; set; }
        public int FrameRate { get; set; } 
        public double Duration { get; set; }
        public double DetectionTolerance { get; set; }

        // 截图列表 - 支持多张截图
        public List<CollisionReportScreenshot> Screenshots { get; set; } = new List<CollisionReportScreenshot>();

        // 排除对象列表
        public List<ExcludedObjectRecord> ExcludedObjects { get; set; } = new List<ExcludedObjectRecord>();
    }

    /// <summary>
    /// 生成碰撞报告Command
    /// </summary>
    public class GenerateCollisionReportCommand : CommandBase
    {
        private readonly CollisionReportParameters _parameters;
        private string _specificTestName = null; // 指定的测试名称（用于历史报告）
        private int? _detectionRecordId = null;  // 检测记录ID（优先使用）

        public GenerateCollisionReportCommand(CollisionReportParameters parameters = null)
            : base("GenerateCollisionReport", "生成碰撞报告", "生成并显示详细的碰撞检测报告")
        {
            _parameters = parameters ?? new CollisionReportParameters();
        }

        /// <summary>
        /// 设置要生成报告的测试名称
        /// </summary>
        public void SetTestName(string testName)
        {
            _specificTestName = testName;
        }

        /// <summary>
        /// 设置检测记录ID（优先使用ID查询）
        /// </summary>
        public void SetDetectionRecordId(int? detectionRecordId)
        {
            _detectionRecordId = detectionRecordId;
        }

        protected override PathPlanningResult ValidateParameters()
        {
            return _parameters.ValidateParameters();
        }

        protected override async Task<PathPlanningResult> ExecuteInternalAsync(CancellationToken cancellationToken)
        {
            var startTime = DateTime.UtcNow;

            UpdateProgress(10, "开始生成碰撞报告...");

            // 获取ClashDetectiveIntegration实例
            var clashIntegration = ClashDetectiveIntegration.Instance;

            // 优先使用检测记录ID，其次使用测试名称
            var targetTestName = _specificTestName ?? clashIntegration?.CurrentTestName;

            // 获取检测记录信息（优先使用ID查询）
            var testInfo = GetTestInfoFromDatabase();
            if (testInfo == null && !string.IsNullOrEmpty(targetTestName))
            {
                // 如果ID查询失败且提供了测试名称，尝试用名称查询
                testInfo = GetTestInfoFromDatabaseByName(targetTestName);
            }

            if (testInfo == null)
            {
                return PathPlanningResult.Failure("无法找到检测记录，请先运行碰撞检测或选择历史记录");
            }

            // 使用实际的数据库记录中的TestName
            targetTestName = testInfo.TestName ?? targetTestName;

            var result = new CollisionReportResult();

            try
            {
                UpdateProgress(30, "收集碰撞数据...");

                // 收集所有碰撞数据及统计信息（同步执行，避免 COM 线程问题）
                var collisionData = CollectAllCollisionData(targetTestName);
                result.AllCollisions = collisionData.AllCollisions;

                // 修改统计数据
                result.AnimationCollisions = collisionData.AnimationCollisions;
                result.TotalCollisions = collisionData.ClashDetectiveCollisionCount;
                result.MovingObjectInfo = collisionData.MovingObjectInfo;

                // 新增：被撞物体清单
                result.CollidedObjectsList = collisionData.UniqueCollidedObjects.OrderBy(x => x).ToList();
                result.UniqueCollidedObjectsCount = collisionData.UniqueCollidedObjects.Count;

                // 新增：从动画管理器获取动画参数
                var animationManager = Core.Animation.PathAnimationManager.GetInstance();
                if (animationManager != null)
                {
                    result.FrameRate = animationManager.AnimationFrameRate;
                    result.Duration = animationManager.AnimationDuration;
                    result.DetectionTolerance = ConfigManager.Instance.Current.Animation.DetectionToleranceMeters;
                }

                // 从数据库记录填充路径信息
                var db = PathPlanningManager.Instance?.GetPathDatabase();
                var route = db?.GetPathRouteSync(testInfo.RouteId);
                result.PathName = route?.Name ?? "未知路径";
                result.RouteId = testInfo.RouteId;
                result.ResultId = testInfo.Id;

                LogManager.Info($"碰撞报告数据 - TestName={targetTestName}, ResultId={result.ResultId}, PathName={result.PathName}");

                UpdateProgress(70, "生成报告内容...");

                // 生成报告内容
                result.ReportContent = GenerateReportContent(collisionData, _parameters.Type, _parameters.IncludeDetails);

                UpdateProgress(90, "处理报告显示...");

                // 如果碰撞结果还没有高亮，则执行高亮（不清除之前的高亮，避免影响其他场景）
                if (!_parameters.HasHighlighted && collisionData.AllCollisions.Count > 0)
                {
                    try
                    {
                        var highlightIntegration = ClashDetectiveIntegration.Instance;
                        if (highlightIntegration != null)
                        {
                            // 使用 ClashDetectiveResultsCategory（深红色），不是预计算高亮
                            ModelHighlightHelper.ManageCollisionHighlightsByCategory(
                                ModelHighlightHelper.ClashDetectiveResultsCategory, 
                                collisionData.AllCollisions, 
                                clearOtherCategories: false);
                            LogManager.Info($"碰撞报告生成前高亮 {collisionData.AllCollisions.Count} 个碰撞对象");
                        }
                    }
                    catch (Exception ex)
                    {
                        LogManager.Error($"高亮碰撞对象失败: {ex.Message}");
                    }
                }

                // 保存原始视角
                Viewpoint originalViewpoint = null;
                try
                {
                    originalViewpoint = ViewpointHelper.SaveCurrentViewpoint();
                    LogManager.Info("原始视角已保存");
                }
                catch (Exception ex)
                {
                    LogManager.Error($"保存原始视角失败: {ex.Message}");
                }

                // 智能调整视角（确保所有碰撞都在视野内）
                try
                {
                    // 从所有路径中查找当前路径
                    var allRoutes = PathPlanningManager.Instance.GetAllRoutes();
                    var pathRoute = allRoutes.FirstOrDefault(r => r.Id == _parameters.RouteId);
                    
                    ViewpointHelper.AdjustViewpointSmart(pathRoute, collisionData.AllCollisions);
                    
                    LogManager.Info("视角调整完成");
                }
                catch (Exception ex)
                {
                    LogManager.Error($"自动调整视角失败: {ex.Message}");
                    // 视角调整失败不影响截图生成
                }

                UpdateProgress(95, "加载碰撞报告截图...");

                // 加载多截图数据（从新的截图表）
                bool loadedScreenshotsFromDatabase = false;
                var pathDatabase = PathPlanningManager.Instance?.GetPathDatabase();
                if (pathDatabase != null)
                {
                    try
                    {
                        // 先获取结果记录以获取 DetectionRecordId
                        var testRecord = pathDatabase.GetDetectionResultByTestName(targetTestName);
                        if (testRecord != null)
                        {
                            LogManager.Debug($"加载截图 - 找到测试记录: TestName={targetTestName}, DetectionRecordId={testRecord.Id}");
                            
                            // 从截图表加载所有截图
                            var screenshotRecords = pathDatabase.GetCollisionReportScreenshots(testRecord.Id);
                            LogManager.Debug($"加载截图 - 查询到 {screenshotRecords?.Count ?? 0} 张截图 (ResultId={testRecord.Id})");
                            
                            if (screenshotRecords != null && screenshotRecords.Count > 0)
                            {
                                result.Screenshots = screenshotRecords.Select(r => new CollisionReportScreenshot
                                {
                                    DatabaseId = r.Id,  // 数据库主键，用于删除
                                    FilePath = r.FilePath,
                                    Format = r.Format,
                                    Width = r.Width,
                                    Height = r.Height,
                                    CaptureTime = r.CaptureTime,
                                    Description = r.Description,
                                    SortOrder = r.SortOrder
                                }).ToList();
                                loadedScreenshotsFromDatabase = true;
                                LogManager.Info($"从数据库加载了 {result.Screenshots.Count} 张截图 (ResultId={testRecord.Id})");
                            }

                            // 加载排除对象列表
                            try
                            {
                                var excludedObjects = pathDatabase.GetExcludedObjectsForDetectionRecord(testRecord.Id);
                                if (excludedObjects != null && excludedObjects.Count > 0)
                                {
                                    result.ExcludedObjects = excludedObjects;
                                    LogManager.Info($"从数据库加载了 {excludedObjects.Count} 个排除对象 (ResultId={testRecord.Id})");
                                }
                            }
                            catch (Exception ex)
                            {
                                LogManager.Error($"加载排除对象列表失败: {ex.Message}");
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        LogManager.Error($"加载截图数据失败: {ex.Message}");
                    }
                }

                // 检查并创建路径子目录（用于存放该路径的所有截图）
                string pathDir = System.IO.Path.Combine(PathHelper.GetScreenshotDirectory(), 
                    string.Format("{0}_{1}", result.RouteId.Substring(0, 8), result.PathName ?? "collision"));
                PathHelper.EnsureDirectoryExists(pathDir);
                
                // 先生成默认截图（整条路径的概览）
                if (result.Screenshots == null || result.Screenshots.Count == 0)
                {
                    try
                    {
                        UpdateProgress(92, "生成默认路径截图...");
                        
                        // 记录截图前虚拟物体位置和动画管理器状态。
                        // 不读取 ModelItem.Transform 的“实际朝向”，因为 override 后该值不可靠，容易误导排查。
                        var virtualObject = VirtualObjectManager.Instance.CurrentVirtualObject;
                        if (virtualObject != null)
                        {
                            var pam = PathAnimationManager.GetInstance();
                            var position = GetAnimatedObjectReportedPosition(virtualObject, pam);
                            LogManager.Info(string.Format("[默认截图前] 虚拟物体位置: ({0:F2},{1:F2},{2:F2}), PAM记录朝向: {3:F2}°, customRotation={4}",
                                position.X, position.Y, position.Z,
                                pam.CurrentYaw * 180 / Math.PI, pam.HasTrackedRotation));
                        }
                        else
                        {
                            LogManager.Warning("[默认截图前] 无法获取虚拟物体");
                        }
                        
                        // 获取当前视窗尺寸
                        var generator = new NavigationMapGenerator();
                        var viewportSize = generator.GetCurrentViewportSize();
                        int screenshotWidth = viewportSize.Width;
                        int screenshotHeight = viewportSize.Height;
                        
                        string screenshotPath = PathHelper.GenerateSceneScreenshotToDirectory(
                            pathDir,
                            "path",
                            screenshotWidth,
                            screenshotHeight,
                            System.Drawing.Imaging.ImageFormat.Jpeg,
                            "overview"
                        );
                        
                        // 记录截图后虚拟物体位置和动画管理器状态。
                        virtualObject = VirtualObjectManager.Instance.CurrentVirtualObject;
                        if (virtualObject != null)
                        {
                            var pam = PathAnimationManager.GetInstance();
                            var position = GetAnimatedObjectReportedPosition(virtualObject, pam);
                            LogManager.Info(string.Format("[默认截图后] 虚拟物体位置: ({0:F2},{1:F2},{2:F2}), PAM记录朝向: {3:F2}°, customRotation={4}",
                                position.X, position.Y, position.Z,
                                pam.CurrentYaw * 180 / Math.PI, pam.HasTrackedRotation));
                        }

                        if (screenshotPath != null)
                        {
                            // 保存截图到数据库
                            int screenshotId = 0;
                            if (pathDatabase != null && result.ResultId > 0)
                            {
                                try
                                {
                                    screenshotId = pathDatabase.SaveCollisionReportScreenshot(
                                        result.ResultId,
                                        screenshotPath,
                                        "JPG",
                                        screenshotWidth,
                                        screenshotHeight,
                                        0,
                                        "路径概览"
                                    );
                                    LogManager.Info(string.Format("默认截图已保存到数据库: ScreenshotId={0}", screenshotId));
                                }
                                catch (Exception dbEx)
                                {
                                    LogManager.Error(string.Format("保存默认截图到数据库失败: {0}", dbEx.Message));
                                }
                            }
                            
                            result.Screenshots = new List<CollisionReportScreenshot>
                            {
                                new CollisionReportScreenshot
                                {
                                    DatabaseId = screenshotId,  // 设置数据库Id
                                    FilePath = screenshotPath,
                                    Format = "JPG",
                                    Width = screenshotWidth,
                                    Height = screenshotHeight,
                                    CaptureTime = DateTime.Now,
                                    Description = "路径概览",
                                    SortOrder = 0
                                }
                            };
                            LogManager.Info(string.Format("生成默认截图: {0}", screenshotPath));
                        }
                    }
                    catch (Exception ex)
                    {
                        LogManager.Error(string.Format("生成默认截图失败: {0}", ex.Message));
                    }
                }

                // 再生成每个碰撞对的单独截图（需要移动物体到碰撞位置）
                // 只有未从数据库加载截图时才生成
                if (!loadedScreenshotsFromDatabase && collisionData.AllCollisions?.Count > 0)
                {
                    try
                    {
                        UpdateProgress(94, string.Format("正在为 {0} 个碰撞对生成视角截图...", collisionData.AllCollisions.Count));
                        
                        // 获取当前视窗尺寸
                        var generator2 = new NavigationMapGenerator();
                        var viewportSize2 = generator2.GetCurrentViewportSize();
                        int collisionScreenshotWidth = viewportSize2.Width;
                        int collisionScreenshotHeight = viewportSize2.Height;
                        
                        int sortOrder = result.Screenshots?.Count ?? 0;
                        int successCount = 0;
                        
                        // 保存动画物体原始状态（用于截图后恢复）
                        // 对受 PathAnimationManager 控制的对象，直接复用与 ClashDetective 相同的保存/恢复主链路，
                        // 避免报告生成额外引入第二套状态语义。
                        ModelItem animatedObject = null;
                        ModelItemTransformHelper.ObjectStateSnapshot savedObjectState = null;
                        bool restoreViaAnimationManager = false;
                        
                        // 找到第一个有位置信息的碰撞来获取动画物体
                        foreach (var c in collisionData.AllCollisions)
                        {
                            if (c.Item1 != null && c.HasPositionInfo)
                            {
                                animatedObject = c.Item1;
                                var pam = PathAnimationManager.GetInstance();
                                restoreViaAnimationManager = pam != null && pam.ControlsAnimatedObject(animatedObject);

                                if (restoreViaAnimationManager)
                                {
                                    pam.SaveObjectState(animatedObject);
                                    LogManager.Info(string.Format("已通过动画主链路保存物体状态: {0}", animatedObject.DisplayName));
                                }
                                else
                                {
                                    savedObjectState = CollisionSceneHelper.SaveAnimatedObjectState(animatedObject);
                                }
                                break;
                            }
                        }
                        
                        for (int i = 0; i < collisionData.AllCollisions.Count; i++)
                        {
                            var collision = collisionData.AllCollisions[i];
                            try
                            {
                                // 使用通用方法移动物体到碰撞位置并聚焦
                                CollisionSceneHelper.MoveToCollisionAndFocus(collision, animatedObject);
                                
                                // 生成截图
                                string screenshotPath = PathHelper.GenerateSceneScreenshotToDirectory(
                                    pathDir, "collision", collisionScreenshotWidth, collisionScreenshotHeight, 
                                    System.Drawing.Imaging.ImageFormat.Jpeg, string.Format("collision_{0:D3}", i + 1));
                                
                                if (screenshotPath != null)
                                {
                                    string item1Name = collision.Item1 != null ? collision.Item1.DisplayName : "物体1";
                                    string item2Name = collision.Item2 != null ? collision.Item2.DisplayName : "物体2";
                                    string description = string.Format("碰撞对 {0}/{1}: {2} vs {3}", i + 1, collisionData.AllCollisions.Count, item1Name, item2Name);
                                    
                                    // 先保存到数据库获取Id
                                    int screenshotId = 0;
                                    if (pathDatabase != null && result.ResultId > 0)
                                    {
                                        try
                                        {
                                            screenshotId = pathDatabase.SaveCollisionReportScreenshot(result.ResultId, screenshotPath, "JPG", 
                                                collisionScreenshotWidth, collisionScreenshotHeight, sortOrder, description);
                                        }
                                        catch (Exception dbEx)
                                        {
                                            LogManager.Error(string.Format("保存碰撞对截图到数据库失败: {0}", dbEx.Message));
                                        }
                                    }
                                    
                                    var screenshot = new CollisionReportScreenshot
                                    {
                                        DatabaseId = screenshotId,  // 设置数据库Id
                                        FilePath = screenshotPath,
                                        Format = "JPG",
                                        Width = collisionScreenshotWidth,
                                        Height = collisionScreenshotHeight,
                                        CaptureTime = DateTime.Now,
                                        Description = description,
                                        SortOrder = sortOrder++
                                    };
                                    result.Screenshots.Add(screenshot);
                                    
                                    successCount++;
                                }
                                
                                // 截图后立即处理下一张，无需额外延迟
                            }
                            catch (Exception ex)
                            {
                                LogManager.Error(string.Format("生成碰撞对 {0} 截图失败: {1}", i + 1, ex.Message));
                            }
                        }
                        
                        // 恢复动画物体到原始状态
                        if (animatedObject != null)
                        {
                            var pam = PathAnimationManager.GetInstance();
                            if (restoreViaAnimationManager && pam != null && pam.ControlsAnimatedObject(animatedObject))
                            {
                                pam.RestoreAnimatedObjectState(animatedObject);
                                LogManager.Debug(string.Format("已通过动画主链路恢复物体状态: {0}", animatedObject.DisplayName));
                            }
                            else
                            {
                                CollisionSceneHelper.RestoreAnimatedObjectState(animatedObject, savedObjectState);
                            }
                        }
                        
                        LogManager.Info(string.Format("已生成 {0}/{1} 个碰撞对视角截图", successCount, collisionData.AllCollisions.Count));
                    }
                    catch (Exception ex)
                    {
                        LogManager.Error(string.Format("生成碰撞对视角截图失败: {0}", ex.Message));
                    }
                }

                // 恢复原始视角
                if (originalViewpoint != null)
                {
                    try
                    {
                        ViewpointHelper.RestoreViewpoint(originalViewpoint);
                        LogManager.Info("原始视角已恢复");
                    }
                    catch (Exception ex)
                    {
                        LogManager.Error($"恢复原始视角失败: {ex.Message}");
                    }
                }

                UpdateProgress(100, "报告生成完成");

                // 显示报告（UI线程），根据参数决定是否弹窗
                if (_parameters.ShowDialog)
                {
                    ShowReport(result);
                }

                if (!_parameters.ShowDialog)
                {
                    try
                    {
                        string htmlPath = Utils.CollisionReportHtmlGenerator.AutoSaveHtmlReport(result);
                        if (!string.IsNullOrEmpty(htmlPath))
                        {
                            LogManager.Info($"HTML报告已自动导出: {htmlPath}");
                        }
                    }
                    catch (Exception ex)
                    {
                        LogManager.Error($"自动导出HTML报告失败: {ex.Message}");
                        // HTML导出失败不影响报告生成
                    }
                }
            }
            catch (OperationCanceledException)
            {
                return PathPlanningResult.Failure("报告生成被取消");
            }
            catch (Exception ex)
            {
                LogManager.Error($"生成碰撞报告失败: {ex.Message}");
                return PathPlanningResult.Failure($"报告生成失败: {ex.Message}");
            }

            result.GenerationTimeMs = (long)(DateTime.UtcNow - startTime).TotalMilliseconds;

            var message = result.TotalCollisions > 0 ?
                $"碰撞报告生成完成：发现 {result.TotalCollisions} 个碰撞" :
                "碰撞报告生成完成：未发现碰撞";

            return PathPlanningResult<CollisionReportResult>.Success(result, message);
        }

        private static Point3D GetAnimatedObjectReportedPosition(ModelItem animatedObject, PathAnimationManager pam)
        {
            if (animatedObject == null)
            {
                return new Point3D(0, 0, 0);
            }

            if (pam != null && pam.ControlsAnimatedObject(animatedObject))
            {
                return pam.GetObjectCurrentPosition(animatedObject).Position;
            }

            var bounds = animatedObject.BoundingBox();
            return bounds?.Center ?? new Point3D(0, 0, 0);
        }

        

        /// <summary>
        /// 收集所有碰撞数据及统计信息
        /// </summary>
        private CollisionDataResult CollectAllCollisionData(string targetTestName = null)
        {
            var result = new CollisionDataResult();
            var allCollisions = new List<CollisionResult>();

            try
            {
                LogManager.Info("开始收集所有碰撞数据及统计信息...");

                var clashIntegration = ClashDetectiveIntegration.Instance;
                if (clashIntegration == null)
                {
                    throw new InvalidOperationException("无法获取ClashDetectiveIntegration实例");
                }

                // 从动画管理器获取当前路径名称
                var animationManager = Core.Animation.PathAnimationManager.GetInstance();
                var currentPathName = animationManager?.PathName;
                
                // 如果未提供targetTestName，尝试从字段获取
                if (string.IsNullOrEmpty(targetTestName))
                {
                    targetTestName = _specificTestName ?? clashIntegration?.CurrentTestName;
                }

                if (string.IsNullOrEmpty(targetTestName))
                {
                    throw new InvalidOperationException("无法确定测试名称，请先运行碰撞检测或选择历史记录");
                }

                // 获取碰撞结果（先检查缓存，没有则从数据库加载）
                var testCollisionsRaw = clashIntegration.GetCurrentPathClashResults(targetTestName);

                if (testCollisionsRaw == null || testCollisionsRaw.Count == 0)
                {
                    LogManager.Info($"测试 '{targetTestName}' 没有碰撞结果，返回空数据");
                    result.AllCollisions = allCollisions;
                    result.ClashDetectiveCollisionCount = 0;
                    result.AnimationCollisions = 0;
                    result.UniqueCollidedObjects = new HashSet<string>();
                    result.BoundingBoxTestCount = 0;
                    result.MovingObjectInfo = "无碰撞";
                    return result;
                }

                LogManager.Info($"从缓存获取ClashDetective结果: {testCollisionsRaw.Count}个碰撞，测试名称：{targetTestName}");

                // 直接使用缓存中的CollisionResult对象（已经过复合对象处理和去重）
                allCollisions.AddRange(testCollisionsRaw);

                // 统计碰撞总数
                result.ClashDetectiveCollisionCount = testCollisionsRaw.Count;
                LogManager.Debug($"测试 '{targetTestName}' 包含 {testCollisionsRaw.Count} 个碰撞");

                // 统计被撞物体（缓存中已经是复合对象，不需要再去重）
                var nameCountDict = new Dictionary<string, int>();
                var uniqueCollidedObjectsList = new List<string>();

                foreach (var collision in testCollisionsRaw)
                {
                    if (collision.Item2 != null)
                    {
                        // Item2已经是容器对象（在创建CollisionResult时已用FindNamedParentContainer处理）
                        var item2Name = ModelItemAnalysisHelper.GetSafeDisplayName(collision.Item2) ?? "未知对象";

                        // 为相同名称的对象添加编号区分
                        if (nameCountDict.ContainsKey(item2Name))
                        {
                            nameCountDict[item2Name]++;
                            uniqueCollidedObjectsList.Add($"{item2Name} #{nameCountDict[item2Name]}");
                        }
                        else
                        {
                            nameCountDict[item2Name] = 1;
                            uniqueCollidedObjectsList.Add(item2Name);
                        }
                    }
                }

                result.AllCollisions = allCollisions;
                result.UniqueCollidedObjects = new HashSet<string>(uniqueCollidedObjectsList);
                result.BoundingBoxTestCount = 0;

                // 动画碰撞数量已弃用，始终设为0（预计算碰撞数现在作为参数传递）
                result.AnimationCollisions = 0;

                // 从碰撞结果的Item1中获取运动构件信息
                if (allCollisions.Count > 0 && allCollisions[0].Item1 != null)
                {
                    // Item1已经是容器对象（在创建CollisionResult时已用FindNamedParentContainer处理）
                    var movingItemName = ModelItemAnalysisHelper.GetSafeDisplayName(allCollisions[0].Item1) ?? "未知运动构件";
                    result.MovingObjectInfo = $"运动构件: {movingItemName}";
                }
                else
                {
                    result.MovingObjectInfo = "运动构件: 未知";
                }

                LogManager.Info($"收集完成 - Clash Detective权威结果: {result.ClashDetectiveCollisionCount}个, 碰撞对象: {allCollisions.Count}个, 被撞构件: {uniqueCollidedObjectsList.Count}个");

                return result;
            }
            catch (Exception ex)
            {
                LogManager.Error($"收集碰撞数据失败: {ex.Message}");
                result.AllCollisions = allCollisions;
                return result;
            }
        }

        /// <summary>
        /// 从数据库获取路径名称（同步方法，避免在主线程中使用await造成死锁）
        /// </summary>
        private string GetPathNameFromDatabase(string testName)
        {
            var pathDatabase = PathPlanningManager.Instance?.GetPathDatabase();
            if (pathDatabase == null)
            {
                LogManager.Warning("无法获取PathDatabase实例");
                return null;
            }

            try
            {
                var testInfo = pathDatabase.GetDetectionResultByTestName(testName);
                if (testInfo != null)
                {
                    // 通过 RouteId 获取路径名称
                    var route = pathDatabase.GetPathRouteSync(testInfo.RouteId);
                    return route?.Name;
                }
                return null;
            }
            catch (Exception ex)
            {
                LogManager.Error($"从数据库获取路径名称失败: {ex.Message}");
                return null;
            }
        }

        /// <summary>
        /// 从数据库获取测试信息（优先使用检测记录ID）
        /// </summary>
        private CollisionDetectionRecord GetTestInfoFromDatabase()
        {
            var pathDatabase = PathPlanningManager.Instance?.GetPathDatabase();
            if (pathDatabase == null)
            {
                LogManager.Warning("无法获取PathDatabase实例");
                return null;
            }

            // 优先使用检测记录ID查询
            if (_detectionRecordId.HasValue)
            {
                try
                {
                    var record = pathDatabase.GetDetectionResultById(_detectionRecordId.Value);
                    if (record != null)
                    {
                        LogManager.Info($"使用检测记录ID查询成功: Id={_detectionRecordId}");
                        return record;
                    }
                }
                catch (Exception ex)
                {
                    LogManager.Error($"使用ID查询检测记录失败: {ex.Message}");
                }
            }

            return null;
        }

        /// <summary>
        /// 从数据库获取测试信息（按测试名称查询，作为后备）
        /// </summary>
        private CollisionDetectionRecord GetTestInfoFromDatabaseByName(string testName)
        {
            var pathDatabase = PathPlanningManager.Instance?.GetPathDatabase();
            if (pathDatabase == null)
            {
                LogManager.Warning("无法获取PathDatabase实例");
                return null;
            }

            if (string.IsNullOrEmpty(testName))
            {
                return null;
            }

            try
            {
                return pathDatabase.GetDetectionResultByTestName(testName);
            }
            catch (Exception ex)
            {
                LogManager.Error($"从数据库获取测试信息失败: {ex.Message}");
                return null;
            }
        }

        /// <summary>
        /// 生成报告内容
        /// </summary>
        private string GenerateReportContent(CollisionDataResult collisionData, 
            CollisionReportParameters.ReportType reportType, bool includeDetails)
        {
            var report = new StringBuilder();
            var now = DateTime.Now;
            var collisions = collisionData.AllCollisions;

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

            // 运动构件信息（原运动物体信息）
            if (!string.IsNullOrEmpty(collisionData.MovingObjectInfo))
            {
                var movingInfo = collisionData.MovingObjectInfo.Replace("运动对象", "运动构件");
                report.AppendLine($"{movingInfo}");
            }
            report.AppendLine();

            // 总体统计
            report.AppendLine("=== 总体统计 ===");

            report.AppendLine($"总碰撞数: {collisionData.ClashDetectiveCollisionCount}个");
            report.AppendLine($"碰撞构件: {collisionData.UniqueCollidedObjects.Count}个");
            report.AppendLine();

            // 碰撞构件清单（新增）
            if (collisionData.UniqueCollidedObjects?.Count > 0)
            {
                report.AppendLine("=== 碰撞构件清单 ===");
                int index = 1;
                foreach (var objName in collisionData.UniqueCollidedObjects.OrderBy(x => x).Take(20)) // 限制显示前20个
                {
                    report.AppendLine($"  {index}. {objName}");
                    index++;
                }
                if (collisionData.UniqueCollidedObjects.Count > 20)
                {
                    report.AppendLine($"  ... 还有 {collisionData.UniqueCollidedObjects.Count - 20} 个构件");
                }
                report.AppendLine();
            }

            // 详细信息
            if (includeDetails && collisions.Count > 0)
            {
                report.AppendLine("=== 详细碰撞信息 ===");
                
                report.AppendLine("--- 碰撞详情 ---");
                foreach (var collision in collisions.Take(10)) // 限制显示数量
                {
                    AppendCollisionDetail(report, collision);
                }
                if (collisions.Count > 10)
                {
                    report.AppendLine($"... 还有 {collisions.Count - 10} 个碰撞未显示");
                }
                report.AppendLine();
            }

            // 建议和结论
            report.AppendLine("=== 建议与结论 ===");
            if (collisions.Count == 0)
            {
                report.AppendLine("✅ 未发现碰撞问题，路径规划良好。");
            }
            else
            {
                report.AppendLine($"⚠️ 发现 {collisions.Count} 个碰撞问题，建议采取以下措施：");
                report.AppendLine("   1. 调整路径规划，避开碰撞区域");
                report.AppendLine("   2. 检查物体尺寸和安全边距设置");
                report.AppendLine("   3. 考虑增加临时障碍物标记");
                report.AppendLine("   4. 重新评估物流流程设计");
                
                report.AppendLine("   5. 建议进行更详细的碰撞检测分析");
            }

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

            return report.ToString();
        }

        /// <summary>
        /// 添加碰撞详细信息到报告中
        /// </summary>
        private void AppendCollisionDetail(StringBuilder report, CollisionResult collision)
        {
            var item1Name = collision.Item1?.DisplayName ?? "未知对象";
            var item2Name = collision.Item2?.DisplayName ?? "未知对象";
            
            // 转换距离单位为米
            var distanceInMeters = ConvertDistanceToMeters(collision.Distance);
            
            report.AppendLine($"• {item1Name} ↔ {item2Name}");
            report.AppendLine($"  状态: {GetStatusName(collision.Status)}, 距离: {distanceInMeters:F3}m");
            
            // 转换位置坐标单位为米
            var centerInMeters = ConvertPointToMeters(collision.Center);
            report.AppendLine($"  位置: ({centerInMeters.X:F2}, {centerInMeters.Y:F2}, {centerInMeters.Z:F2})m");
            report.AppendLine($"  GUID: {collision.ClashGuid}");
            report.AppendLine();
        }

        /// <summary>
        /// 获取报告类型名称
        /// </summary>
        private string GetReportTypeName(CollisionReportParameters.ReportType reportType)
        {
            switch (reportType)
            {
                case CollisionReportParameters.ReportType.Animation:
                    return "动画碰撞报告";
                case CollisionReportParameters.ReportType.Independent:
                    return "独立检测报告";
                case CollisionReportParameters.ReportType.Comprehensive:
                    return "综合碰撞报告";
                default:
                    return "未知类型";
            }
        }

        /// <summary>
        /// 获取碰撞状态名称
        /// </summary>
        private string GetStatusName(ClashResultStatus status)
        {
            switch (status)
            {
                case ClashResultStatus.New:
                    return "新发现";
                case ClashResultStatus.Active:
                    return "活跃";
                case ClashResultStatus.Reviewed:
                    return "已审阅";
                case ClashResultStatus.Approved:
                    return "已批准";
                case ClashResultStatus.Resolved:
                    return "已解决";
                default:
                    return "未知";
            }
        }

        /// <summary>
        /// 显示报告
        /// </summary>
        private void ShowReport(CollisionReportResult reportResult)
        {
            try
            {
                // 确保在UI线程中执行
                if (System.Windows.Application.Current != null)
                {
                    if (System.Windows.Application.Current.Dispatcher.CheckAccess())
                    {
                        // 已在UI线程上
                        ShowReportInternal(reportResult);
                    }
                    else
                    {
                        // 切换到UI线程
                        System.Windows.Application.Current.Dispatcher.Invoke(() => ShowReportInternal(reportResult));
                    }
                }
                else
                {
                    // 如果WPF Application不存在，回退到原来的方式
                    ShowReportInternal(reportResult);
                }
            }
            catch (Exception ex)
            {
                LogManager.Error($"显示报告失败: {ex.Message}");
                System.Windows.MessageBox.Show($"显示报告失败: {ex.Message}", "错误", 
                    System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error);
            }
        }

        /// <summary>
        /// 内部报告显示方法
        /// </summary>
        private void ShowReportInternal(CollisionReportResult reportResult)
        {
            try
            {
                // 使用新的WPF碰撞报告对话框
                var reportDialog = CollisionReportDialog.ShowReport(reportResult);
                
                if (reportDialog != null)
                {
                    LogManager.Info("WPF碰撞报告对话框显示成功");
                }
            }
            catch (Exception ex)
            {
                LogManager.Error($"显示WPF报告对话框失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 创建综合报告命令
        /// </summary>
        /// <param name="routeId">路径ID（用于视角调整），如果为空则使用全局CurrentRoute</param>
        /// <param name="hasHighlighted">碰撞结果是否已经被高亮</param>
        /// <param name="showDialog">是否显示报告窗口（批处理模式设为false）</param>
        public static GenerateCollisionReportCommand CreateComprehensive(string routeId = null, bool hasHighlighted = false, bool showDialog = true)
        {
            // 如果没有传入路径ID，则从全局CurrentRoute获取
            if (string.IsNullOrEmpty(routeId))
            {
                try
                {
                    var currentRoute = PathPlanningManager.Instance?.CurrentRoute;
                    if (currentRoute != null)
                    {
                        routeId = currentRoute.Id;
                    }
                }
                catch (Exception ex)
                {
                    LogManager.Error($"获取当前路径ID失败: {ex.Message}");
                }
            }

            return new GenerateCollisionReportCommand(new CollisionReportParameters
            {
                Type = CollisionReportParameters.ReportType.Comprehensive,
                IncludeDetails = true,
                HasHighlighted = hasHighlighted,
                RouteId = routeId,
                ShowDialog = showDialog
            });
        }

        /// <summary>
        /// 将距离转换为米
        /// </summary>
        private double ConvertDistanceToMeters(double distance)
        {
            try
            {
                var conversionFactor = UnitsConverter.GetUnitsToMetersConversionFactor();
                return distance * conversionFactor;
            }
            catch (Exception ex)
            {
                LogManager.Warning($"距离单位转换失败: {ex.Message}，使用原始值");
                return distance;
            }
        }

        /// <summary>
        /// 将3D点坐标转换为米
        /// </summary>
        private Point3D ConvertPointToMeters(Point3D point)
        {
            try
            {
                var conversionFactor = UnitsConverter.GetUnitsToMetersConversionFactor();
                return new Point3D(
                    point.X * conversionFactor,
                    point.Y * conversionFactor,
                    point.Z * conversionFactor
                );
            }
            catch (Exception ex)
            {
                LogManager.Warning($"坐标单位转换失败: {ex.Message}，使用原始值");
                return point;
            }
        }
    }
}
