using System;
using System.Collections.Generic;
using static NavisworksTransport.CategoryAttributeManager;

namespace NavisworksTransport.PathPlanning
{
    /// <summary>
    /// 体素网格可视化器 - 在 Navisworks 3D 视图中显示体素网格
    /// 阶段 1.5：体素可视化验证
    /// </summary>
    public class VoxelGridVisualizer
    {
        /// <summary>
        /// 可视化体素网格（简化版本 - 使用小球表示体素）
        /// </summary>
        /// <param name="voxelGrid">体素网格</param>
        /// <param name="samplingRate">采样率（1=全部显示，2=每隔一个显示，以此类推）</param>
        /// <param name="showPassableOnly">是否只显示可通行体素</param>
        /// <returns>生成的路径点列表，可用于PathPointRenderPlugin渲染</returns>
        public static List<PathPoint> VisualizeAsPoints(
            VoxelGrid voxelGrid,
            int samplingRate = 2,
            bool showPassableOnly = false)
        {
            LogManager.Info("=== 开始体素网格可视化 ===");
            LogManager.Info($"网格尺寸: {voxelGrid.SizeX} × {voxelGrid.SizeY} × {voxelGrid.SizeZ}");
            LogManager.Info($"采样率: {samplingRate} (每{samplingRate}个体素显示1个)");
            LogManager.Info($"仅显示可通行: {showPassableOnly}");

            var points = new List<PathPoint>();
            int totalVoxels = 0;
            int visualizedVoxels = 0;

            try
            {
                for (int x = 0; x < voxelGrid.SizeX; x += samplingRate)
                {
                    for (int y = 0; y < voxelGrid.SizeY; y += samplingRate)
                    {
                        for (int z = 0; z < voxelGrid.SizeZ; z += samplingRate)
                        {
                            totalVoxels++;

                            var cell = voxelGrid.GetCell(x, y, z);
                            if (cell == null) continue;

                            // 过滤：如果只显示可通行体素，跳过不可通行的
                            if (showPassableOnly && !cell.IsPassable)
                                continue;

                            // 获取体素中心点的世界坐标
                            var worldPos = voxelGrid.VoxelToWorldCenter(x, y, z);

                            // 创建路径点表示体素
                            // 根据体素类型选择PathPointType，以便渲染器使用不同颜色
                            PathPointType pointType;
                            if (cell.IsPassable)
                            {
                                pointType = PathPointType.StartPoint;  // 绿色 - 自由空间
                            }
                            else
                            {
                                pointType = PathPointType.EndPoint;    // 红色 - 障碍物
                            }

                            var point = new PathPoint
                            {
                                Index = visualizedVoxels,
                                Position = worldPos,
                                Name = GetVoxelDisplayName(cell, x, y, z),
                                Type = pointType,
                                Notes = $"VoxelType:{cell.Type},IsPassable:{cell.IsPassable}"
                            };

                            points.Add(point);
                            visualizedVoxels++;
                        }
                    }
                }

                LogManager.Info($"总体素数: {voxelGrid.TotalVoxels:N0}");
                LogManager.Info($"采样后体素数: {totalVoxels:N0}");
                LogManager.Info($"可视化体素数: {visualizedVoxels:N0}");
                LogManager.Info("=== 体素网格可视化完成 ===");
            }
            catch (Exception ex)
            {
                LogManager.Error($"体素网格可视化失败: {ex.Message}");
                LogManager.Error($"堆栈跟踪: {ex.StackTrace}");
            }

            return points;
        }

        /// <summary>
        /// 可视化体素网格的切片（指定Z高度）
        /// </summary>
        /// <param name="voxelGrid">体素网格</param>
        /// <param name="zIndex">Z方向索引（高度层）</param>
        /// <returns>生成的路径点列表</returns>
        public static List<PathPoint> VisualizeSlice(VoxelGrid voxelGrid, int zIndex)
        {
            LogManager.Info($"=== 可视化体素网格切片 (Z={zIndex}) ===");

            var points = new List<PathPoint>();
            int visualizedCount = 0;

            try
            {
                if (!voxelGrid.IsValidIndex(0, 0, zIndex))
                {
                    LogManager.Warning($"无效的 Z 索引: {zIndex}，有效范围: 0 ~ {voxelGrid.SizeZ - 1}");
                    return points;
                }

                for (int x = 0; x < voxelGrid.SizeX; x++)
                {
                    for (int y = 0; y < voxelGrid.SizeY; y++)
                    {
                        var cell = voxelGrid.GetCell(x, y, zIndex);
                        if (cell == null) continue;

                        // 获取体素中心点的世界坐标
                        var worldPos = voxelGrid.VoxelToWorldCenter(x, y, zIndex);

                        // 创建路径点表示体素
                        var point = new PathPoint
                        {
                            Index = visualizedCount,
                            Position = worldPos,
                            Name = GetVoxelDisplayName(cell, x, y, zIndex),
                            Type = PathPointType.WayPoint,
                            Notes = $"VoxelType:{cell.Type}"
                        };

                        points.Add(point);
                        visualizedCount++;
                    }
                }

                LogManager.Info($"切片 Z={zIndex} 可视化体素数: {visualizedCount:N0}");
                LogManager.Info("=== 切片可视化完成 ===");
            }
            catch (Exception ex)
            {
                LogManager.Error($"切片可视化失败: {ex.Message}");
                LogManager.Error($"堆栈跟踪: {ex.StackTrace}");
            }

            return points;
        }

        /// <summary>
        /// 可视化体素网格的边界（只显示障碍物表面）
        /// </summary>
        /// <param name="voxelGrid">体素网格</param>
        /// <returns>生成的路径点列表</returns>
        public static List<PathPoint> VisualizeBoundary(VoxelGrid voxelGrid)
        {
            LogManager.Info("=== 可视化体素网格边界（障碍物表面） ===");

            var points = new List<PathPoint>();
            int visualizedCount = 0;

            try
            {
                for (int x = 0; x < voxelGrid.SizeX; x++)
                {
                    for (int y = 0; y < voxelGrid.SizeY; y++)
                    {
                        for (int z = 0; z < voxelGrid.SizeZ; z++)
                        {
                            var cell = voxelGrid.GetCell(x, y, z);
                            if (cell == null || cell.IsPassable) continue;

                            // 检查是否是边界体素（至少有一个相邻体素是可通行的）
                            if (IsBoundaryVoxel(voxelGrid, x, y, z))
                            {
                                var worldPos = voxelGrid.VoxelToWorldCenter(x, y, z);

                                var point = new PathPoint
                                {
                                    Index = visualizedCount,
                                    Position = worldPos,
                                    Name = GetVoxelDisplayName(cell, x, y, z),
                                    Type = PathPointType.WayPoint,
                                    Notes = $"VoxelType:{cell.Type},Boundary:true"
                                };

                                points.Add(point);
                                visualizedCount++;
                            }
                        }
                    }
                }

                LogManager.Info($"边界体素数: {visualizedCount:N0}");
                LogManager.Info("=== 边界可视化完成 ===");
            }
            catch (Exception ex)
            {
                LogManager.Error($"边界可视化失败: {ex.Message}");
                LogManager.Error($"堆栈跟踪: {ex.StackTrace}");
            }

            return points;
        }

        /// <summary>
        /// 判断体素是否为边界体素
        /// </summary>
        private static bool IsBoundaryVoxel(VoxelGrid voxelGrid, int x, int y, int z)
        {
            // 获取 6 邻域
            var neighbors = voxelGrid.GetNeighbors6(x, y, z);

            // 如果至少有一个邻居是可通行的，则当前体素是边界
            foreach (var (nx, ny, nz) in neighbors)
            {
                if (voxelGrid.IsPassable(nx, ny, nz))
                {
                    return true;
                }
            }

            return false;
        }

        /// <summary>
        /// 获取体素显示名称
        /// </summary>
        private static string GetVoxelDisplayName(VoxelCell cell, int x, int y, int z)
        {
            string typeStr = cell.IsPassable ? "通行" : "障碍";
            return $"体素({x},{y},{z})-{typeStr}-{cell.Type}";
        }

        /// <summary>
        /// 将体素列表转换为 PathRoute，以便使用 PathPointRenderPlugin 渲染
        /// </summary>
        /// <param name="voxelPoints">体素点列表</param>
        /// <param name="routeName">路径名称</param>
        /// <returns>PathRoute 对象</returns>
        public static PathRoute ConvertToPathRoute(List<PathPoint> voxelPoints, string routeName = "体素网格可视化")
        {
            var route = new PathRoute
            {
                Id = "voxel_grid_visualization",  // 使用固定ID，让PathPointRenderPlugin识别为体素网格
                Name = routeName,
                Points = voxelPoints,
                IsComplete = true,
                CreatedTime = DateTime.Now
            };

            return route;
        }

        /// <summary>
        /// 快速可视化测试
        /// </summary>
        /// <param name="voxelGrid">体素网格</param>
        public static void QuickVisualizationTest(VoxelGrid voxelGrid)
        {
            LogManager.Info("=== 开始快速可视化测试 ===");

            try
            {
                // 统计信息
                var (total, passable, obstacle) = voxelGrid.GetStatistics();
                LogManager.Info($"体素统计: 总数={total:N0}, 可通行={passable:N0}, 障碍={obstacle:N0}");

                // 测试1：可视化底层切片（Z=0）
                LogManager.Info("[测试 1] 可视化底层切片 (Z=0)");
                var slicePoints = VisualizeSlice(voxelGrid, 0);
                LogManager.Info($"底层切片点数: {slicePoints.Count}");

                // 测试2：可视化中间层切片（Z=中间）
                int midZ = voxelGrid.SizeZ / 2;
                LogManager.Info($"[测试 2] 可视化中间层切片 (Z={midZ})");
                var midSlicePoints = VisualizeSlice(voxelGrid, midZ);
                LogManager.Info($"中间层切片点数: {midSlicePoints.Count}");

                // 测试3：可视化边界
                LogManager.Info("[测试 3] 可视化边界（障碍物表面）");
                var boundaryPoints = VisualizeBoundary(voxelGrid);
                LogManager.Info($"边界点数: {boundaryPoints.Count}");

                // 测试4：采样可视化（每隔2个体素显示1个）
                LogManager.Info("[测试 4] 采样可视化（采样率=2）");
                var sampledPoints = VisualizeAsPoints(voxelGrid, 2, false);
                LogManager.Info($"采样点数: {sampledPoints.Count}");

                LogManager.Info("=== 快速可视化测试完成 ===");
                LogManager.Info("提示：使用 PathPointRenderPlugin 渲染这些点");
            }
            catch (Exception ex)
            {
                LogManager.Error($"快速可视化测试失败: {ex.Message}");
                LogManager.Error($"堆栈跟踪: {ex.StackTrace}");
            }
        }

        /// <summary>
        /// 生成可视化报告（文本格式）
        /// </summary>
        /// <param name="voxelGrid">体素网格</param>
        /// <returns>报告文本</returns>
        public static string GenerateVisualizationReport(VoxelGrid voxelGrid)
        {
            var report = new System.Text.StringBuilder();

            report.AppendLine("================================");
            report.AppendLine("  体素网格可视化报告");
            report.AppendLine("================================");
            report.AppendLine();

            // 基本信息
            report.AppendLine("【基本信息】");
            report.AppendLine($"网格尺寸: {voxelGrid.SizeX} × {voxelGrid.SizeY} × {voxelGrid.SizeZ}");
            report.AppendLine($"体素尺寸: {voxelGrid.VoxelSize:F4} 模型单位");
            report.AppendLine($"总体素数: {voxelGrid.TotalVoxels:N0}");
            report.AppendLine($"网格边界: {voxelGrid.Bounds.Min} ~ {voxelGrid.Bounds.Max}");
            report.AppendLine();

            // 统计信息
            var (total, passable, obstacle) = voxelGrid.GetStatistics();
            double passableRatio = (double)passable / total * 100.0;
            double obstacleRatio = (double)obstacle / total * 100.0;

            report.AppendLine("【统计信息】");
            report.AppendLine($"总体素数: {total:N0}");
            report.AppendLine($"可通行体素: {passable:N0} ({passableRatio:F1}%)");
            report.AppendLine($"障碍物体素: {obstacle:N0} ({obstacleRatio:F1}%)");
            report.AppendLine();

            // 类型分布
            report.AppendLine("【体素类型分布】");
            var typeDistribution = AnalyzeTypeDistribution(voxelGrid);
            foreach (var kvp in typeDistribution)
            {
                double ratio = (double)kvp.Value / total * 100.0;
                report.AppendLine($"  {kvp.Key}: {kvp.Value:N0} ({ratio:F1}%)");
            }
            report.AppendLine();

            // 可视化建议
            report.AppendLine("【可视化建议】");
            if (total > 1000000)
            {
                report.AppendLine("  ⚠️ 体素数量很大，建议使用采样率 >= 5");
                report.AppendLine("  或者只可视化边界/切片");
            }
            else if (total > 100000)
            {
                report.AppendLine("  ⚠️ 体素数量较大，建议使用采样率 >= 3");
            }
            else
            {
                report.AppendLine("  ✅ 体素数量适中，可以使用采样率 1-2");
            }
            report.AppendLine();

            report.AppendLine("================================");

            return report.ToString();
        }

        /// <summary>
        /// 分析体素类型分布
        /// </summary>
        private static Dictionary<LogisticsElementType, int> AnalyzeTypeDistribution(VoxelGrid voxelGrid)
        {
            var distribution = new Dictionary<LogisticsElementType, int>();

            for (int x = 0; x < voxelGrid.SizeX; x++)
            {
                for (int y = 0; y < voxelGrid.SizeY; y++)
                {
                    for (int z = 0; z < voxelGrid.SizeZ; z++)
                    {
                        var cell = voxelGrid.GetCell(x, y, z);
                        if (cell == null) continue;

                        if (!distribution.ContainsKey(cell.Type))
                        {
                            distribution[cell.Type] = 0;
                        }

                        distribution[cell.Type]++;
                    }
                }
            }

            return distribution;
        }
    }
}
