using System;
using System.Collections.Generic;
using System.Diagnostics;
using Autodesk.Navisworks.Api;
using g4;

namespace NavisworksTransport.PathPlanning
{
    /// <summary>
    /// Mesh SDF 测试器 - 测试 geometry4Sharp 的 MeshSignedDistanceGrid 功能
    /// 阶段 1.4：验证 Navisworks 网格到 DMesh3 的转换和 SDF 计算
    /// 注意：这是原型版本，部分API需要根据实际geometry4Sharp文档调整
    /// </summary>
    public class MeshSDFTester
    {
        /// <summary>
        /// 简单测试：验证 geometry4Sharp 是否可用
        /// </summary>
        public static void QuickLibraryTest()
        {
            LogManager.Info("=== geometry4Sharp 库可用性测试 ===");

            try
            {
                // 测试创建 DMesh3
                var mesh = new DMesh3(MeshComponents.None);
                LogManager.Info($"✅ DMesh3 创建成功");

                // 添加简单的三角形
                int v0 = mesh.AppendVertex(new Vector3d(0, 0, 0));
                int v1 = mesh.AppendVertex(new Vector3d(1, 0, 0));
                int v2 = mesh.AppendVertex(new Vector3d(0, 1, 0));
                int t0 = mesh.AppendTriangle(v0, v1, v2);

                LogManager.Info($"✅ 顶点和三角形添加成功: {mesh.VertexCount} 顶点, {mesh.TriangleCount} 三角形");

                // 测试 AABB 树
                var spatial = new DMeshAABBTree3(mesh, autoBuild: true);
                LogManager.Info($"✅ DMeshAABBTree3 创建成功");

                LogManager.Info("=== geometry4Sharp 库测试通过 ===");
            }
            catch (Exception ex)
            {
                LogManager.Error($"❌ geometry4Sharp 库测试失败: {ex.Message}");
                LogManager.Error($"堆栈跟踪: {ex.StackTrace}");
            }
        }
        /// <summary>
        /// 将 Navisworks 三角形转换为 geometry4Sharp DMesh3
        /// </summary>
        /// <param name="triangles">Navisworks 三角形集合</param>
        /// <returns>DMesh3 对象</returns>
        public static DMesh3 ConvertToDMesh3(List<Triangle3D> triangles)
        {
            var stopwatch = Stopwatch.StartNew();
            LogManager.Info("=== 开始转换 Navisworks 网格到 DMesh3 ===");

            var mesh = new DMesh3(MeshComponents.None); // 不需要法线、颜色等额外组件

            try
            {
                // 第一步：添加所有顶点（使用字典去重）
                var vertexMap = new Dictionary<string, int>();
                int vertexCount = 0;

                foreach (var triangle in triangles)
                {
                    AddVertexIfNotExists(mesh, triangle.Point1, vertexMap, ref vertexCount);
                    AddVertexIfNotExists(mesh, triangle.Point2, vertexMap, ref vertexCount);
                    AddVertexIfNotExists(mesh, triangle.Point3, vertexMap, ref vertexCount);
                }

                LogManager.Info($"顶点添加完成: {mesh.VertexCount} 个顶点");

                // 第二步：添加所有三角形面
                int triangleAddedCount = 0;
                int triangleFailedCount = 0;

                foreach (var triangle in triangles)
                {
                    try
                    {
                        int v1 = GetVertexIndex(triangle.Point1, vertexMap);
                        int v2 = GetVertexIndex(triangle.Point2, vertexMap);
                        int v3 = GetVertexIndex(triangle.Point3, vertexMap);

                        if (v1 >= 0 && v2 >= 0 && v3 >= 0 && v1 != v2 && v2 != v3 && v1 != v3)
                        {
                            int tid = mesh.AppendTriangle(v1, v2, v3);
                            if (tid >= 0)
                            {
                                triangleAddedCount++;
                            }
                            else
                            {
                                triangleFailedCount++;
                            }
                        }
                        else
                        {
                            triangleFailedCount++;
                        }
                    }
                    catch (Exception ex)
                    {
                        triangleFailedCount++;
                        LogManager.Debug($"添加三角形失败: {ex.Message}");
                    }
                }

                LogManager.Info($"三角形添加完成: 成功={triangleAddedCount}, 失败={triangleFailedCount}");

                // 第三步：网格验证和修复
                if (!mesh.IsClosed())
                {
                    LogManager.Warning("网格不闭合，可能影响 SDF 计算准确性");
                }

                // 计算边界框
                var bounds = mesh.CachedBounds;
                LogManager.Info($"网格边界: Min=({bounds.Min.x:F2}, {bounds.Min.y:F2}, {bounds.Min.z:F2}), " +
                    $"Max=({bounds.Max.x:F2}, {bounds.Max.y:F2}, {bounds.Max.z:F2})");

                stopwatch.Stop();
                LogManager.Info($"=== DMesh3 转换完成 ===");
                LogManager.Info($"转换耗时: {stopwatch.ElapsedMilliseconds} ms ({stopwatch.Elapsed.TotalSeconds:F2} 秒)");
                LogManager.Info($"网格统计: 顶点={mesh.VertexCount}, 三角形={mesh.TriangleCount}, 边={mesh.EdgeCount}");
            }
            catch (Exception ex)
            {
                LogManager.Error($"转换到 DMesh3 失败: {ex.Message}");
                LogManager.Error($"堆栈跟踪: {ex.StackTrace}");
            }

            return mesh;
        }

        /// <summary>
        /// 添加顶点（如果不存在）
        /// </summary>
        private static void AddVertexIfNotExists(DMesh3 mesh, Point3D point, Dictionary<string, int> vertexMap, ref int vertexCount)
        {
            string key = GetVertexKey(point);

            if (!vertexMap.ContainsKey(key))
            {
                int vid = mesh.AppendVertex(new Vector3d(point.X, point.Y, point.Z));
                vertexMap[key] = vid;
                vertexCount++;
            }
        }

        /// <summary>
        /// 获取顶点索引
        /// </summary>
        private static int GetVertexIndex(Point3D point, Dictionary<string, int> vertexMap)
        {
            string key = GetVertexKey(point);
            return vertexMap.TryGetValue(key, out int index) ? index : -1;
        }

        /// <summary>
        /// 生成顶点键（用于去重）
        /// </summary>
        private static string GetVertexKey(Point3D point, double tolerance = 0.0001)
        {
            // 使用较高精度避免过度合并
            return $"{Math.Round(point.X / tolerance) * tolerance:F6}," +
                   $"{Math.Round(point.Y / tolerance) * tolerance:F6}," +
                   $"{Math.Round(point.Z / tolerance) * tolerance:F6}";
        }

        /// <summary>
        /// 计算签名距离场（Signed Distance Field）
        /// </summary>
        /// <param name="mesh">DMesh3 网格</param>
        /// <param name="cellSize">网格单元尺寸（模型单位）</param>
        /// <returns>MeshSignedDistanceGrid 对象</returns>
        public static MeshSignedDistanceGrid ComputeSDF(DMesh3 mesh, double cellSize)
        {
            var stopwatch = Stopwatch.StartNew();
            LogManager.Info("=== 开始计算签名距离场 (SDF) ===");

            MeshSignedDistanceGrid sdf = null;

            try
            {
                // 获取网格边界
                var bounds = mesh.CachedBounds;
                LogManager.Info($"网格边界: {bounds.Min} ~ {bounds.Max}");
                LogManager.Info($"网格尺寸: {bounds.Width:F2} × {bounds.Height:F2} × {bounds.Depth:F2} 模型单位");

                // 计算网格分辨率
                int nx = (int)Math.Ceiling(bounds.Width / cellSize);
                int ny = (int)Math.Ceiling(bounds.Height / cellSize);
                int nz = (int)Math.Ceiling(bounds.Depth / cellSize);

                LogManager.Info($"SDF 网格分辨率: {nx} × {ny} × {nz} = {nx * ny * nz:N0} 个单元");
                LogManager.Info($"单元尺寸: {cellSize:F4} 模型单位");

                // 创建 DMeshAABBTree3（空间索引树，加速距离查询）
                LogManager.Info("构建 AABB 树...");
                var spatialStopwatch = Stopwatch.StartNew();
                var spatial = new DMeshAABBTree3(mesh, autoBuild: true);
                spatialStopwatch.Stop();
                LogManager.Info($"AABB 树构建完成: {spatialStopwatch.ElapsedMilliseconds} ms");

                // 计算 SDF
                LogManager.Info("开始计算距离场...");
                sdf = new MeshSignedDistanceGrid(mesh, cellSize, spatial);
                sdf.Compute();

                stopwatch.Stop();
                LogManager.Info($"=== SDF 计算完成 ===");
                LogManager.Info($"计算耗时: {stopwatch.ElapsedMilliseconds} ms ({stopwatch.Elapsed.TotalSeconds:F2} 秒)");

                // 统计距离场信息
                AnalyzeSDF(sdf);
            }
            catch (Exception ex)
            {
                LogManager.Error($"计算 SDF 失败: {ex.Message}");
                LogManager.Error($"堆栈跟踪: {ex.StackTrace}");
            }

            return sdf;
        }

        /// <summary>
        /// 分析 SDF 统计信息（简化版本）
        /// </summary>
        private static void AnalyzeSDF(MeshSignedDistanceGrid sdf)
        {
            try
            {
                var dims = sdf.Dimensions;
                LogManager.Info($"SDF 维度: {dims.x} × {dims.y} × {dims.z}");
                LogManager.Info("SDF 创建成功，具体距离查询API需要进一步研究");
            }
            catch (Exception ex)
            {
                LogManager.Warning($"分析 SDF 失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 完整测试流程：从 ModelItem 到 SDF
        /// </summary>
        /// <param name="modelItem">Navisworks 模型元素</param>
        /// <param name="cellSize">SDF 网格单元尺寸（模型单位）</param>
        /// <returns>MeshSignedDistanceGrid 对象</returns>
        public static MeshSignedDistanceGrid TestFullPipeline(ModelItem modelItem, double cellSize)
        {
            var stopwatch = Stopwatch.StartNew();
            LogManager.Info("=== 开始完整 SDF 测试流程 ===");
            LogManager.Info($"模型元素: {modelItem.DisplayName}");
            LogManager.Info($"SDF 单元尺寸: {cellSize:F4} 模型单位");

            MeshSignedDistanceGrid sdf = null;

            try
            {
                // 步骤 1：提取三角形
                LogManager.Info("[步骤 1/3] 提取三角形网格...");
                var triangles = GeometryHelper.ExtractTriangles(new[] { modelItem });

                if (triangles.Count == 0)
                {
                    LogManager.Error("未提取到三角形数据");
                    return null;
                }

                LogManager.Info($"提取到 {triangles.Count} 个三角形");

                // 步骤 2：转换为 DMesh3
                LogManager.Info("[步骤 2/3] 转换到 DMesh3 格式...");
                var mesh = ConvertToDMesh3(triangles);

                if (mesh.TriangleCount == 0)
                {
                    LogManager.Error("DMesh3 网格为空");
                    return null;
                }

                LogManager.Info($"DMesh3: {mesh.VertexCount} 顶点, {mesh.TriangleCount} 三角形");

                // 步骤 3：计算 SDF
                LogManager.Info("[步骤 3/3] 计算签名距离场...");
                sdf = ComputeSDF(mesh, cellSize);

                if (sdf == null)
                {
                    LogManager.Error("SDF 计算失败");
                    return null;
                }

                stopwatch.Stop();
                LogManager.Info($"=== 完整测试流程完成 ===");
                LogManager.Info($"总耗时: {stopwatch.ElapsedMilliseconds} ms ({stopwatch.Elapsed.TotalSeconds:F2} 秒)");

                // 验证 SDF 正确性
                VerifySDFCorrectness(sdf, mesh);
            }
            catch (Exception ex)
            {
                LogManager.Error($"完整测试流程失败: {ex.Message}");
                LogManager.Error($"堆栈跟踪: {ex.StackTrace}");
            }

            return sdf;
        }

        /// <summary>
        /// 验证 SDF 正确性（简化版本）
        /// </summary>
        private static void VerifySDFCorrectness(MeshSignedDistanceGrid sdf, DMesh3 mesh)
        {
            LogManager.Info("=== 验证 SDF 正确性（简化版本） ===");

            try
            {
                var bounds = mesh.CachedBounds;
                LogManager.Info($"网格边界: {bounds}");
                LogManager.Info("✅ SDF 创建成功，距离查询API需要进一步研究");
            }
            catch (Exception ex)
            {
                LogManager.Error($"SDF 验证失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 创建简单测试网格（手动构建立方体）
        /// </summary>
        /// <param name="size">立方体尺寸</param>
        /// <returns>DMesh3 立方体网格</returns>
        public static DMesh3 CreateTestCubeMesh(double size = 1.0)
        {
            LogManager.Info($"创建测试立方体网格: 尺寸={size}");

            var mesh = new DMesh3(MeshComponents.None);

            // 手动创建立方体的8个顶点
            double h = size / 2.0;
            int v0 = mesh.AppendVertex(new Vector3d(-h, -h, -h));
            int v1 = mesh.AppendVertex(new Vector3d(h, -h, -h));
            int v2 = mesh.AppendVertex(new Vector3d(h, h, -h));
            int v3 = mesh.AppendVertex(new Vector3d(-h, h, -h));
            int v4 = mesh.AppendVertex(new Vector3d(-h, -h, h));
            int v5 = mesh.AppendVertex(new Vector3d(h, -h, h));
            int v6 = mesh.AppendVertex(new Vector3d(h, h, h));
            int v7 = mesh.AppendVertex(new Vector3d(-h, h, h));

            // 12个三角形（每个面2个三角形）
            mesh.AppendTriangle(v0, v2, v1); // 底面
            mesh.AppendTriangle(v0, v3, v2);
            mesh.AppendTriangle(v4, v5, v6); // 顶面
            mesh.AppendTriangle(v4, v6, v7);
            mesh.AppendTriangle(v0, v1, v5); // 前面
            mesh.AppendTriangle(v0, v5, v4);
            mesh.AppendTriangle(v2, v3, v7); // 后面
            mesh.AppendTriangle(v2, v7, v6);
            mesh.AppendTriangle(v0, v4, v7); // 左面
            mesh.AppendTriangle(v0, v7, v3);
            mesh.AppendTriangle(v1, v2, v6); // 右面
            mesh.AppendTriangle(v1, v6, v5);

            LogManager.Info($"测试网格: {mesh.VertexCount} 顶点, {mesh.TriangleCount} 三角形");

            return mesh;
        }
    }
}
