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 CollisionResultsCategory = "collisionResults";
        public const string ManualTargetsCategory = "manualTargets";
        public const string ChannelPreviewCategory = "channelPreview";
        public const string ClashDetectiveResultsCategory = "clashDetectiveResults";

        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) },
                { CollisionResultsCategory, Color.Green },
                { ChannelPreviewCategory, Color.Green },
                { ClashDetectiveResultsCategory, Color.Red }
            };

        /// <summary>
        /// 高亮指定对象集合。
        /// </summary>
        public static void HighlightItems(string category, IEnumerable<ModelItem> items, Color color)
        {
            if (items == null)
                return;

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

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

            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);
            }
        }

        public static void HighlightItems(string category, IEnumerable<ModelItem> items)
        {
            if (string.IsNullOrWhiteSpace(category))
            {
                category = "default";
            }

            var color = GetCategoryColor(category);
            HighlightItems(category, items, color);
        }

        /// <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(CollisionResultsCategory);
                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))
            {
                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
            {
                // 忽略重绘异常
            }
        }
    }
}
