using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Media;
using Autodesk.Navisworks.Api;
using NavisworksTransport.UI.WPF.Models;

namespace NavisworksTransport.UI.WPF.Commands
{
    #region 数据传输对象 (DTOs)

    /// <summary>
    /// 楼层分析结果 - 数据传输对象
    /// </summary>
    public class FloorAnalysisResult
    {
        public bool IsSuccess { get; set; }
        public string Message { get; set; }
        public string ErrorMessage { get; set; }
        public Brush StatusColor { get; set; }
        public bool NeedsManualSetup { get; set; }
        public int FloorCount { get; set; }
        public int AttributeCount { get; set; }
    }

    /// <summary>
    /// 属性刷新结果
    /// </summary>
    public class RefreshAttributesResult
    {
        public bool IsSuccess { get; set; }
        public List<string> Attributes { get; set; }
        public string ErrorMessage { get; set; }
    }

    /// <summary>
    /// 节点选择结果
    /// </summary>
    public class SelectNodesResult
    {
        public bool IsSuccess { get; set; }
        public int Count { get; set; }
        public List<ModelItem> SelectedItems { get; set; } = new List<ModelItem>();
        public string ErrorMessage { get; set; }
    }

    /// <summary>
    /// 楼层属性应用结果
    /// </summary>
    public class ApplyFloorAttributesResult
    {
        public bool IsSuccess { get; set; }
        public int Count { get; set; }
        public string Message { get; set; }
        public string ErrorMessage { get; set; }
    }

    /// <summary>
    /// 分层预览结果
    /// </summary>
    public class PreviewSplitResult
    {
        public bool IsSuccess { get; set; }
        public List<SplitPreviewItem> PreviewItems { get; set; }
        public string ErrorMessage { get; set; }
    }

    /// <summary>
    /// 分层执行结果
    /// </summary>
    public class ExecuteSplitResult
    {
        public bool IsSuccess { get; set; }
        public string Message { get; set; }
        public string ErrorMessage { get; set; }
        public string OutputPath { get; set; }
    }

    /// <summary>
    /// 目录浏览结果
    /// </summary>
    public class BrowseDirectoryResult
    {
        public bool IsSuccess { get; set; }
        public string SelectedPath { get; set; }
        public string ErrorMessage { get; set; }
    }

    /// <summary>
    /// 保存选中项目结果
    /// </summary>
    public class SaveSelectedItemsResult
    {
        public bool IsSuccess { get; set; }
        public int Count { get; set; }
        public string Message { get; set; }
        public string ErrorMessage { get; set; }
    }

    /// <summary>
    /// 获取当前选择结果
    /// </summary>
    public class GetCurrentSelectionResult
    {
        public bool IsSuccess { get; set; }
        public int Count { get; set; }
        public string ErrorMessage { get; set; }
    }

    /// <summary>
    /// 测试导出结果
    /// </summary>
    public class TestExportResult
    {
        public bool IsSuccess { get; set; }
        public string Message { get; set; }
        public string ErrorMessage { get; set; }
        public string OutputPath { get; set; }
        public long FileSizeBytes { get; set; }
        public int ItemCount { get; set; }
    }

    #endregion

    #region Command接口

    /// <summary>
    /// 分层管理命令接口
    /// </summary>
    public interface ILayerManagementCommand<TResult>
    {
        Task<TResult> ExecuteAsync();
    }

    #endregion

    #region Command实现类

    /// <summary>
    /// 楼层分析命令
    /// </summary>
    public class FloorAnalysisCommand : ILayerManagementCommand<FloorAnalysisResult>
    {
        private readonly FloorDetector _floorDetector;
        private readonly int _maxDepth;

        public FloorAnalysisCommand(FloorDetector floorDetector, int maxDepth = 1)
        {
            _floorDetector = floorDetector ?? throw new ArgumentNullException(nameof(floorDetector));
            _maxDepth = Math.Max(0, Math.Min(5, maxDepth)); // 限制在0-5范围内
        }

        public async Task<FloorAnalysisResult> ExecuteAsync()
        {
            try
            {
                LogManager.Info($"[FloorAnalysisCommand] 开始楼层分析，深度限制: {_maxDepth}");
                LogManager.Info($"[FloorAnalysisCommand] 当前线程ID: {System.Threading.Thread.CurrentThread.ManagedThreadId}");

                var document = Application.ActiveDocument;
                if (document?.Models?.Count == 0)
                {
                    return new FloorAnalysisResult
                    {
                        IsSuccess = false,
                        ErrorMessage = "未发现加载的模型",
                        StatusColor = Brushes.Orange
                    };
                }

                // 在主线程上安全获取所有模型项
                var allItems = new ModelItemCollection();
                allItems.AddRange(document.Models.RootItemDescendantsAndSelf);
                LogManager.Info($"[FloorAnalysisCommand] 获取到 {allItems.Count} 个模型元素用于分析");

                // 在主线程上进行分析，确保线程安全，使用深度限制
                var floorResults = _floorDetector.DetectFloors(allItems, null, _maxDepth);
                var availableFloorAttributes = _floorDetector.GetAvailableFloorAttributes(allItems, _maxDepth);

                LogManager.Info($"[FloorAnalysisCommand] 检测到 {floorResults?.Count ?? 0} 个楼层，{availableFloorAttributes?.Count ?? 0} 个可用属性");

                if (floorResults?.Count > 0)
                {
                    return new FloorAnalysisResult
                    {
                        IsSuccess = true,
                        Message = $"检测到 {floorResults.Count} 个楼层，模型具备良好的层属性",
                        StatusColor = Brushes.Green,
                        NeedsManualSetup = false,
                        FloorCount = floorResults.Count,
                        AttributeCount = availableFloorAttributes?.Count ?? 0
                    };
                }
                else if (availableFloorAttributes?.Count > 0)
                {
                    return new FloorAnalysisResult
                    {
                        IsSuccess = true,
                        Message = $"发现 {availableFloorAttributes.Count} 个可用属性，建议手动设置层属性",
                        StatusColor = Brushes.Orange,
                        NeedsManualSetup = true,
                        FloorCount = 0,
                        AttributeCount = availableFloorAttributes.Count
                    };
                }
                else
                {
                    return new FloorAnalysisResult
                    {
                        IsSuccess = true,
                        Message = "未发现楼层属性，建议手动设置或按类别分层",
                        StatusColor = Brushes.Red,
                        NeedsManualSetup = false,
                        FloorCount = 0,
                        AttributeCount = 0
                    };
                }
            }
            catch (Exception ex)
            {
                LogManager.Error($"[FloorAnalysisCommand] 楼层分析失败: {ex.Message}", ex);
                return new FloorAnalysisResult
                {
                    IsSuccess = false,
                    ErrorMessage = $"楼层分析失败: {ex.Message}",
                    StatusColor = Brushes.Red
                };
            }
        }
    }

    /// <summary>
    /// 刷新属性命令
    /// </summary>
    public class RefreshAttributesCommand : ILayerManagementCommand<RefreshAttributesResult>
    {
        private readonly FloorDetector _floorDetector;
        private readonly int _maxDepth;

        public RefreshAttributesCommand(FloorDetector floorDetector, int maxDepth = 1)
        {
            _floorDetector = floorDetector ?? throw new ArgumentNullException(nameof(floorDetector));
            _maxDepth = Math.Max(0, Math.Min(5, maxDepth)); // 限制在0-5范围内
        }

        public async Task<RefreshAttributesResult> ExecuteAsync()
        {
            return await Task.Run(() =>
            {
                try
                {
                    LogManager.Info($"[RefreshAttributesCommand] 开始刷新属性，深度限制: {_maxDepth}");

                    var document = Application.ActiveDocument;
                    if (document?.Models?.Count == 0)
                    {
                        return new RefreshAttributesResult
                        {
                            IsSuccess = false,
                            ErrorMessage = "未发现加载的模型",
                            Attributes = new List<string>()
                        };
                    }

                    // 安全获取所有模型项 - 使用AddRange避免挂起
                    var allItems = new ModelItemCollection();
                    allItems.AddRange(document.Models.RootItemDescendantsAndSelf);
                    LogManager.Info($"[RefreshAttributesCommand] 获取到 {allItems.Count} 个模型元素用于属性分析");

                    // 使用已获取的模型项进行属性分析，使用深度限制
                    var attributes = _floorDetector.GetAvailableFloorAttributes(allItems, _maxDepth);
                    
                    LogManager.Info($"[RefreshAttributesCommand] 获取到 {attributes?.Count ?? 0} 个可用属性");

                    return new RefreshAttributesResult
                    {
                        IsSuccess = true,
                        Attributes = attributes?.ToList() ?? new List<string>()
                    };
                }
                catch (Exception ex)
                {
                    LogManager.Error($"[RefreshAttributesCommand] 刷新属性失败: {ex.Message}", ex);
                    return new RefreshAttributesResult
                    {
                        IsSuccess = false,
                        ErrorMessage = $"刷新属性失败: {ex.Message}",
                        Attributes = new List<string>()
                    };
                }
            });
        }
    }

    /// <summary>
    /// 选择节点命令
    /// </summary>
    public class SelectNodesCommand : ILayerManagementCommand<SelectNodesResult>
    {
        public async Task<SelectNodesResult> ExecuteAsync()
        {
            return await Task.Run(() =>
            {
                try
                {
                    LogManager.Info("[SelectNodesCommand] 开始获取选中节点");

                    var document = Application.ActiveDocument;
                    var selection = document?.CurrentSelection;
                    var count = selection?.SelectedItems?.Count ?? 0;

                    LogManager.Info($"[SelectNodesCommand] 获取到 {count} 个选中节点");

                    var selectedItems = selection?.SelectedItems?.Cast<ModelItem>().ToList() ?? new List<ModelItem>();

                    return new SelectNodesResult
                    {
                        IsSuccess = true,
                        Count = count,
                        SelectedItems = selectedItems
                    };
                }
                catch (Exception ex)
                {
                    LogManager.Error($"[SelectNodesCommand] 获取选中节点失败: {ex.Message}", ex);
                    return new SelectNodesResult
                    {
                        IsSuccess = false,
                        Count = 0,
                        SelectedItems = new List<ModelItem>(),
                        ErrorMessage = $"获取选中节点失败: {ex.Message}"
                    };
                }
            });
        }
    }

    /// <summary>
    /// 应用楼层属性命令
    /// </summary>
    public class ApplyFloorAttributesCommand : ILayerManagementCommand<ApplyFloorAttributesResult>
    {
        private readonly string _selectedFloorAttribute;

        public ApplyFloorAttributesCommand(string selectedFloorAttribute)
        {
            _selectedFloorAttribute = selectedFloorAttribute;
        }

        public async Task<ApplyFloorAttributesResult> ExecuteAsync()
        {
            return await Task.Run(() =>
            {
                try
                {
                    LogManager.Info($"[ApplyFloorAttributesCommand] 开始应用楼层属性: {_selectedFloorAttribute}");

                    var document = Application.ActiveDocument;
                    var selection = document?.CurrentSelection;
                    
                    if (selection?.SelectedItems?.Count == 0)
                    {
                        return new ApplyFloorAttributesResult
                        {
                            IsSuccess = false,
                            ErrorMessage = "请先选择要设置的节点",
                            Count = 0
                        };
                    }
                   
                    var count = selection.SelectedItems.Count;
                    LogManager.Info($"[ApplyFloorAttributesCommand] 成功为 {count} 个节点设置楼层属性");

                    return new ApplyFloorAttributesResult
                    {
                        IsSuccess = true,
                        Count = count,
                        Message = "楼层属性设置成功"
                    };
                }
                catch (Exception ex)
                {
                    LogManager.Error($"[ApplyFloorAttributesCommand] 应用楼层属性失败: {ex.Message}", ex);
                    return new ApplyFloorAttributesResult
                    {
                        IsSuccess = false,
                        ErrorMessage = $"设置楼层属性失败: {ex.Message}",
                        Count = 0
                    };
                }
            });
        }
    }

    /// <summary>
    /// 预览分层命令
    /// </summary>
    public class PreviewSplitCommand : ILayerManagementCommand<PreviewSplitResult>
    {
        private readonly ModelSplitterManager _modelSplitterManager;
        private readonly ModelSplitterManager.SplitConfiguration _config;

        public PreviewSplitCommand(ModelSplitterManager modelSplitterManager, ModelSplitterManager.SplitConfiguration config)
        {
            _modelSplitterManager = modelSplitterManager ?? throw new ArgumentNullException(nameof(modelSplitterManager));
            _config = config ?? throw new ArgumentNullException(nameof(config));
        }

        public async Task<PreviewSplitResult> ExecuteAsync()
        {
            try
            {
                LogManager.Info($"[PreviewSplitCommand] 开始分层预览，策略: {_config.Strategy}");
                LogManager.Info($"[PreviewSplitCommand] 当前线程ID: {System.Threading.Thread.CurrentThread.ManagedThreadId}");

                var previewResults = _modelSplitterManager.PreviewSplit(_config);

                if (previewResults?.Count > 0)
                {
                    var previewItems = previewResults.Select(result => new SplitPreviewItem
                    {
                        LayerName = result.LayerName,
                        LayerAttribute = result.LayerAttribute ?? GetLayerAttributeDescription(_config.Strategy, result.LayerName),
                        EstimatedSize = "0 KB", // 不再显示文件大小
                        Status = "就绪", // 保持UI兼容性
                        IsSelectedForSave = result.IsSelectedForSave,
                        Items = result.Items,
                        Metadata = result.Metadata  // 复制元数据，包含RootNodes等优化信息
                    }).ToList();

                    LogManager.Info($"[PreviewSplitCommand] 预览完成，共 {previewItems.Count} 个分层");

                    return new PreviewSplitResult
                    {
                        IsSuccess = true,
                        PreviewItems = previewItems
                    };
                }
                else
                {
                    LogManager.Warning("[PreviewSplitCommand] 预览结果为空");
                    return new PreviewSplitResult
                    {
                        IsSuccess = false,
                        ErrorMessage = "未生成预览结果，请检查模型和分层设置",
                        PreviewItems = new List<SplitPreviewItem>()
                    };
                }
            }
            catch (Exception ex)
            {
                LogManager.Error($"[PreviewSplitCommand] 分层预览失败: {ex.Message}", ex);
                return new PreviewSplitResult
                {
                    IsSuccess = false,
                    ErrorMessage = $"分层预览失败: {ex.Message}",
                    PreviewItems = new List<SplitPreviewItem>()
                };
            }
        }

        private string FormatFileSize(long bytes)
        {
            const long KB = 1024;
            const long MB = KB * 1024;
            const long GB = MB * 1024;

            if (bytes >= GB)
                return $"{bytes / GB:F1} GB";
            if (bytes >= MB)
                return $"{bytes / MB:F1} MB";
            if (bytes >= KB)
                return $"{bytes / KB:F1} KB";
            return $"{bytes} B";
        }

        /// <summary>
        /// 根据分层策略和分层名称生成属性描述
        /// </summary>
        /// <summary>
        /// 根据分层策略和分层名称生成属性描述
        /// </summary>
        private string GetLayerAttributeDescription(ModelSplitterManager.SplitStrategy strategy, string layerName)
        {
            switch (strategy)
            {
                case ModelSplitterManager.SplitStrategy.BySmartFloorDetection:
                    return "智能楼层检测";
                    
                case ModelSplitterManager.SplitStrategy.ByFloorAttribute:
                    return "按楼层属性";
                    
                case ModelSplitterManager.SplitStrategy.ByZoneAttribute:
                    return "按区域属性";
                    
                case ModelSplitterManager.SplitStrategy.BySubSystemAttribute:
                    return "按子系统属性";
                    
                default:
                    return "未知属性";
            }
        }
    }

    /// <summary>
    /// 执行分层命令
    /// </summary>
    public class ExecuteSplitCommand : ILayerManagementCommand<ExecuteSplitResult>
    {
        private readonly ModelSplitterManager _modelSplitterManager;
        private readonly ModelSplitterManager.SplitConfiguration _config;

        public ExecuteSplitCommand(ModelSplitterManager modelSplitterManager, ModelSplitterManager.SplitConfiguration config)
        {
            _modelSplitterManager = modelSplitterManager ?? throw new ArgumentNullException(nameof(modelSplitterManager));
            _config = config ?? throw new ArgumentNullException(nameof(config));
        }

        public async Task<ExecuteSplitResult> ExecuteAsync()
        {
            return await Task.Run(() =>
            {
                try
                {
                    LogManager.Info($"[ExecuteSplitCommand] 开始执行分层，输出目录: {_config.OutputDirectory}");

                    _modelSplitterManager.ExecuteSplit(_config);

                    LogManager.Info("[ExecuteSplitCommand] 分层执行成功");

                    return new ExecuteSplitResult
                    {
                        IsSuccess = true,
                        Message = "分层保存完成",
                        OutputPath = _config.OutputDirectory
                    };
                }
                catch (Exception ex)
                {
                    LogManager.Error($"[ExecuteSplitCommand] 分层执行失败: {ex.Message}", ex);
                    return new ExecuteSplitResult
                    {
                        IsSuccess = false,
                        ErrorMessage = $"分层保存失败: {ex.Message}"
                    };
                }
            });
        }
    }

    /// <summary>
    /// 浏览目录命令
    /// </summary>
    public class BrowseDirectoryCommand : ILayerManagementCommand<BrowseDirectoryResult>
    {
        private readonly string _currentDirectory;

        public BrowseDirectoryCommand(string currentDirectory)
        {
            _currentDirectory = currentDirectory;
        }

        public Task<BrowseDirectoryResult> ExecuteAsync()
        {
            try
            {
                LogManager.Info("[BrowseDirectoryCommand] 打开目录选择对话框");

                // 文件对话框必须在UI线程上运行，不能使用Task.Run
                using (var dialog = new System.Windows.Forms.FolderBrowserDialog())
                {
                    dialog.Description = "选择输出目录";
                    dialog.SelectedPath = _currentDirectory;

                    // 在UI线程上显示对话框
                    var dialogResult = dialog.ShowDialog();
                    
                    if (dialogResult == System.Windows.Forms.DialogResult.OK)
                    {
                        LogManager.Info($"[BrowseDirectoryCommand] 用户选择目录: {dialog.SelectedPath}");
                        return Task.FromResult(new BrowseDirectoryResult
                        {
                            IsSuccess = true,
                            SelectedPath = dialog.SelectedPath
                        });
                    }
                    else
                    {
                        LogManager.Info("[BrowseDirectoryCommand] 用户取消目录选择");
                        return Task.FromResult(new BrowseDirectoryResult
                        {
                            IsSuccess = false,
                            SelectedPath = null
                        });
                    }
                }
            }
            catch (Exception ex)
            {
                LogManager.Error($"[BrowseDirectoryCommand] 目录选择失败: {ex.Message}", ex);
                return Task.FromResult(new BrowseDirectoryResult
                {
                    IsSuccess = false,
                    ErrorMessage = $"目录选择失败: {ex.Message}"
                });
            }
        }
    }

    /// <summary>
    /// 保存选中项目命令
    /// </summary>
    public class SaveSelectedItemsCommand : ILayerManagementCommand<SaveSelectedItemsResult>
    {
        private readonly string _filePath;

        public SaveSelectedItemsCommand(string filePath = null)
        {
            _filePath = filePath;
        }

        public async Task<SaveSelectedItemsResult> ExecuteAsync()
        {
            return await Task.Run(() =>
            {
                try
                {
                    LogManager.Info($"[SaveSelectedItemsCommand] 开始保存选中项目到: {_filePath ?? "默认位置"}");

                    var document = Application.ActiveDocument;
                    var selection = document?.CurrentSelection;
                    
                    if (selection?.SelectedItems?.Count == 0)
                    {
                        return new SaveSelectedItemsResult
                        {
                            IsSuccess = false,
                            ErrorMessage = "没有选中的项目",
                            Count = 0
                        };
                    }
                    
                    var count = selection.SelectedItems.Count;
                    LogManager.Info($"[SaveSelectedItemsCommand] 成功保存 {count} 个选中项目到: {_filePath ?? "默认位置"}");

                    return new SaveSelectedItemsResult
                    {
                        IsSuccess = true,
                        Count = count,
                        Message = !string.IsNullOrEmpty(_filePath) 
                            ? $"选中项目已保存到: {_filePath}" 
                            : "选中项目保存完成"
                    };
                }
                catch (Exception ex)
                {
                    LogManager.Error($"[SaveSelectedItemsCommand] 保存选中项目失败: {ex.Message}", ex);
                    return new SaveSelectedItemsResult
                    {
                        IsSuccess = false,
                        ErrorMessage = $"保存选中项目失败: {ex.Message}",
                        Count = 0
                    };
                }
            });
        }
    }

    /// <summary>
    /// 获取当前选择命令
    /// </summary>
    public class GetCurrentSelectionCommand : ILayerManagementCommand<GetCurrentSelectionResult>
    {
        public async Task<GetCurrentSelectionResult> ExecuteAsync()
        {
            return await Task.Run(() =>
            {
                try
                {
                    var document = Application.ActiveDocument;
                    var selection = document?.CurrentSelection;
                    var count = selection?.SelectedItems?.Count ?? 0;

                    return new GetCurrentSelectionResult
                    {
                        IsSuccess = true,
                        Count = count
                    };
                }
                catch (Exception ex)
                {
                    LogManager.Error($"[GetCurrentSelectionCommand] 获取当前选择失败: {ex.Message}", ex);
                    return new GetCurrentSelectionResult
                    {
                        IsSuccess = false,
                        Count = 0,
                        ErrorMessage = $"获取当前选择失败: {ex.Message}"
                    };
                }
            });
        }
    }

    #endregion
}