using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Navisworks.Api;
using NavisworksTransport.Utils;
using NavisApplication = Autodesk.Navisworks.Api.Application;

namespace NavisworksTransport.Core
{
    /// <summary>
    /// 楼层属性管理器 - 基于COM API的自定义楼层属性管理
    /// 提供楼层属性的增删改查功能，支持属性继承查询
    /// </summary>
    public class FloorAttributeManager
    {
        #region 常量定义

        /// <summary>
        /// 分层信息属性分类名称
        /// </summary>
        public const string FLOOR_CATEGORY = "分层信息";
        
        /// <summary>
        /// 分层信息属性分类内部名称
        /// </summary>
        public const string FLOOR_CATEGORY_INTERNAL = "Floor_Info_Category";
        
        /// <summary>
        /// 楼层属性名称
        /// </summary>
        public const string FLOOR_LEVEL_PROPERTY = "Floor_Level";
        
        /// <summary>
        /// 楼层属性显示名称
        /// </summary>
        public const string FLOOR_LEVEL_DISPLAY_NAME = "楼层";
        
        /// <summary>
        /// 区域属性名称
        /// </summary>
        public const string ZONE_PROPERTY = "Zone";
        
        /// <summary>
        /// 区域属性显示名称
        /// </summary>
        public const string ZONE_DISPLAY_NAME = "区域";
        
        /// <summary>
        /// 子系统属性名称
        /// </summary>
        public const string SUBSYSTEM_PROPERTY = "Sub_System";
        
        /// <summary>
        /// 子系统属性显示名称
        /// </summary>
        public const string SUBSYSTEM_DISPLAY_NAME = "子系统";

        #endregion

        #region 公共方法

        /// <summary>
        /// 设置对象的分层属性
        /// </summary>
        /// <param name="item">目标模型项</param>
        /// <param name="floorLevel">楼层标识，如"F1", "F2", "B1"等</param>
        /// <param name="zone">区域标识（可选）</param>
        /// <param name="subSystem">子系统标识（可选）</param>
        /// <returns>设置成功返回true，失败返回false</returns>
        public bool SetFloorAttribute(ModelItem item, string floorLevel, string zone = null, string subSystem = null)
        {
            if (item == null || string.IsNullOrEmpty(floorLevel))
            {
                LogManager.Error("[FloorAttributeManager] 设置楼层属性失败：参数无效");
                return false;
            }

            try
            {
                LogManager.Info($"[FloorAttributeManager] 开始设置模型 {item.DisplayName} 的楼层属性 {floorLevel}");
                
                return ExecuteWithUIThread(() =>
                {
                    return NavisworksComPropertyManager.SetFloorProperties(
                        item,
                        floorLevel,
                        zone,
                        subSystem,
                        FLOOR_CATEGORY,
                        FLOOR_CATEGORY_INTERNAL,
                        FLOOR_LEVEL_PROPERTY,
                        ZONE_PROPERTY,
                        SUBSYSTEM_PROPERTY);
                });
            }
            catch (Exception ex)
            {
                LogManager.Error($"[FloorAttributeManager] ❌ 设置楼层属性失败，错误: {ex.Message}", ex);
                return false;
            }
        }

        
        /// <summary>
        /// 设置单个分层属性，保留其他现有属性
        /// </summary>
        /// <param name="item">模型项</param>
        /// <param name="attributeType">属性类型：楼层、区域、子系统</param>
        /// <param name="attributeValue">属性值</param>
        /// <returns>操作是否成功</returns>
        public bool SetSingleLayerAttribute(ModelItem item, string attributeType, string attributeValue)
        {
            if (item == null || string.IsNullOrEmpty(attributeType) || string.IsNullOrEmpty(attributeValue))
            {
                LogManager.Error("[FloorAttributeManager] 设置单个分层属性失败：参数无效");
                return false;
            }

            try
            {
                LogManager.Info($"[FloorAttributeManager] 开始设置模型 {item.DisplayName} 的{attributeType}属性: {attributeValue}");
                
                return ExecuteWithUIThread(() =>
                {
                    // 获取现有的所有分层属性值
                    var existingFloorLevel = NavisworksComPropertyManager.GetFloorPropertyValue(item, FLOOR_CATEGORY, FLOOR_LEVEL_PROPERTY);
                    var existingZone = NavisworksComPropertyManager.GetFloorPropertyValue(item, FLOOR_CATEGORY, ZONE_PROPERTY);
                    var existingSubSystem = NavisworksComPropertyManager.GetFloorPropertyValue(item, FLOOR_CATEGORY, SUBSYSTEM_PROPERTY);

                    // 根据属性类型更新对应的值
                    string finalFloorLevel = existingFloorLevel;
                    string finalZone = existingZone;
                    string finalSubSystem = existingSubSystem;

                    switch (attributeType)
                    {
                        case "楼层":
                            finalFloorLevel = attributeValue;
                            break;
                        case "区域":
                            finalZone = attributeValue;
                            break;
                        case "子系统":
                            finalSubSystem = attributeValue;
                            break;
                        default:
                            LogManager.Error($"[FloorAttributeManager] 不支持的属性类型: {attributeType}");
                            return false;
                    }

                    // 使用静态方法设置完整的楼层属性
                    bool success = NavisworksComPropertyManager.SetFloorProperties(
                        item,
                        finalFloorLevel,
                        finalZone,
                        finalSubSystem,
                        FLOOR_CATEGORY,
                        FLOOR_CATEGORY_INTERNAL,
                        FLOOR_LEVEL_PROPERTY,
                        ZONE_PROPERTY,
                        SUBSYSTEM_PROPERTY);

                    if (success)
                    {
                        LogManager.Info($"[FloorAttributeManager] ✅ 成功设置{attributeType}属性");
                        
                        // 属性修改成功，清除分层缓存确保下次预览使用最新数据
                        try
                        {
                            ModelSplitterManager.Instance?.ClearCache();
                            LogManager.Info("[FloorAttributeManager] 属性修改成功，已清除分层缓存");
                        }
                        catch (Exception cacheEx)
                        {
                            LogManager.Warning($"[FloorAttributeManager] 清除缓存时出错: {cacheEx.Message}");
                        }
                    }

                    return success;
                });
            }
            catch (Exception ex)
            {
                LogManager.Error($"[FloorAttributeManager] ❌ 设置{attributeType}属性失败，错误: {ex.Message}", ex);
                return false;
            }
        }

        


        /// <summary>
        /// 获取楼层属性值（使用 Native API，性能最优）
        /// </summary>
        /// <param name="item">模型项</param>
        /// <param name="propertyName">属性显示名称，如 "楼层"、"区域"、"子系统"</param>
        /// <returns>属性值，不存在返回 null</returns>
        public string GetFloorProperty(ModelItem item, string propertyName)
        {
            if (item == null) return null;
            
            try
            {
                foreach (PropertyCategory category in item.PropertyCategories)
                {
                    if (category.DisplayName == FLOOR_CATEGORY)
                    {
                        foreach (DataProperty property in category.Properties)
                        {
                            if (property.DisplayName == propertyName)
                            {
                                return property.Value.ToDisplayString();
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                LogManager.Debug($"[FloorAttributeManager] 获取楼层属性 '{propertyName}' 失败: {ex.Message}");
            }
            return null;
        }

        /// <summary>
        /// 检查模型项是否有楼层属性（性能优化版本）
        /// </summary>
        public bool HasFloorAttributes(ModelItem item)
        {
            if (item == null) return false;
            
            try
            {
                foreach (PropertyCategory category in item.PropertyCategories)
                {
                    if (category.DisplayName == FLOOR_CATEGORY)
                        return true;
                }
            }
            catch (Exception ex)
            {
                LogManager.Debug($"[楼层管理器] 检查类别失败: {ex.Message}");
            }
            return false;
        }

        /// <summary>
        /// 通过 COM API 获取楼层属性值（特殊场景使用）
        /// 仅在以下情况使用：
        /// 1. 刚通过 COM API 更新属性后需要立即读取
        /// 2. 遇到 Native API 缓存不同步问题时
        /// 注意：性能较差，需要 UI 线程同步
        /// </summary>
        public string GetFloorPropertyViaCom(ModelItem item, string propertyName)
        {
            if (item == null) return null;
            
            // 将显示名称转换为内部名称
            string internalName = ConvertToInternalName(propertyName);
            
            return ExecuteWithUIThread(() =>
            {
                return NavisworksComPropertyManager.GetFloorPropertyValue(
                    item, FLOOR_CATEGORY, internalName);
            });
        }

        /// <summary>
        /// 将显示名称转换为内部名称
        /// </summary>
        private string ConvertToInternalName(string displayName)
        {
            switch (displayName)
            {
                case "楼层": return FLOOR_LEVEL_PROPERTY;
                case "区域": return ZONE_PROPERTY;
                case "子系统": return SUBSYSTEM_PROPERTY;
                default: return displayName + "_Internal";
            }
        }



        /// <summary>
        /// 批量设置楼层属性
        /// </summary>
        /// <param name="floorMappings">楼层映射字典，键为ModelItem，值为楼层标识</param>
        /// <returns>设置成功的数量</returns>
        public int SetFloorAttributeBatch(Dictionary<ModelItem, string> floorMappings)
        {
            if (floorMappings == null || floorMappings.Count == 0)
            {
                LogManager.Warning("[FloorAttributeManager] 批量设置楼层属性：输入为空");
                return 0;
            }

            int successCount = 0;
            LogManager.Info($"[FloorAttributeManager] 开始批量设置楼层属性，共 {floorMappings.Count} 个对象");

            foreach (var mapping in floorMappings)
            {
                try
                {
                    if (SetFloorAttribute(mapping.Key, mapping.Value))
                    {
                        successCount++;
                    }
                }
                catch (Exception ex)
                {
                    LogManager.Error($"[FloorAttributeManager] 批量设置楼层属性时出错：{mapping.Key?.DisplayName} -> {mapping.Value}, 错误: {ex.Message}");
                }
            }

            // 批量操作完成后执行缓存刷新
            if (successCount > 0)
            {
                NavisworksApiHelper.SafeCacheRefresh("FloorAttributeManager");
            }

            LogManager.Info($"[FloorAttributeManager] 批量设置完成，成功 {successCount}/{floorMappings.Count} 个对象");
            return successCount;
        }

        /// <summary>
        /// 获取所有楼层分组
        /// </summary>
        /// <returns>楼层分组字典，键为楼层标识，值为该楼层的ModelItem列表</returns>
        public Dictionary<string, List<ModelItem>> GetFloorGroups()
        {
            var floorGroups = new Dictionary<string, List<ModelItem>>();

            try
            {
                LogManager.Info("[FloorAttributeManager] 开始分析楼层分组");
                
                // 获取所有模型项
                var allItems = NavisApplication.ActiveDocument.Models.RootItemDescendantsAndSelf
                    .Where(item => item.HasGeometry)
                    .ToList();

                LogManager.Info($"[FloorAttributeManager] 共找到 {allItems.Count} 个几何体对象");

                foreach (var item in allItems)
                {
                    try
                    {
                        string floorLevel = GetFloorProperty(item, "楼层");
                        if (!string.IsNullOrEmpty(floorLevel))
                        {
                            if (!floorGroups.ContainsKey(floorLevel))
                            {
                                floorGroups[floorLevel] = new List<ModelItem>();
                            }
                            floorGroups[floorLevel].Add(item);
                        }
                        else
                        {
                            // 未分层对象归类到"未分层"
                            const string unclassified = "未分层";
                            if (!floorGroups.ContainsKey(unclassified))
                            {
                                floorGroups[unclassified] = new List<ModelItem>();
                            }
                            floorGroups[unclassified].Add(item);
                        }
                    }
                    catch (Exception ex)
                    {
                        LogManager.Error($"[FloorAttributeManager] 处理对象 {item.DisplayName} 时出错：{ex.Message}");
                    }
                }

                LogManager.Info($"[FloorAttributeManager] 楼层分组完成，共 {floorGroups.Count} 个分组");
                foreach (var group in floorGroups)
                {
                    LogManager.Info($"  - {group.Key}: {group.Value.Count} 个对象");
                }

                return floorGroups;
            }
            catch (Exception ex)
            {
                LogManager.Error($"[FloorAttributeManager] 获取楼层分组失败：{ex.Message}", ex);
                return new Dictionary<string, List<ModelItem>>();
            }
        }


        /// <summary>
        /// 清除对象的楼层属性
        /// </summary>
        /// <param name="item">目标模型项</param>
        /// <returns>清除成功返回true</returns>
        public bool ClearFloorAttribute(ModelItem item)
        {
            if (item == null) return false;

            try
            {
                LogManager.Info($"[FloorAttributeManager] 开始清除模型 {item.DisplayName} 的楼层属性");
                
                bool result = ExecuteWithUIThread(() =>
                {
                    var items = new ModelItemCollection { item };
                    int removedCount = NavisworksComPropertyManager.RemoveUserDefinedCategory(items, FLOOR_CATEGORY);
                    return removedCount > 0;
                });

                // 执行安全的缓存刷新
                if (result)
                {
                    NavisworksApiHelper.SafeCacheRefresh("FloorAttributeManager");
                    
                    // 属性清除成功，清除分层缓存确保下次预览使用最新数据
                    try
                    {
                        ModelSplitterManager.Instance?.ClearCache();
                        LogManager.Info("[FloorAttributeManager] 属性清除成功，已清除分层缓存");
                    }
                    catch (Exception cacheEx)
                    {
                        LogManager.Warning($"[FloorAttributeManager] 清除缓存时出错: {cacheEx.Message}");
                    }
                }

                return result;
            }
            catch (Exception ex)
            {
                LogManager.Error($"[FloorAttributeManager] ❌ 清除楼层属性失败：{ex.Message}", ex);
                return false;
            }
        }

        #endregion

        #region 私有方法

        /// <summary>
        /// 在UI线程中执行操作，确保线程安全
        /// </summary>
        private T ExecuteWithUIThread<T>(Func<T> operation)
        {
            return NavisworksApiHelper.ExecuteOnUIThread(operation);
        }

        #endregion
    }
}