using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Autodesk.Navisworks.Api;
using NavisworksTransport.Core;

namespace NavisworksTransport.Commands
{
    /// <summary>
    /// 设置物流属性参数类
    /// </summary>
    public class SetLogisticsAttributeParameters
    {
        /// <summary>
        /// 目标模型项集合
        /// </summary>
        public ModelItemCollection TargetItems { get; set; }

        /// <summary>
        /// 物流元素类型
        /// </summary>
        public CategoryAttributeManager.LogisticsElementType ElementType { get; set; }

        /// <summary>
        /// 是否可通行（仅对通道类型有效）
        /// </summary>
        public bool? IsTraversable { get; set; }

        /// <summary>
        /// 自定义属性字典
        /// </summary>
        public Dictionary<string, object> CustomAttributes { get; set; }

        /// <summary>
        /// 是否覆盖现有属性
        /// </summary>
        public bool OverwriteExisting { get; set; } = true;

        /// <summary>
        /// 操作描述（用于日志记录）
        /// </summary>
        public string Description { get; set; }

        public SetLogisticsAttributeParameters()
        {
            TargetItems = new ModelItemCollection();
            CustomAttributes = new Dictionary<string, object>();
        }

        /// <summary>
        /// 验证参数有效性
        /// </summary>
        public PathPlanningResult ValidateParameters()
        {
            var errors = new List<string>();

            if (TargetItems == null || TargetItems.Count == 0)
                errors.Add("目标模型项集合不能为空");

            if (!Enum.IsDefined(typeof(CategoryAttributeManager.LogisticsElementType), ElementType))
                errors.Add("无效的物流元素类型");

            // 检查通道类型的特殊要求
            if (ElementType == CategoryAttributeManager.LogisticsElementType.通道 && !IsTraversable.HasValue)
            {
                errors.Add("通道类型必须指定是否可通行");
            }

            if (errors.Count > 0)
            {
                return PathPlanningResult.ValidationFailure($"参数验证失败: {string.Join("; ", errors)}");
            }

            return PathPlanningResult.Success("参数验证通过");
        }
    }

    /// <summary>
    /// 设置物流属性结果类
    /// </summary>
    public class SetLogisticsAttributeResult
    {
        /// <summary>
        /// 成功设置属性的模型项数量
        /// </summary>
        public int SuccessCount { get; set; }

        /// <summary>
        /// 失败的模型项数量
        /// </summary>
        public int FailureCount { get; set; }

        /// <summary>
        /// 总模型项数量
        /// </summary>
        public int TotalCount { get; set; }

        /// <summary>
        /// 详细结果信息
        /// </summary>
        public List<string> DetailedResults { get; set; }

        /// <summary>
        /// 已设置的物流元素类型
        /// </summary>
        public CategoryAttributeManager.LogisticsElementType ElementType { get; set; }

        /// <summary>
        /// 操作执行时间（毫秒）
        /// </summary>
        public long ExecutionTimeMs { get; set; }

        public SetLogisticsAttributeResult()
        {
            DetailedResults = new List<string>();
        }

        /// <summary>
        /// 成功率
        /// </summary>
        public double SuccessRate => TotalCount > 0 ? (double)SuccessCount / TotalCount : 0.0;
    }

    /// <summary>
    /// 设置物流属性Command
    /// </summary>
    public class SetLogisticsAttributeCommand : CommandBase
    {
        #region 字段和属性

        private readonly SetLogisticsAttributeParameters _parameters;
        private readonly CategoryAttributeManager _categoryAttributeManager;
        private readonly UIStateManager _uiStateManager;

        /// <summary>
        /// 命令参数
        /// </summary>
        public SetLogisticsAttributeParameters Parameters => _parameters;

        #endregion

        #region 构造函数

        /// <summary>
        /// 初始化设置物流属性命令
        /// </summary>
        /// <param name="parameters">设置参数</param>
        /// <param name="categoryAttributeManager">类别属性管理器</param>
        public SetLogisticsAttributeCommand(SetLogisticsAttributeParameters parameters, CategoryAttributeManager categoryAttributeManager = null)
            : base("SetLogisticsAttribute", "设置物流属性", "为指定模型项设置物流相关的属性信息")
        {
            _parameters = parameters ?? throw new ArgumentNullException(nameof(parameters));
            _categoryAttributeManager = categoryAttributeManager ?? new CategoryAttributeManager();
            _uiStateManager = UIStateManager.Instance;

            LogInfo("设置物流属性命令初始化完成");
        }

        #endregion

        #region CommandBase实现

        /// <summary>
        /// 验证命令参数
        /// </summary>
        protected override PathPlanningResult ValidateParameters()
        {
            LogInfo("开始验证设置物流属性参数");

            try
            {
                // 验证基础参数
                var basicValidation = _parameters.ValidateParameters();
                if (!basicValidation.IsSuccess)
                {
                    LogWarning($"基础参数验证失败: {basicValidation.ErrorMessage}");
                    return basicValidation;
                }

                // 验证CategoryAttributeManager状态
                if (_categoryAttributeManager == null)
                {
                    return PathPlanningResult.ValidationFailure("类别属性管理器未初始化");
                }

                // 验证Navisworks文档状态
                var document = Application.ActiveDocument;
                if (document?.Models == null || !document.Models.Any())
                {
                    return PathPlanningResult.ValidationFailure("当前没有加载的Navisworks模型");
                }

                // 验证目标模型项是否在当前文档中
                foreach (ModelItem item in _parameters.TargetItems)
                {
                    if (item == null)
                    {
                        return PathPlanningResult.ValidationFailure("目标模型项集合包含空引用");
                    }
                }

                LogInfo("参数验证通过");
                return PathPlanningResult.Success("所有参数验证通过");
            }
            catch (Exception ex)
            {
                LogError("参数验证过程中发生异常", ex);
                return PathPlanningResult.ValidationFailure($"验证过程异常: {ex.Message}");
            }
        }

        /// <summary>
        /// 执行设置物流属性的核心逻辑
        /// </summary>
        protected override async Task<PathPlanningResult> ExecuteInternalAsync(CancellationToken cancellationToken)
        {
            LogInfo("开始执行设置物流属性");
            var startTime = DateTime.UtcNow;

            try
            {
                // 第一阶段：初始化（10%）
                UpdateProgress(10, "正在初始化物流属性设置环境...");
                ThrowIfCancellationRequested(cancellationToken);

                // 更新UI状态
                await _uiStateManager.ExecuteUIUpdateAsync(() =>
                {
                    LogInfo("UI状态更新：物流属性设置进行中");
                });

                // 第二阶段：准备属性设置（20%）
                UpdateProgress(20, "正在准备属性设置参数...");
                ThrowIfCancellationRequested(cancellationToken);

                var totalItems = _parameters.TargetItems.Count;
                LogInfo($"目标模型项数量: {totalItems}");
                LogInfo($"物流元素类型: {_parameters.ElementType}");
                LogInfo($"是否覆盖现有属性: {_parameters.OverwriteExisting}");
                if (_parameters.IsTraversable.HasValue)
                {
                    LogInfo($"可通行性设置: {_parameters.IsTraversable.Value}");
                }

                // 第三阶段：执行属性设置（30% - 80%）
                UpdateProgress(30, "正在设置物流属性...");
                ThrowIfCancellationRequested(cancellationToken);

                var result = new SetLogisticsAttributeResult
                {
                    TotalCount = totalItems,
                    ElementType = _parameters.ElementType
                };

                // 在后台线程中执行属性设置操作
                await Task.Run(() =>
                {
                    try
                    {
                        LogInfo("开始批量设置物流属性");
                        
                        int processedCount = 0;
                        foreach (ModelItem item in _parameters.TargetItems)
                        {
                            try
                            {
                                // 检查取消请求
                                ThrowIfCancellationRequested(cancellationToken);

                                // 设置基本物流属性
                                // 创建单个项目的ModelItemCollection
                                var itemCollection = new ModelItemCollection
                                {
                                    item
                                };
                                
                                // 使用配置的默认值添加物流属性
                                int affectedCount = CategoryAttributeManager.AddLogisticsAttributes(
                                    itemCollection,
                                    _parameters.ElementType);
                                
                                bool success = affectedCount > 0;
                                
                                if (success)
                                {
                                    // 如果是通道类型，设置可通行性
                                    if (_parameters.ElementType == CategoryAttributeManager.LogisticsElementType.通道 && 
                                        _parameters.IsTraversable.HasValue)
                                    {
                                        success = _categoryAttributeManager.SetTraversable(item, _parameters.IsTraversable.Value);
                                    }

                                    // 设置自定义属性
                                    if (success && _parameters.CustomAttributes.Count > 0)
                                    {
                                        foreach (var kvp in _parameters.CustomAttributes)
                                        {
                                            try
                                            {
                                                _categoryAttributeManager.SetCustomAttribute(item, kvp.Key, kvp.Value?.ToString() ?? string.Empty, _parameters.OverwriteExisting);
                                            }
                                            catch (Exception attrEx)
                                            {
                                                LogWarning($"设置自定义属性失败 - 项: {item.DisplayName}, 属性: {kvp.Key}, 错误: {attrEx.Message}");
                                            }
                                        }
                                    }
                                }

                                if (success)
                                {
                                    result.SuccessCount++;
                                    result.DetailedResults.Add($"成功: {item.DisplayName}");
                                    LogInfo($"成功设置物流属性: {item.DisplayName} -> {_parameters.ElementType}");
                                }
                                else
                                {
                                    result.FailureCount++;
                                    result.DetailedResults.Add($"失败: {item.DisplayName}");
                                    LogWarning($"设置物流属性失败: {item.DisplayName}");
                                }

                                processedCount++;
                                
                                // 更新进度（30% - 80%）
                                var progressPercent = 30 + (int)((double)processedCount / totalItems * 50);
                                UpdateProgress(progressPercent, $"正在设置物流属性... ({processedCount}/{totalItems})");
                            }
                            catch (OperationCanceledException)
                            {
                                throw; // 重新抛出取消异常
                            }
                            catch (Exception itemEx)
                            {
                                result.FailureCount++;
                                result.DetailedResults.Add($"异常: {item.DisplayName} - {itemEx.Message}");
                                LogError($"设置模型项属性时发生异常: {item.DisplayName}", itemEx);
                            }
                        }
                        
                        LogInfo($"物流属性设置完成 - 成功: {result.SuccessCount}, 失败: {result.FailureCount}");
                    }
                    catch (OperationCanceledException)
                    {
                        LogInfo("物流属性设置被用户取消");
                        throw; // 重新抛出取消异常
                    }
                    catch (Exception ex)
                    {
                        LogError("批量设置物流属性时发生异常", ex);
                        throw;
                    }
                }, cancellationToken);

                UpdateProgress(85, "正在完成属性设置...");
                ThrowIfCancellationRequested(cancellationToken);

                // 第四阶段：保存更改和后处理（90%）
                UpdateProgress(90, "正在保存更改...");
                
                // 刷新文档以确保属性更改生效
                try
                {
                    await _uiStateManager.ExecuteUIUpdateAsync(() =>
                    {
                        // 触发文档刷新
                        Application.ActiveDocument.CurrentSelection.Clear();
                        LogInfo("文档状态已刷新");
                    });
                }
                catch (Exception refreshEx)
                {
                    LogWarning($"刷新文档状态失败: {refreshEx.Message}");
                }

                // 完成（100%）
                UpdateProgress(100, "物流属性设置完成");

                var elapsedMs = (DateTime.UtcNow - startTime).TotalMilliseconds;
                result.ExecutionTimeMs = (long)elapsedMs;

                LogInfo($"设置物流属性执行完成，总耗时: {elapsedMs:F0}ms");
                LogInfo($"设置结果 - 总数: {result.TotalCount}, 成功: {result.SuccessCount}, 失败: {result.FailureCount}, 成功率: {result.SuccessRate:P2}");

                // 创建结果对象
                var commandResult = PathPlanningResult<SetLogisticsAttributeResult>.Success(
                    result,
                    $"物流属性设置完成：成功 {result.SuccessCount}/{result.TotalCount} 项，成功率 {result.SuccessRate:P2}"
                );

                commandResult.ElapsedMilliseconds = (long)elapsedMs;
                return commandResult;
            }
            catch (OperationCanceledException)
            {
                LogInfo("设置物流属性被用户取消");
                throw; // 让基类处理取消异常
            }
            catch (Exception ex)
            {
                var elapsedMs = (DateTime.UtcNow - startTime).TotalMilliseconds;
                LogError($"设置物流属性执行失败，已耗时: {elapsedMs:F0}ms", ex);

                // 尝试恢复UI状态
                try
                {
                    await _uiStateManager.ExecuteUIUpdateAsync(() =>
                    {
                        LogInfo("尝试恢复UI状态");
                    });
                }
                catch (Exception uiEx)
                {
                    LogError("UI状态恢复失败", uiEx);
                }

                return PathPlanningResult.Failure($"设置物流属性失败: {ex.Message}", ex);
            }
        }

        #endregion

        #region 公共方法

        /// <summary>
        /// 创建设置物流属性命令的快捷方法
        /// </summary>
        /// <param name="targetItems">目标模型项</param>
        /// <param name="elementType">物流元素类型</param>
        /// <param name="isTraversable">是否可通行（通道类型）</param>
        /// <param name="description">操作描述</param>
        /// <returns>设置物流属性命令实例</returns>
        public static SetLogisticsAttributeCommand CreateQuick(ModelItemCollection targetItems, 
            CategoryAttributeManager.LogisticsElementType elementType, 
            bool? isTraversable = null, 
            string description = null)
        {
            var parameters = new SetLogisticsAttributeParameters
            {
                TargetItems = targetItems ?? new ModelItemCollection(),
                ElementType = elementType,
                IsTraversable = isTraversable,
                Description = description,
                OverwriteExisting = true
            };

            return new SetLogisticsAttributeCommand(parameters);
        }

        /// <summary>
        /// 创建带自定义属性的设置命令
        /// </summary>
        /// <param name="targetItems">目标模型项</param>
        /// <param name="elementType">物流元素类型</param>
        /// <param name="customAttributes">自定义属性</param>
        /// <param name="overwriteExisting">是否覆盖现有属性</param>
        /// <returns>设置物流属性命令实例</returns>
        public static SetLogisticsAttributeCommand CreateWithCustomAttributes(ModelItemCollection targetItems,
            CategoryAttributeManager.LogisticsElementType elementType,
            Dictionary<string, object> customAttributes,
            bool overwriteExisting = true)
        {
            var parameters = new SetLogisticsAttributeParameters
            {
                TargetItems = targetItems ?? new ModelItemCollection(),
                ElementType = elementType,
                CustomAttributes = customAttributes ?? new Dictionary<string, object>(),
                OverwriteExisting = overwriteExisting
            };

            return new SetLogisticsAttributeCommand(parameters);
        }

        /// <summary>
        /// 获取命令执行摘要信息
        /// </summary>
        /// <returns>命令信息摘要</returns>
        public string GetExecutionSummary()
        {
            return $"设置物流属性命令 - 目标数量:{_parameters.TargetItems?.Count ?? 0}, " +
                   $"元素类型:{_parameters.ElementType}, " +
                   $"可通行:{_parameters.IsTraversable?.ToString() ?? "未设置"}, " +
                   $"状态:{Status}";
        }

        #endregion
    }
}