using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Autodesk.Navisworks.Api;
using NavisworksTransport.Commands;

namespace NavisworksTransport.Utils
{
    /// <summary>
    /// 碰撞报告HTML生成器
    /// </summary>
    public static class CollisionReportHtmlGenerator
    {
        /// <summary>
        /// 生成HTML报告内容
        /// </summary>
        /// <param name="report">碰撞报告结果</param>
        /// <param name="htmlFilePath">HTML文件路径（用于计算截图相对路径）</param>
        /// <returns>HTML内容</returns>
        public static string GenerateHtmlReport(CollisionReportResult report, string htmlFilePath)
        {
            if (report == null)
            {
                throw new ArgumentNullException(nameof(report));
            }

            var html = new StringBuilder();
            var now = DateTime.Now;

            // HTML头部和样式
            html.AppendLine("<!DOCTYPE html>");
            html.AppendLine("<html><head>");
            html.AppendLine("<meta charset='UTF-8'>");
            html.AppendLine("<title>NavisworksTransport 碰撞检测报告</title>");
            html.AppendLine("<style>");
            html.AppendLine("body { font-family: 'Microsoft YaHei', Arial, sans-serif; margin: 20px; line-height: 1.6; }");
            html.AppendLine("h1 { color: #2c5aa0; text-align: center; border-bottom: 2px solid #2c5aa0; padding-bottom: 10px; }");
            html.AppendLine("h2 { color: #2c5aa0; margin-top: 25px; }");
            html.AppendLine(".summary { background: #f8fbff; padding: 15px; border-radius: 8px; margin: 15px 0; border-left: 4px solid #2c5aa0; }");
            html.AppendLine(".stats-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 15px; margin: 15px 0; }");
            html.AppendLine(".stat-item { background: white; padding: 15px; border-radius: 6px; border: 1px solid #ddd; text-align: center; }");
            html.AppendLine(".stat-label { font-size: 12px; color: #666; margin-bottom: 5px; }");
            html.AppendLine(".stat-value { font-size: 18px; font-weight: bold; color: #2c5aa0; }");
            html.AppendLine(".moving-object { background: #f0f8ff; padding: 15px; border-radius: 8px; text-align: center; margin: 15px 0; border: 1px solid #b0d4f1; }");
            html.AppendLine(".collided-list { background: #fdf2f2; padding: 15px; border-radius: 8px; margin: 15px 0; max-height: 200px; overflow-y: auto; border: 1px solid #f5c6c6; }");
            html.AppendLine(".collided-list .list-item { margin: 5px 0; padding: 5px; border-left: 3px solid #dc3545; padding-left: 10px; color: #721c24; font-weight: 500; }");
            html.AppendLine(".excluded-list { background: #fef9e7; padding: 15px; border-radius: 8px; margin: 15px 0; max-height: 250px; overflow-y: auto; border: 1px solid #f9e79f; }");
            html.AppendLine(".excluded-list .list-item { margin: 5px 0; padding: 5px; border-left: 3px solid #f9e79f; padding-left: 10px; color: #856404; }");
            html.AppendLine(".recommendation { background: #fff3cd; padding: 15px; border-radius: 8px; border-left: 4px solid #ffc107; margin: 15px 0; }");
            html.AppendLine(".collision-item { background: white; margin: 10px 0; padding: 15px; border-radius: 6px; border: 1px solid #eee; }");
            html.AppendLine(".collision-title { font-weight: bold; color: #333; margin-bottom: 8px; }");
            html.AppendLine(".collision-status { display: inline-block; padding: 3px 8px; border-radius: 12px; font-size: 11px; color: white; margin-bottom: 8px; }");
            html.AppendLine(".status-new { background-color: #ff6b6b; } .status-active { background-color: #ffa500; }");
            html.AppendLine(".status-reviewed { background-color: #87ceeb; } .status-approved { background-color: #98fb98; } .status-resolved { background-color: #90ee90; }");
            html.AppendLine(".screenshot-section { margin: 20px 0; padding: 15px; background-color: #f5f5f5; border-radius: 5px; }");
            html.AppendLine(".screenshot-container { text-align: center; }");
            html.AppendLine(".screenshot-image { max-width: 100%; height: auto; border: 1px solid #ddd; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }");
            html.AppendLine(".screenshot-info { margin-top: 10px; font-size: 12px; color: #666; }");
            html.AppendLine("</style>");
            html.AppendLine("</head><body>");

            // 从数据库获取检测记录信息
            var (testName, testTime) = GetDetectionRecordInfo(report.ResultId);

            // 报告标题
            html.AppendLine($"<h1>NavisworksTransport 碰撞检测报告</h1>");
            html.AppendLine($"<p style='text-align: center; color: #666;'>生成时间: {now:yyyy年MM月dd日 HH:mm:ss}</p>");
            html.AppendLine($"<p style='text-align: center; color: #666;'>报告类型: 综合报告</p>");

            // 检测记录信息
            html.AppendLine("<div class='summary'>");
            html.AppendLine("<h2>检测记录</h2>");
            html.AppendLine("<div class='stats-grid' style='grid-template-columns: repeat(2, 1fr);'>");
            html.AppendLine("<div class='stat-item'>");
            html.AppendLine("<div class='stat-label'>测试名称</div>");
            html.AppendLine($"<div class='stat-value'>{testName ?? "未命名"}</div>");
            html.AppendLine("</div>");
            html.AppendLine("<div class='stat-item'>");
            html.AppendLine("<div class='stat-label'>检测时间</div>");
            html.AppendLine($"<div class='stat-value'>{testTime}</div>");
            html.AppendLine("</div>");
            html.AppendLine("</div>");
            html.AppendLine("</div>");

            // 总体统计
            html.AppendLine("<div class='summary'>");
            html.AppendLine("<h2>总体统计</h2>");
            html.AppendLine("<div class='stats-grid'>");
            html.AppendLine("<div class='stat-item'>");
            html.AppendLine("<div class='stat-label'>总碰撞数</div>");
            html.AppendLine($"<div class='stat-value'>{report.TotalCollisions}</div>");
            html.AppendLine("</div>");
            html.AppendLine("<div class='stat-item'>");
            html.AppendLine("<div class='stat-label'>碰撞构件</div>");
            html.AppendLine($"<div class='stat-value'>{report.UniqueCollidedObjectsCount}个</div>");
            html.AppendLine("</div>");
            html.AppendLine("<div class='stat-item'>");
            html.AppendLine("<div class='stat-label'>检测点</div>");
            html.AppendLine($"<div class='stat-value'>{report.AnimationCollisions}个</div>");
            html.AppendLine("</div>");
            html.AppendLine("</div>");
            html.AppendLine("</div>");

            // 动画参数
            html.AppendLine("<h2>动画参数</h2>");
            html.AppendLine("<div class='stats-grid'>");
            html.AppendLine("<div class='stat-item'>");
            html.AppendLine("<div class='stat-label'>帧率</div>");
            html.AppendLine($"<div class='stat-value'>{report.FrameRate} FPS</div>");
            html.AppendLine("</div>");
            html.AppendLine("<div class='stat-item'>");
            html.AppendLine("<div class='stat-label'>时长</div>");
            html.AppendLine($"<div class='stat-value'>{report.Duration:F1} 秒</div>");
            html.AppendLine("</div>");
            html.AppendLine("<div class='stat-item'>");
            html.AppendLine("<div class='stat-label'>检测容差</div>");
            html.AppendLine($"<div class='stat-value'>{report.DetectionTolerance:F2} 米</div>");
            html.AppendLine("</div>");
            html.AppendLine("</div>");

            // 碰撞场景截图（支持多张）
            var validScreenshots = report.Screenshots?.Where(s => !string.IsNullOrEmpty(s.FilePath) && File.Exists(s.FilePath)).ToList();
            if (validScreenshots?.Count > 0)
            {
                html.AppendLine("<h2>碰撞场景截图</h2>");
                
                // 多张截图样式 - 大图+缩略图横排交互式布局
                if (validScreenshots?.Count > 1)
                {
                    html.AppendLine("<style>");
                    // 主图区域样式
                    html.AppendLine(".main-image-container { background: white; padding: 15px; border-radius: 6px; border: 1px solid #ddd; margin-bottom: 15px; }");
                    html.AppendLine(".main-image { width: 100%; height: auto; border-radius: 4px; cursor: pointer; transition: transform 0.2s; }");
                    html.AppendLine(".main-image:hover { transform: scale(1.01); }");
                    html.AppendLine(".main-image-info { margin-top: 10px; font-size: 13px; color: #666; text-align: center; }");
                    // 缩略图横排样式
                    html.AppendLine(".thumbnail-row { display: flex; gap: 10px; overflow-x: auto; padding: 10px; background: #f9f9f9; border-radius: 6px; border: 1px solid #e0e0e0; }");
                    html.AppendLine(".thumbnail-item { flex: 0 0 auto; width: 120px; cursor: pointer; transition: all 0.2s; }");
                    html.AppendLine(".thumbnail-item img { width: 100%; height: 80px; object-fit: cover; border-radius: 4px; border: 2px solid transparent; transition: all 0.2s; }");
                    html.AppendLine(".thumbnail-item:hover img { border-color: #87ceeb; transform: scale(1.05); }");
                    html.AppendLine(".thumbnail-item.active img { border-color: #2B579A; box-shadow: 0 0 6px rgba(43,87,154,0.4); }");
                    html.AppendLine(".thumbnail-label { font-size: 11px; color: #666; text-align: center; margin-top: 4px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }");
                    html.AppendLine(".thumbnail-item.active .thumbnail-label { color: #2B579A; font-weight: bold; }");
                    html.AppendLine("</style>");
                    
                    // 主图区域
                    html.AppendLine("<div class='main-image-container'>");
                    html.AppendLine("<img id='mainImage' src=\"\" alt=\"主图\" class=\"main-image\" onclick=\"window.open(this.src)\">");
                    html.AppendLine("<div id='mainImageInfo' class='main-image-info'></div>");
                    html.AppendLine("</div>");
                    
                    // 缩略图横排
                    html.AppendLine("<div class='thumbnail-row' id='thumbnailRow'>");
                    int index = 1;
                    foreach (var screenshot in validScreenshots.OrderBy(s => s.SortOrder))
                    {
                        string relativePath = PathHelper.GetRelativePath(htmlFilePath, screenshot.FilePath);
                        string label = string.IsNullOrEmpty(screenshot.Description) ? $"截图 {index}" : screenshot.Description;
                        string desc = screenshot.Description ?? $"截图 {index}";
                        html.AppendLine($"<div class='thumbnail-item' data-src=\"{relativePath}\" data-index=\"{index}\" data-width=\"{screenshot.Width}\" data-height=\"{screenshot.Height}\" data-time=\"{screenshot.CaptureTime:yyyy-MM-dd HH:mm}\" data-desc=\"{desc}\" onclick=\"selectImage(this)\">");
                        html.AppendLine($"<img src=\"{relativePath}\" alt=\"{label}\">");
                        html.AppendLine($"<div class='thumbnail-label'>{label}</div>");
                        html.AppendLine("</div>");
                        index++;
                    }
                    html.AppendLine("</div>");
                    
                    // JavaScript交互
                    html.AppendLine("<script>");
                    html.AppendLine("function selectImage(element) {");
                    html.AppendLine("    // 更新选中状态");
                    html.AppendLine("    document.querySelectorAll('.thumbnail-item').forEach(function(el) { el.classList.remove('active'); });");
                    html.AppendLine("    element.classList.add('active');");
                    html.AppendLine("    // 更新主图");
                    html.AppendLine("    var mainImage = document.getElementById('mainImage');");
                    html.AppendLine("    mainImage.src = element.getAttribute('data-src');");
                    html.AppendLine("    // 更新主图信息");
                    html.AppendLine("    var desc = element.getAttribute('data-desc');");
                    html.AppendLine("    var width = element.getAttribute('data-width');");
                    html.AppendLine("    var height = element.getAttribute('data-height');");
                    html.AppendLine("    var time = element.getAttribute('data-time');");
                    html.AppendLine("    document.getElementById('mainImageInfo').innerHTML = desc + ' &bull; ' + width + 'x' + height + ' &bull; ' + time;");
                    html.AppendLine("}");
                    html.AppendLine("// 初始化显示第一张图");
                    html.AppendLine("document.addEventListener('DOMContentLoaded', function() {");
                    html.AppendLine("    var firstThumb = document.querySelector('.thumbnail-item');");
                    html.AppendLine("    if (firstThumb) selectImage(firstThumb);");
                    html.AppendLine("});");
                    html.AppendLine("</script>");
                }
                else if (validScreenshots?.Count == 1)
                {
                    // 单张截图样式
                    var screenshot = validScreenshots.First();
                    
                    html.AppendLine("<div class='screenshot-section'>");
                    string relativePath = PathHelper.GetRelativePath(htmlFilePath, screenshot.FilePath);
                    html.AppendLine("<div class='screenshot-container'>");
                    html.AppendLine($"<img src=\"{relativePath}\" alt=\"碰撞场景截图\" class=\"screenshot-image\"/>");
                    html.AppendLine("<div class='screenshot-info'>");
                    html.AppendLine($"<p>分辨率: {screenshot.Width} x {screenshot.Height}</p>");
                    html.AppendLine($"<p>格式: {screenshot.Format}</p>");
                    html.AppendLine("</div>");
                    html.AppendLine("</div>");
                    html.AppendLine("</div>");
                }
            }

            // 运动构件信息
            if (!string.IsNullOrEmpty(report.MovingObjectInfo))
            {
                html.AppendLine("<h2>运动构件信息</h2>");
                html.AppendLine("<div class='moving-object'>");
                html.AppendLine($"<strong>🚛 {report.MovingObjectInfo}</strong>");
                html.AppendLine("</div>");
            }

            // 碰撞构件清单
            if (report.CollidedObjectsList?.Count > 0)
            {
                html.AppendLine("<h2>碰撞构件清单</h2>");
                html.AppendLine("<div class='collided-list'>");
                html.AppendLine($"<p style='margin: 0 0 10px 0; color: #721c24;'><strong>⚠️ 发现 {report.UniqueCollidedObjectsCount} 个碰撞构件</strong></p>");
                int index = 1;
                foreach (var objName in report.CollidedObjectsList.Take(50)) // 限制显示前50个
                {
                    html.AppendLine($"<div class='list-item'>{index}. {objName}</div>");
                    index++;
                }
                if (report.CollidedObjectsList.Count > 50)
                {
                    html.AppendLine($"<div class='list-item'><em>... 还有 {report.CollidedObjectsList.Count - 50} 个构件</em></div>");
                }
                html.AppendLine("</div>");
            }

            // 排除对象清单
            if (report.ExcludedObjects?.Count > 0)
            {
                html.AppendLine("<h2>排除对象清单</h2>");
                html.AppendLine("<div class='excluded-list'>");
                html.AppendLine($"<p style='margin: 0 0 10px 0; color: #856404;'><strong>🚫 以下 {report.ExcludedObjects.Count} 个对象被排除在碰撞检测之外</strong></p>");
                int index = 1;
                foreach (var excludedObj in report.ExcludedObjects.Take(30)) // 限制显示前30个
                {
                    string displayName = !string.IsNullOrEmpty(excludedObj.DisplayName) ? excludedObj.DisplayName : excludedObj.ObjectName ?? "未知对象";
                    string reason = !string.IsNullOrEmpty(excludedObj.Reason) ? $"原因: {excludedObj.Reason}" : "无";
                    string time = excludedObj.ExcludedTime > DateTime.MinValue ? $"时间: {excludedObj.ExcludedTime:yyyy-MM-dd HH:mm}" : "";
                    html.AppendLine($"<div class='list-item'>");
                    html.AppendLine($"<strong>{index}. {displayName}</strong>");
                    html.AppendLine($"<span style='color: #856404; font-size: 11px; margin-left: 10px;'>({reason}{(!string.IsNullOrEmpty(time) ? " | " + time : "")})</span>");
                    html.AppendLine("</div>");
                    index++;
                }
                if (report.ExcludedObjects.Count > 30)
                {
                    html.AppendLine($"<div class='list-item'><em>... 还有 {report.ExcludedObjects.Count - 30} 个排除对象</em></div>");
                }
                html.AppendLine("</div>");
            }

            // 总结与建议
            html.AppendLine("<h2>总结与建议</h2>");
            html.AppendLine("<div class='recommendation'>");
            
            // 根据碰撞数量生成总结信息
            string summaryMessage;
            if (report.TotalCollisions == 0)
            {
                summaryMessage = "✅ 未检测到碰撞，路径规划合理，可以安全通行。";
            }
            else if (report.TotalCollisions <= 5)
            {
                summaryMessage = $"⚠️ 检测到 {report.TotalCollisions} 个碰撞，建议优化路径或调整构件位置。";
            }
            else
            {
                summaryMessage = $"🔴 检测到 {report.TotalCollisions} 个碰撞，存在严重安全隐患，必须立即处理。";
            }
            
            html.AppendLine($"<p><strong>{summaryMessage}</strong></p>");
            
            // 生成建议措施
            html.AppendLine("<p><strong>建议措施：</strong></p>");
            html.AppendLine("<ul>");
            
            if (report.TotalCollisions == 0)
            {
                html.AppendLine("<li>保持当前路径规划方案</li>");
                html.AppendLine("<li>定期检查构件位置变化</li>");
                html.AppendLine("<li>建议进行现场复核确认</li>");
            }
            else
            {
                html.AppendLine("<li>检查碰撞构件的实际位置和尺寸</li>");
                html.AppendLine("<li>优化路径规划，避开碰撞区域</li>");
                html.AppendLine("<li>调整构件位置或尺寸</li>");
                html.AppendLine("<li>考虑增加安全间隙</li>");
                html.AppendLine("<li>进行现场勘察确认</li>");
            }
            
            html.AppendLine("</ul>");
            html.AppendLine("</div>");

            // 详细碰撞信息（前10个）
            if (report.AllCollisions?.Count > 0)
            {
                html.AppendLine("<h2>碰撞详情</h2>");
                int collisionIndex = 1;
                foreach (var collision in report.AllCollisions.Take(10))
                {
                    html.AppendLine("<div class='collision-item'>");
                    
                    // 生成碰撞标题
                    string item1Name = collision.Item1 != null ? ModelItemAnalysisHelper.GetSafeDisplayName(collision.Item1) : "未知对象";
                    string item2Name = collision.Item2 != null ? ModelItemAnalysisHelper.GetSafeDisplayName(collision.Item2) : "未知对象";
                    html.AppendLine($"<div class='collision-title'>{collisionIndex}. {item1Name} ↔ {item2Name}</div>");
                    
                    // 全路径
                    string item1Path = GetModelItemFullPath(collision.Item1);
                    string item2Path = GetModelItemFullPath(collision.Item2);
                    html.AppendLine($"<p style='font-size: 11px; color: #666; margin: 3px 0;'>🚛 <strong>运动物体:</strong> {item1Path}</p>");
                    html.AppendLine($"<p style='font-size: 11px; color: #666; margin: 3px 0;'>💥 <strong>被撞对象:</strong> {item2Path}</p>");
                    
                    // 碰撞位置
                    if (collision.Center != null)
                    {
                        html.AppendLine($"<p style='font-size: 11px; color: #999; margin: 3px 0;'><strong>位置:</strong> ({collision.Center.X:F2}, {collision.Center.Y:F2}, {collision.Center.Z:F2})</p>");
                    }
                    
                    html.AppendLine("</div>");
                    collisionIndex++;
                }
                if (report.AllCollisions.Count > 10)
                {
                    html.AppendLine($"<p><em>... 还有 {report.AllCollisions.Count - 10} 个碰撞未显示</em></p>");
                }
            }

            // HTML结尾
            html.AppendLine($"<hr style='margin: 30px 0;'>");
            html.AppendLine($"<p style='text-align: center; color: #999; font-size: 12px;'>报告生成完成 - {now:HH:mm:ss}</p>");
            html.AppendLine("</body></html>");

            return html.ToString();
        }

        /// <summary>
        /// 保存HTML报告到文件
        /// </summary>
        /// <param name="report">碰撞报告结果</param>
        /// <param name="htmlFilePath">HTML文件保存路径</param>
        /// <returns>是否保存成功</returns>
        public static bool SaveHtmlReport(CollisionReportResult report, string htmlFilePath)
        {
            try
            {
                // 确保目录存在
                string directory = Path.GetDirectoryName(htmlFilePath);
                if (!string.IsNullOrEmpty(directory))
                {
                    PathHelper.EnsureDirectoryExists(directory);
                }

                // 生成HTML内容
                string htmlContent = GenerateHtmlReport(report, htmlFilePath);

                // 保存到文件
                File.WriteAllText(htmlFilePath, htmlContent, System.Text.Encoding.UTF8);

                LogManager.Info($"HTML报告已保存: {htmlFilePath}");
                return true;
            }
            catch (Exception ex)
            {
                LogManager.Error($"保存HTML报告失败: {ex.Message}", ex);
                return false;
            }
        }

        /// <summary>
        /// 获取ModelItem的完整层级路径
        /// </summary>
        private static 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>
        /// 自动生成并保存HTML报告到默认目录
        /// </summary>
        /// <param name="report">碰撞报告结果</param>
        /// <returns>HTML文件路径，失败返回null</returns>
        public static string AutoSaveHtmlReport(CollisionReportResult report)
        {
            try
            {
                // 生成文件名
                string fileName = PathHelper.GenerateCollisionReportFileName(report.PathName, "html");
                
                // 获取报告目录
                string reportDir = PathHelper.GetReportDirectory();
                string htmlFilePath = Path.Combine(reportDir, fileName);

                // 保存报告
                if (SaveHtmlReport(report, htmlFilePath))
                {
                    return htmlFilePath;
                }
                
                return null;
            }
            catch (Exception ex)
            {
                LogManager.Error($"自动保存HTML报告失败: {ex.Message}", ex);
                return null;
            }
        }

        /// <summary>
        /// 从数据库获取检测记录信息
        /// </summary>
        private static (string testName, string testTime) GetDetectionRecordInfo(int resultId)
        {
            try
            {
                if (resultId <= 0)
                {
                    return (null, "未知时间");
                }

                var pathDatabase = PathPlanningManager.Instance?.GetPathDatabase();
                if (pathDatabase == null)
                {
                    return (null, "未知时间");
                }

                var record = pathDatabase.GetDetectionResultById(resultId);
                if (record != null)
                {
                    string timeStr = record.TestTime?.ToString("yyyy-MM-dd HH:mm:ss") ?? "未知时间";
                    return (record.TestName, timeStr);
                }
            }
            catch (Exception ex)
            {
                LogManager.Error($"[CollisionReportHtmlGenerator] 获取检测记录信息失败: {ex.Message}");
            }

            return (null, "未知时间");
        }
    }
}
