using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Navisworks.Api;

namespace NavisworksTransport.Utils
{
    /// <summary>
    /// 统一管理 Navisworks 临时高亮的工具类，支持按类别高亮与清除。
    /// </summary>
    public static class ModelHighlightHelper
    {
        public const string PrecomputeCollisionResultsCategory = "collisionResults";
        public const string ManualTargetsCategory = "manualTargets";
        public const string ChannelPreviewCategory = "channelPreview";
        public const string ClashDetectiveResultsCategory = "clashDetectiveResults";
        public const string AnimatedObjectCategory = "animatedObject";

        private class HighlightEntry
        {
            public Color Color { get; set; }
            public ModelItemCollection Items { get; set; }
        }

        public class HighlightInfo
        {
            public string Category { get; set; } = string.Empty;
            public Color Color { get; set; }
            public int Count { get; set; }
        }

        private static readonly object _syncRoot = new object();
        private static readonly Dictionary<string, HighlightEntry> _activeHighlights =
            new Dictionary<string, HighlightEntry>(StringComparer.OrdinalIgnoreCase);

        private static readonly Dictionary<string, Color> _categoryColors =
            new Dictionary<string, Color>(StringComparer.OrdinalIgnoreCase)
            {
                { "animation", Color.Red },
                { "runtime", Color.Red },
                { "independent", Color.Red },
                { "static", Color.Red },
                { "report", Color.Green },
                { "preview", Color.Blue },
                { ManualTargetsCategory, Color.FromByteRGB(255, 170, 0) },
                { PrecomputeCollisionResultsCategory, Color.FromByteRGB(156, 39, 176) }, // Material Purple #9C27B0（预计算碰撞，与红色/橙色明显区分）
                { ChannelPreviewCategory, Color.Green },
                { ClashDetectiveResultsCategory, Color.Red },
                { AnimatedObjectCategory, Color.FromByteRGB(255, 193, 7) }, // Amber/Yellow（动画物体-琥珀黄，更醒目且不与碰撞检测红色冲突）
                { "excludedObjects", Color.FromByteRGB(76, 175, 80) } // 排除对象-Material Green (#4CAF50)
            };

        /// <summary>
        /// 高亮指定对象集合（使用类别默认颜色）。
        /// </summary>
        public static void HighlightItems(string category, IEnumerable<ModelItem> items)
        {
            if (items == null)
                return;

            var document = Application.ActiveDocument;
            if (document?.Models == null)
                return;

            if (string.IsNullOrWhiteSpace(category))
            {
                category = "default";
            }

            var color = GetCategoryColor(category);

            lock (_syncRoot)
            {
                if (_activeHighlights.ContainsKey(category))
                {
                    _activeHighlights.Remove(category);
                    ResetAllHighlights(document);
                    ReapplyHighlights(document);
                }

                var collection = BuildCollection(items);
                if (collection.Count == 0)
                {
                    _activeHighlights.Remove(category);
                    return;
                }

                document.Models.OverrideTemporaryColor(collection, color);
                _activeHighlights[category] = new HighlightEntry
                {
                    Color = color,
                    Items = collection
                };

                RequestRedraw(document);
            }
        }

        /// <summary>
        /// 清除指定类别的高亮。
        /// </summary>
        public static void ClearCategory(string category)
        {
            if (string.IsNullOrWhiteSpace(category))
                return;

            var document = Application.ActiveDocument;
            if (document?.Models == null)
                return;

            lock (_syncRoot)
            {
                if (!_activeHighlights.Remove(category))
                    return;

                ResetAllHighlights(document);
                ReapplyHighlights(document);
                RequestRedraw(document);
            }
        }

        /// <summary>
        /// 清除所有碰撞相关高亮（预计算碰撞和ClashDetective碰撞）
        /// </summary>
        public static void ClearCollisionHighlights()
        {
            lock (_syncRoot)
            {
                ClearCategory(PrecomputeCollisionResultsCategory);
                ClearCategory(ClashDetectiveResultsCategory);
            }
        }

        /// <summary>
        /// 清除全部高亮。
        /// </summary>
        public static void ClearAllHighlights()
        {
            var document = Application.ActiveDocument;
            if (document?.Models == null)
                return;

            lock (_syncRoot)
            {
                ResetAllHighlights(document);
                _activeHighlights.Clear();
                RequestRedraw(document);
            }
        }

        /// <summary>
        /// 获取当前高亮快照。
        /// </summary>
        public static List<HighlightInfo> GetActiveHighlightSnapshot()
        {
            lock (_syncRoot)
            {
                return _activeHighlights
                    .Select(kvp => new HighlightInfo
                    {
                        Category = kvp.Key,
                        Color = kvp.Value.Color,
                        Count = kvp.Value.Items?.Count ?? 0
                    })
                    .ToList();
            }
        }

        public static Color GetCategoryColor(string category)
        {
            if (string.IsNullOrWhiteSpace(category))
            {
                category = "default";
            }

            if (_categoryColors.TryGetValue(category, out var color))
            {
                // 调试用：输出预计算高亮颜色值（转换为0-255整数）
                if (category == PrecomputeCollisionResultsCategory)
                {
                    int r = (int)(color.R * 255);
                    int g = (int)(color.G * 255);
                    int b = (int)(color.B * 255);
                    LogManager.Debug($"[GetCategoryColor] 预计算高亮颜色: R={r}, G={g}, B={b} (#{r:X2}{g:X2}{b:X2})");
                }
                return color;
            }

            return Color.White;
        }

        private static ModelItemCollection BuildCollection(IEnumerable<ModelItem> items)
        {
            var collection = new ModelItemCollection();
            if (items == null)
                return collection;

            foreach (var item in items)
            {
                if (item == null)
                    continue;

                try
                {
                    // 访问属性以检测对象是否有效
                    _ = item.DisplayName;
                }
                catch
                {
                    continue;
                }

                if (!collection.Contains(item))
                {
                    collection.Add(item);
                }
            }

            return collection;
        }

        private static void ResetAllHighlights(Document document)
        {
            document.Models.ResetAllTemporaryMaterials();
        }

        private static void ReapplyHighlights(Document document)
        {
            foreach (var entry in _activeHighlights.Values)
            {
                if (entry.Items == null || entry.Items.Count == 0)
                    continue;

                document.Models.OverrideTemporaryColor(entry.Items, entry.Color);
            }
        }

        private static void RequestRedraw(Document document)
        {
            try
            {
                document.ActiveView?.RequestDelayedRedraw(ViewRedrawRequests.All);
            }
            catch
            {
                // 忽略重绘异常
            }
        }

        #region 碰撞结果高亮相关方法

        /// <summary>
        /// <param name="category">类别名称</param>
        /// <param name="results">碰撞结果列表</param>
        /// <param name="clearOtherCategories">是否清除其他类别</param>
        public static void ManageCollisionHighlightsByCategory(string category, List<CollisionResult> results,
            bool clearOtherCategories = false)
        {
            try
            {
                var collidingItems = new List<ModelItem>();

                if (results != null)
                {
                    foreach (var result in results)
                    {
                        var item1 = result.Item1;
                        var item2 = result.Item2;

                        // 只高亮被撞物体（Item2），排除物体对象（Item1）
                        if (item2 != null && !collidingItems.Contains(item2))
                        {
                            collidingItems.Add(item2);
                        }
                    }
                }

                if (clearOtherCategories)
                {
                    ClearCategory(category);
                }

                HighlightItems(category, collidingItems);
            }
            catch (Exception ex)
            {
                LogManager.Error($"按类别管理碰撞高亮失败 [{category}]: {ex.Message}");
            }
        }

        /// <summary>
        /// 高亮ClashDetective测试结果
        /// </summary>
        /// <param name="testName">测试名称</param>
        /// <param name="getResultsFunc">获取碰撞结果的函数</param>
        public static void HighlightClashDetectiveResults(string testName, Func<string, List<CollisionResult>> getResultsFunc)
        {
            try
            {
                if (getResultsFunc == null)
                {
                    LogManager.Warning("[ClashDetective高亮] 获取结果的函数为空");
                    return;
                }

                // 获取碰撞结果
                var clashResults = getResultsFunc(testName);

                if (clashResults == null || clashResults.Count == 0)
                {
                    LogManager.Info("[ClashDetective高亮] 指定测试中未找到碰撞结果");
                    return;
                }

                // 提取碰撞对象
                var highlightItems = new List<ModelItem>();
                foreach (var clash in clashResults)
                {
                    // 只高亮被撞物体（Item2），排除物体对象（Item1）
                    // 🔥 移除去重逻辑：应该显示所有被撞物体，包括重复的
                    if (clash.Item2 != null)
                    {
                        highlightItems.Add(clash.Item2);
                    }
                }

                if (highlightItems.Count > 0)
                {
                    HighlightItems(ClashDetectiveResultsCategory, highlightItems);
                    LogManager.Info($"[ClashDetective高亮] 已高亮 {highlightItems.Count} 个对象，来自 {clashResults.Count} 个碰撞结果");
                }
                else
                {
                    LogManager.Info("[ClashDetective高亮] 没有有效的碰撞对象可高亮");
                }
            }
            catch (Exception ex)
            {
                LogManager.Error($"[ClashDetective高亮] 高亮失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 清除ClashDetective高亮
        /// </summary>
        public static void ClearClashDetectiveHighlights()
        {
            try
            {
                ClearCategory(ClashDetectiveResultsCategory);
                LogManager.Info("[ClashDetective高亮] 已清除高亮");
            }
            catch (Exception ex)
            {
                LogManager.Error($"[ClashDetective高亮] 清除高亮失败: {ex.Message}");
            }
        }

        #endregion
    }
}
