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

namespace NavisworksTransport
{
    /// <summary>
    /// 属性分组器 - 负责根据自定义属性对模型元素进行分组
    /// </summary>
    public class AttributeGrouper
    {
        #region 数据结构

        /// <summary>
        /// 属性分组结果
        /// </summary>
        public class AttributeGroup
        {
            public string GroupName { get; set; }
            public string AttributeValue { get; set; }
            public ModelItemCollection Items { get; set; }
            public Dictionary<string, object> Metadata { get; set; }
            public int ItemCount => Items?.Count ?? 0;

            public AttributeGroup()
            {
                Items = new ModelItemCollection();
                Metadata = new Dictionary<string, object>();
            }
        }

        /// <summary>
        /// 属性统计信息
        /// </summary>
        public class AttributeStatistics
        {
            public string AttributeName { get; set; }
            public Dictionary<string, int> ValueCounts { get; set; }
            public int TotalItems { get; set; }
            public int ItemsWithAttribute { get; set; }
            public int UniqueValues { get; set; }
            public double Coverage => TotalItems > 0 ? (double)ItemsWithAttribute / TotalItems : 0.0;

            public AttributeStatistics()
            {
                ValueCounts = new Dictionary<string, int>();
            }
        }

        #endregion

        #region 公共方法

        /// <summary>
        /// 根据指定属性对模型元素进行分组
        /// </summary>
        /// <param name="items">要分组的模型元素集合</param>
        /// <param name="attributeName">分组依据的属性名称</param>
        /// <returns>分组结果列表</returns>
        public List<AttributeGroup> GroupByAttribute(ModelItemCollection items, string attributeName)
        {
            try
            {
                LogManager.Info($"[AttributeGrouper] 开始按属性分组，属性: {attributeName}, 元素数量: {items.Count}");

                if (items == null || items.Count == 0)
                {
                    LogManager.Warning("[AttributeGrouper] 输入的模型元素集合为空");
                    return new List<AttributeGroup>();
                }

                if (string.IsNullOrEmpty(attributeName))
                {
                    throw new ArgumentException("属性名称不能为空", nameof(attributeName));
                }

                var groups = new Dictionary<string, List<ModelItem>>();
                int processedCount = 0;
                int itemsWithAttribute = 0;

                foreach (ModelItem item in items)
                {
                    string attributeValue = GetAttributeValue(item, attributeName);
                    
                    if (!string.IsNullOrEmpty(attributeValue))
                    {
                        itemsWithAttribute++;
                        
                        if (!groups.ContainsKey(attributeValue))
                        {
                            groups[attributeValue] = new List<ModelItem>();
                        }
                        groups[attributeValue].Add(item);
                    }
                    else
                    {
                        // 处理没有该属性的元素
                        const string unknownGroup = "未定义";
                        if (!groups.ContainsKey(unknownGroup))
                        {
                            groups[unknownGroup] = new List<ModelItem>();
                        }
                        groups[unknownGroup].Add(item);
                    }

                    processedCount++;
                    
                    // 每处理1000个元素记录一次进度
                    if (processedCount % 1000 == 0)
                    {
                        LogManager.Info($"[AttributeGrouper] 已处理 {processedCount}/{items.Count} 个元素");
                    }
                }

                // 转换为AttributeGroup列表
                var result = new List<AttributeGroup>();
                foreach (var kvp in groups.OrderBy(g => g.Key))
                {
                    var group = new AttributeGroup
                    {
                        GroupName = SanitizeGroupName(kvp.Key),
                        AttributeValue = kvp.Key,
                        Items = new ModelItemCollection(),
                        Metadata = new Dictionary<string, object>
                        {
                            ["AttributeName"] = attributeName,
                            ["OriginalValue"] = kvp.Key,
                            ["ItemCount"] = kvp.Value.Count,
                            ["ProcessTime"] = DateTime.Now
                        }
                    };

                    group.Items.AddRange(kvp.Value);
                    result.Add(group);
                }

                LogManager.Info($"[AttributeGrouper] 分组完成，共生成 {result.Count} 个组，覆盖率: {(double)itemsWithAttribute / items.Count:P2}");
                return result;
            }
            catch (Exception ex)
            {
                LogManager.Error($"[AttributeGrouper] 属性分组失败: {ex.Message}");
                throw;
            }
        }

        /// <summary>
        /// 获取可用的属性列表
        /// </summary>
        /// <param name="items">模型元素集合</param>
        /// <returns>可用属性名称列表</returns>
        public List<string> GetAvailableAttributes(ModelItemCollection items)
        {
            try
            {
                var attributes = new HashSet<string>();
                int sampleSize = Math.Min(100, items.Count); // 采样前100个元素

                LogManager.Info($"[AttributeGrouper] 开始获取可用属性，采样数量: {sampleSize}");

                foreach (ModelItem item in items.Take(sampleSize))
                {
                    foreach (PropertyCategory category in item.PropertyCategories)
                    {
                        foreach (DataProperty property in category.Properties)
                        {
                            if (!string.IsNullOrEmpty(property.DisplayName))
                            {
                                attributes.Add(property.DisplayName);
                            }
                        }
                    }
                }

                var result = attributes.OrderBy(attr => attr).ToList();
                LogManager.Info($"[AttributeGrouper] 找到 {result.Count} 个可用属性");
                
                return result;
            }
            catch (Exception ex)
            {
                LogManager.Error($"[AttributeGrouper] 获取可用属性失败: {ex.Message}");
                return new List<string>();
            }
        }

        /// <summary>
        /// 获取指定属性的值分布统计
        /// </summary>
        /// <param name="items">模型元素集合</param>
        /// <param name="attributeName">属性名称</param>
        /// <returns>属性值计数字典</returns>
        public Dictionary<string, int> GetAttributeValueCounts(ModelItemCollection items, string attributeName)
        {
            try
            {
                LogManager.Info($"[AttributeGrouper] 开始统计属性值分布: {attributeName}");

                var valueCounts = new Dictionary<string, int>();

                foreach (ModelItem item in items)
                {
                    string value = GetAttributeValue(item, attributeName);
                    if (!string.IsNullOrEmpty(value))
                    {
                        if (valueCounts.ContainsKey(value))
                            valueCounts[value] = valueCounts[value] + 1;
                        else
                            valueCounts[value] = 1;
                    }
                    else
                    {
                        if (valueCounts.ContainsKey("未定义"))
                            valueCounts["未定义"] = valueCounts["未定义"] + 1;
                        else
                            valueCounts["未定义"] = 1;
                    }
                }

                LogManager.Info($"[AttributeGrouper] 属性值统计完成，共 {valueCounts.Count} 个不同值");
                return valueCounts;
            }
            catch (Exception ex)
            {
                LogManager.Error($"[AttributeGrouper] 统计属性值分布失败: {ex.Message}");
                return new Dictionary<string, int>();
            }
        }

        /// <summary>
        /// 获取属性的详细统计信息
        /// </summary>
        /// <param name="items">模型元素集合</param>
        /// <param name="attributeName">属性名称</param>
        /// <returns>属性统计信息</returns>
        public AttributeStatistics GetAttributeStatistics(ModelItemCollection items, string attributeName)
        {
            try
            {
                var statistics = new AttributeStatistics
                {
                    AttributeName = attributeName,
                    TotalItems = items.Count
                };

                var valueCounts = GetAttributeValueCounts(items, attributeName);
                statistics.ValueCounts = valueCounts;
                statistics.UniqueValues = valueCounts.Count;
                statistics.ItemsWithAttribute = valueCounts.Sum(kvp => kvp.Value);

                // 移除"未定义"项来计算真实的覆盖率
                if (valueCounts.ContainsKey("未定义"))
                {
                    statistics.ItemsWithAttribute -= valueCounts["未定义"];
                }

                LogManager.Info($"[AttributeGrouper] 属性统计完成: {attributeName}, 覆盖率: {statistics.Coverage:P2}");
                return statistics;
            }
            catch (Exception ex)
            {
                LogManager.Error($"[AttributeGrouper] 获取属性统计失败: {ex.Message}");
                return new AttributeStatistics { AttributeName = attributeName };
            }
        }

        /// <summary>
        /// 根据多个属性进行复合分组
        /// </summary>
        /// <param name="items">模型元素集合</param>
        /// <param name="attributeNames">属性名称列表</param>
        /// <returns>复合分组结果</returns>
        public List<AttributeGroup> GroupByMultipleAttributes(ModelItemCollection items, List<string> attributeNames)
        {
            try
            {
                LogManager.Info($"[AttributeGrouper] 开始多属性分组，属性数量: {attributeNames.Count}");

                if (attributeNames == null || attributeNames.Count == 0)
                {
                    throw new ArgumentException("属性名称列表不能为空", nameof(attributeNames));
                }

                var groups = new Dictionary<string, List<ModelItem>>();

                foreach (ModelItem item in items)
                {
                    var attributeValues = new List<string>();
                    
                    foreach (string attributeName in attributeNames)
                    {
                        string value = GetAttributeValue(item, attributeName) ?? "未定义";
                        attributeValues.Add(value);
                    }

                    string compositeKey = string.Join(" | ", attributeValues);
                    
                    if (!groups.ContainsKey(compositeKey))
                    {
                        groups[compositeKey] = new List<ModelItem>();
                    }
                    groups[compositeKey].Add(item);
                }

                var result = new List<AttributeGroup>();
                foreach (var kvp in groups.OrderBy(g => g.Key))
                {
                    var group = new AttributeGroup
                    {
                        GroupName = SanitizeGroupName(kvp.Key),
                        AttributeValue = kvp.Key,
                        Items = new ModelItemCollection(),
                        Metadata = new Dictionary<string, object>
                        {
                            ["AttributeNames"] = attributeNames,
                            ["CompositeKey"] = kvp.Key,
                            ["ItemCount"] = kvp.Value.Count,
                            ["GroupingMethod"] = "MultipleAttributes"
                        }
                    };

                    group.Items.AddRange(kvp.Value);
                    result.Add(group);
                }

                LogManager.Info($"[AttributeGrouper] 多属性分组完成，共生成 {result.Count} 个组");
                return result;
            }
            catch (Exception ex)
            {
                LogManager.Error($"[AttributeGrouper] 多属性分组失败: {ex.Message}");
                throw;
            }
        }

        /// <summary>
        /// 根据属性值范围进行分组（适用于数值属性）
        /// </summary>
        /// <param name="items">模型元素集合</param>
        /// <param name="attributeName">数值属性名称</param>
        /// <param name="rangeSize">范围大小</param>
        /// <returns>范围分组结果</returns>
        public List<AttributeGroup> GroupByAttributeRange(ModelItemCollection items, string attributeName, double rangeSize)
        {
            try
            {
                LogManager.Info($"[AttributeGrouper] 开始按属性范围分组: {attributeName}, 范围大小: {rangeSize}");

                var rangeGroups = new Dictionary<string, List<ModelItem>>();

                foreach (ModelItem item in items)
                {
                    string attributeValueStr = GetAttributeValue(item, attributeName);
                    
                    if (double.TryParse(attributeValueStr, out double numericValue))
                    {
                        double rangeStart = Math.Floor(numericValue / rangeSize) * rangeSize;
                        double rangeEnd = rangeStart + rangeSize;
                        string rangeKey = $"{rangeStart:F1}-{rangeEnd:F1}";

                        if (!rangeGroups.ContainsKey(rangeKey))
                        {
                            rangeGroups[rangeKey] = new List<ModelItem>();
                        }
                        rangeGroups[rangeKey].Add(item);
                    }
                    else
                    {
                        // 非数值的归入"其他"组
                        const string otherGroup = "其他";
                        if (!rangeGroups.ContainsKey(otherGroup))
                        {
                            rangeGroups[otherGroup] = new List<ModelItem>();
                        }
                        rangeGroups[otherGroup].Add(item);
                    }
                }

                var result = new List<AttributeGroup>();
                foreach (var kvp in rangeGroups.OrderBy(g => g.Key))
                {
                    var group = new AttributeGroup
                    {
                        GroupName = $"Range_{kvp.Key}",
                        AttributeValue = kvp.Key,
                        Items = new ModelItemCollection(),
                        Metadata = new Dictionary<string, object>
                        {
                            ["AttributeName"] = attributeName,
                            ["RangeSize"] = rangeSize,
                            ["RangeKey"] = kvp.Key,
                            ["GroupingMethod"] = "AttributeRange"
                        }
                    };

                    group.Items.AddRange(kvp.Value);
                    result.Add(group);
                }

                LogManager.Info($"[AttributeGrouper] 属性范围分组完成，共生成 {result.Count} 个组");
                return result;
            }
            catch (Exception ex)
            {
                LogManager.Error($"[AttributeGrouper] 属性范围分组失败: {ex.Message}");
                throw;
            }
        }

        #endregion

        #region 私有方法

        /// <summary>
        /// 获取模型元素的指定属性值
        /// </summary>
        /// <param name="item">模型元素</param>
        /// <param name="attributeName">属性名称</param>
        /// <returns>属性值字符串</returns>
        private string GetAttributeValue(ModelItem item, string attributeName)
        {
            try
            {
                // 使用 CategoryAttributeManager 的通用属性获取方法，简化代码
                return CategoryAttributeManager.GetGeneralPropertyValueTrimmed(item, attributeName);
            }
            catch (Exception ex)
            {
                LogManager.Warning($"[AttributeGrouper] 获取属性值失败: {item.DisplayName}, 属性: {attributeName}, 错误: {ex.Message}");
                return null;
            }
        }

        /// <summary>
        /// 清理分组名称，移除无效字符
        /// </summary>
        /// <param name="groupName">原始分组名称</param>
        /// <returns>清理后的分组名称</returns>
        private string SanitizeGroupName(string groupName)
        {
            if (string.IsNullOrEmpty(groupName))
                return "Unknown_Group";

            // 替换空格和特殊字符为下划线
            string sanitized = System.Text.RegularExpressions.Regex.Replace(groupName.Trim(), @"\s+", "_");
            
            // 移除或替换其他特殊字符，保留中文字符
            sanitized = System.Text.RegularExpressions.Regex.Replace(sanitized, @"[^\w\u4e00-\u9fa5\-\.]", "_");
            
            // 移除多余的下划线
            sanitized = System.Text.RegularExpressions.Regex.Replace(sanitized, @"_+", "_");
            
            // 移除首尾下划线
            sanitized = sanitized.Trim('_');

            // 限制长度
            if (sanitized.Length > 50)
            {
                sanitized = sanitized.Substring(0, 50);
            }

            return string.IsNullOrEmpty(sanitized) ? "Unknown_Group" : sanitized;
        }

        /// <summary>
        /// 验证属性名称是否有效
        /// </summary>
        /// <param name="attributeName">属性名称</param>
        /// <returns>是否有效</returns>
        private bool IsValidAttributeName(string attributeName)
        {
            return !string.IsNullOrWhiteSpace(attributeName) && 
                   attributeName.Length <= 100 && 
                   !attributeName.Contains('\0');
        }

        /// <summary>
        /// 获取属性的数据类型
        /// </summary>
        /// <param name="items">模型元素集合</param>
        /// <param name="attributeName">属性名称</param>
        /// <returns>数据类型字符串</returns>
        public string GetAttributeDataType(ModelItemCollection items, string attributeName)
        {
            try
            {
                var sampleValues = new List<string>();
                int sampleCount = 0;
                const int maxSamples = 20;

                foreach (ModelItem item in items)
                {
                    if (sampleCount >= maxSamples) break;

                    string value = GetAttributeValue(item, attributeName);
                    if (!string.IsNullOrEmpty(value))
                    {
                        sampleValues.Add(value);
                        sampleCount++;
                    }
                }

                if (sampleValues.Count == 0)
                    return "Unknown";

                // 检查是否为数值类型
                bool allNumeric = sampleValues.All(v => double.TryParse(v, out _));
                if (allNumeric)
                    return "Numeric";

                // 检查是否为日期类型
                bool allDate = sampleValues.All(v => DateTime.TryParse(v, out _));
                if (allDate)
                    return "DateTime";

                // 检查是否为布尔类型
                bool allBoolean = sampleValues.All(v => 
                    v.Equals("true", StringComparison.OrdinalIgnoreCase) || 
                    v.Equals("false", StringComparison.OrdinalIgnoreCase) ||
                    v.Equals("yes", StringComparison.OrdinalIgnoreCase) ||
                    v.Equals("no", StringComparison.OrdinalIgnoreCase));
                if (allBoolean)
                    return "Boolean";

                return "Text";
            }
            catch (Exception ex)
            {
                LogManager.Warning($"[AttributeGrouper] 获取属性数据类型失败: {attributeName}, 错误: {ex.Message}");
                return "Unknown";
            }
        }

        #endregion
    }
}