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 AutoPathPlanningParameters
    {
        /// <summary>
        /// 起点位置
        /// </summary>
        public Point3D StartPoint { get; set; }

        /// <summary>
        /// 终点位置
        /// </summary>
        public Point3D EndPoint { get; set; }

        /// <summary>
        /// 物体长度（米）
        /// </summary>
        public double ObjectLengthMeters { get; set; } = 1.0;

        /// <summary>
        /// 物体宽度（米）
        /// </summary>
        public double ObjectWidthMeters { get; set; } = 1.0;

        /// <summary>
        /// 物体高度（米）
        /// </summary>
        public double ObjectHeightMeters { get; set; } = 2.0;

        /// <summary>
        /// 安全边距（米）
        /// </summary>
        public double SafetyMarginMeters { get; set; } = 0.5;

        /// <summary>
        /// 网格大小（米），-1表示自动选择
        /// </summary>
        public double GridSizeMeters { get; set; } = -1;

        /// <summary>
        /// 路径名称
        /// </summary>
        public string PathName { get; set; }

        /// <summary>
        /// 是否自动绘制可视化
        /// </summary>
        public bool AutoDrawVisualization { get; set; } = true;

        /// <summary>
        /// 路径规划策略（默认为最短路径）
        /// </summary>
        public PathStrategy Strategy { get; set; } = PathStrategy.Shortest;

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

            if (StartPoint == null)
                errors.Add("起点不能为空");

            if (EndPoint == null)
                errors.Add("终点不能为空");

            if (ObjectLengthMeters <= 0 || ObjectLengthMeters > 20)
                errors.Add("物体长度必须在0-20米之间");

            if (ObjectWidthMeters <= 0 || ObjectWidthMeters > 10)
                errors.Add("物体宽度必须在0-10米之间");

            if (ObjectHeightMeters <= 0 || ObjectHeightMeters > 10)
                errors.Add("物体高度必须在0-10米之间");

            if (SafetyMarginMeters < 0 || SafetyMarginMeters > 5)
                errors.Add("安全边距必须在0-5米之间");

            if (GridSizeMeters > 0 && (GridSizeMeters < 0.01 || GridSizeMeters > 5.0))
                errors.Add("网格精度必须在0.01-5.0米之间");

            if (string.IsNullOrWhiteSpace(PathName))
                PathName = $"自动路径_{DateTime.Now:HHmmss}";

            if (StartPoint != null && EndPoint != null)
            {
                var distance = CalculateDistance(StartPoint, EndPoint);
                if (distance < 0.1)
                    errors.Add("起点和终点距离过近（小于0.1米）");
            }

            return errors.Count == 0 
                ? PathPlanningResult.Success("参数验证通过") 
                : PathPlanningResult.ValidationFailure(string.Join("; ", errors));
        }

        /// <summary>
        /// 计算两点之间的距离
        /// </summary>
        private double CalculateDistance(Point3D p1, Point3D p2)
        {
            var dx = p1.X - p2.X;
            var dy = p1.Y - p2.Y;
            var dz = p1.Z - p2.Z;
            return Math.Sqrt(dx * dx + dy * dy + dz * dz);
        }
    }

    /// <summary>
    /// 自动路径规划命令结果
    /// </summary>
    public class AutoPathPlanningResult
    {
        /// <summary>
        /// 生成的路径
        /// </summary>
        public PathRoute GeneratedRoute { get; set; }

        /// <summary>
        /// 路径长度（米）
        /// </summary>
        public double PathLength { get; set; }

        /// <summary>
        /// 路径点数量
        /// </summary>
        public int PathPointCount { get; set; }

        /// <summary>
        /// 计算耗时（毫秒）
        /// </summary>
        public long ComputationTimeMs { get; set; }

        /// <summary>
        /// 使用的网格大小
        /// </summary>
        public double UsedGridSize { get; set; }

        /// <summary>
        /// 算法统计信息
        /// </summary>
        public string AlgorithmStatistics { get; set; }

        /// <summary>
        /// 警告信息
        /// </summary>
        public List<string> Warnings { get; set; } = new List<string>();
    }

    /// <summary>
    /// 自动路径规划命令实现
    /// 展示Command Pattern在路径规划业务中的应用
    /// </summary>
    public class AutoPathPlanningCommand : CommandBase
    {
        #region 字段和属性

        private readonly AutoPathPlanningParameters _parameters;
        private readonly PathPlanningManager _pathPlanningManager;
        private readonly UIStateManager _uiStateManager;

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

        #endregion

        #region 构造函数

        /// <summary>
        /// 初始化自动路径规划命令
        /// </summary>
        /// <param name="parameters">路径规划参数</param>
        /// <param name="pathPlanningManager">路径规划管理器</param>
        public AutoPathPlanningCommand(AutoPathPlanningParameters parameters, PathPlanningManager pathPlanningManager = null)
            : base("AutoPathPlanning", "自动路径规划", "使用A*算法自动规划最优路径")
        {
            _parameters = parameters ?? throw new ArgumentNullException(nameof(parameters));
            _pathPlanningManager = pathPlanningManager ?? throw new ArgumentNullException(nameof(pathPlanningManager));
            _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;
                }

                // 验证PathPlanningManager状态
                if (_pathPlanningManager == null)
                {
                    return PathPlanningResult.ValidationFailure("路径规划管理器未初始化");
                }

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

                // 基本验证：检查通道选择状态
                if (_pathPlanningManager.SelectedChannels.Count == 0)
                {
                    return PathPlanningResult.ValidationFailure("没有选择可通行的通道模型，请先选择通道");
                }

                // 验证起点终点距离
                var distance = CalculateDistance(_parameters.StartPoint, _parameters.EndPoint);
                if (distance > 1000) // 距离过远可能导致计算时间过长
                {
                    LogWarning($"起点和终点距离较远({distance:F2}米)，可能需要较长的计算时间");
                }

                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 actualGridSize = _parameters.GridSizeMeters > 0 ? _parameters.GridSizeMeters : -1;
                LogInfo($"使用参数 - 起点: ({_parameters.StartPoint.X:F2}, {_parameters.StartPoint.Y:F2}), " +
                       $"终点: ({_parameters.EndPoint.X:F2}, {_parameters.EndPoint.Y:F2}), " +
                       $"物体宽度: {_parameters.ObjectWidthMeters}米, 安全边距: {_parameters.SafetyMarginMeters}米, " +
                       $"网格大小: {(actualGridSize > 0 ? $"用户设置 {actualGridSize:F2}米" : "自动选择")}");

                // 第三阶段：执行路径规划（30% - 80%）
                UpdateProgress(30, "正在计算最优路径...");
                ThrowIfCancellationRequested(cancellationToken);

                PathRoute generatedRoute = null;
                
                // 调用PathPlanningManager的真实A*算法进行路径规划
                try
                {
                    LogInfo("开始调用PathPlanningManager进行A*路径规划");
                    
                    // 创建起点和终点对象
                    var startPathPoint = new PathPoint
                    {
                        Name = "起点",
                        Position = _parameters.StartPoint,
                        Type = PathPointType.StartPoint
                    };
                    
                    var endPathPoint = new PathPoint
                    {
                        Name = "终点", 
                        Position = _parameters.EndPoint,
                        Type = PathPointType.EndPoint
                    };
                    
                    // 计算物体半径：基于长度和宽度的较大值的一半
                    var objectRadius = Math.Max(_parameters.ObjectLengthMeters, _parameters.ObjectWidthMeters) / 2.0;
                    LogInfo($"使用物体半径: {objectRadius}m（基于物体长度{_parameters.ObjectLengthMeters}m和宽度{_parameters.ObjectWidthMeters}m的较大值）");
                    
                    // 调用PathPlanningManager的AutoPlanPath方法执行真实的A*算法
                    var pathPlanTask = _pathPlanningManager.AutoPlanPath(
                        startPathPoint, 
                        endPathPoint, 
                        objectRadius, 
                        _parameters.SafetyMarginMeters, 
                        actualGridSize,
                        _parameters.ObjectHeightMeters,  // 使用参数中的物体高度
                        _parameters.Strategy);      // 使用参数中指定的路径策略
                        
                    generatedRoute = await pathPlanTask;
                    
                    if (generatedRoute == null)
                    {
                        throw new Exception("PathPlanningManager未能生成有效路径");
                    }
                    
                    // 如果指定了路径名称，则更新路径名称
                    if (!string.IsNullOrWhiteSpace(_parameters.PathName))
                    {
                        generatedRoute.Name = _parameters.PathName;
                    }
                    
                    LogInfo($"A*算法路径规划完成: {generatedRoute.Name}，包含 {generatedRoute.Points.Count} 个点，长度 {generatedRoute.TotalLength:F2}米");
                }
                catch (Exception ex)
                {
                    LogError($"调用PathPlanningManager进行A*路径规划失败: {ex.Message}", ex);
                    throw;
                }

                if (generatedRoute == null)
                {
                    return PathPlanningResult.Failure("路径规划失败：未能生成有效路径");
                }

                UpdateProgress(70, "路径规划完成，正在处理结果...");
                ThrowIfCancellationRequested(cancellationToken);

                // 第四阶段：设置路径名称（80%）
                if (!string.IsNullOrWhiteSpace(_parameters.PathName))
                {
                    generatedRoute.Name = _parameters.PathName;
                }

                UpdateProgress(80, "正在应用路径配置...");
                LogInfo($"生成路径成功：{generatedRoute.Name}，包含 {generatedRoute.Points.Count} 个点，总长度 {generatedRoute.TotalLength:F2} 米");

                // 第五阶段：添加路径到管理器（90%）
                if (_parameters.AutoDrawVisualization)
                {
                    UpdateProgress(90, "正在添加路径到管理器...");
                    ThrowIfCancellationRequested(cancellationToken);

                    await _uiStateManager.ExecuteUIUpdateAsync(() =>
                    {
                        try
                        {
                            _pathPlanningManager.AddRoute(generatedRoute);
                            LogInfo("路径已添加到管理器");
                        }
                        catch (Exception ex)
                        {
                            LogWarning($"添加路径到管理器失败: {ex.Message}");
                        }
                    });
                }

                // 完成（100%）
                UpdateProgress(100, "自动路径规划完成");

                var elapsedMs = (DateTime.UtcNow - startTime).TotalMilliseconds;
                LogInfo($"自动路径规划执行完成，总耗时: {elapsedMs:F0}ms");

                // 创建结果对象
                var result = PathPlanningResult<AutoPathPlanningResult>.Success(
                    new AutoPathPlanningResult
                    {
                        GeneratedRoute = generatedRoute,
                        PathLength = generatedRoute.TotalLength,
                        PathPointCount = generatedRoute.Points.Count,
                        ComputationTimeMs = (long)elapsedMs,
                        UsedGridSize = actualGridSize > 0 ? actualGridSize : 0.5, // 实际使用的网格大小
                        AlgorithmStatistics = $"A*算法路径规划完成，生成{generatedRoute.Points.Count}个路径点"
                    },
                    $"自动路径规划成功完成：{generatedRoute.Name}"
                );

                result.ElapsedMilliseconds = (long)elapsedMs;
                return result;
            }
            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>
        private double CalculateDistance(Point3D p1, Point3D p2)
        {
            var dx = p1.X - p2.X;
            var dy = p1.Y - p2.Y;
            var dz = p1.Z - p2.Z;
            return Math.Sqrt(dx * dx + dy * dy + dz * dz);
        }

        #endregion

        #region 公共方法

        /// <summary>
        /// 创建自动路径规划命令的快捷方法
        /// </summary>
        /// <param name="startPoint">起点</param>
        /// <param name="endPoint">终点</param>
        /// <param name="objectSize">物体尺寸（应用于长度和宽度）</param>
        /// <param name="pathName">路径名称</param>
        /// <param name="objectHeight">物体高度（可选，默认2.0米）</param>
        /// <param name="strategy">路径策略（可选，默认最短路径）</param>
        /// <returns>自动路径规划命令实例</returns>
        public static AutoPathPlanningCommand CreateQuick(Point3D startPoint, Point3D endPoint, 
            double objectSize = 1.0, string pathName = null, double objectHeight = 2.0, PathStrategy strategy = PathStrategy.Shortest)
        {
            var parameters = new AutoPathPlanningParameters
            {
                StartPoint = startPoint,
                EndPoint = endPoint,
                ObjectLengthMeters = objectSize,
                ObjectWidthMeters = objectSize,
                ObjectHeightMeters = objectHeight,
                SafetyMarginMeters = 0.5,
                GridSizeMeters = -1, // 自动选择
                PathName = pathName,
                AutoDrawVisualization = true,
                Strategy = strategy
            };

            return new AutoPathPlanningCommand(parameters);
        }

        /// <summary>
        /// 获取命令执行摘要信息
        /// </summary>
        /// <returns>命令信息摘要</returns>
        public string GetExecutionSummary()
        {
            return $"自动路径规划命令 - 起点:({_parameters.StartPoint?.X:F1}, {_parameters.StartPoint?.Y:F1}), " +
                   $"终点:({_parameters.EndPoint?.X:F1}, {_parameters.EndPoint?.Y:F1}), " +
                   $"物体尺寸:长{_parameters.ObjectLengthMeters}×宽{_parameters.ObjectWidthMeters}×高{_parameters.ObjectHeightMeters}米, " +
                   $"状态:{Status}";
        }

        #endregion
    }
}