using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Autodesk.Navisworks.Api;
using NavisworksTransport.Core;
using NavisworksTransport.PathPlanning;
using NavisworksTransport.Utils;
using NavisworksTransport.Core.Config;

namespace NavisworksTransport.Commands
{
    /// <summary>
    /// 创建空中路径命令（空轨或吊装）
    /// </summary>
    public class CreateAerialPathCommand : CommandBase
    {
        private readonly AerialPathParameters _parameters;
        private readonly PathPlanningManager _pathPlanningManager;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="parameters">空中路径参数</param>
        public CreateAerialPathCommand(AerialPathParameters parameters)
        {
            _parameters = parameters ?? throw new ArgumentNullException(nameof(parameters));
            _pathPlanningManager = PathPlanningManager.Instance;
        }

        /// <summary>
        /// 执行命令
        /// </summary>
        protected override Task<PathPlanningResult> ExecuteInternalAsync(CancellationToken cancellationToken)
        {
            try
            {
                // 验证参数
                var validationResult = ValidateParameters();
                if (!validationResult.IsSuccess)
                {
                    return Task.FromResult<PathPlanningResult>(validationResult);
                }

                string pathTypeName = _parameters.PathType == PathType.Hoisting ? "吊装" : "空轨";
                LogManager.Info($"开始创建{pathTypeName}路径...");

                List<PathPoint> pathPoints;

                if (_parameters.PathType == PathType.Hoisting)
                {
                    var generator = new AerialPathGenerator();

                    if (_parameters.HoistingMode == HoistingMode.MultiLevel && 
                        _parameters.HoistingLevels != null && 
                        _parameters.HoistingLevels.Count > 0)
                    {
                        // 多层阶梯式吊装
                        pathPoints = generator.GenerateMultiLevelHoistingPath(
                            _parameters.StartPoint,
                            _parameters.EndPoint,
                            _parameters.HoistingLevels);

                        LogManager.Info($"多层吊装路径: 起点=({_parameters.StartPoint.X:F2},{_parameters.StartPoint.Y:F2},{_parameters.StartPoint.Z:F2}), " +
                                       $"终点=({_parameters.EndPoint.X:F2},{_parameters.EndPoint.Y:F2},{_parameters.EndPoint.Z:F2}), " +
                                       $"层级数={_parameters.HoistingLevels.Count}, 总点数={pathPoints.Count}");
                    }
                    else
                    {
                        // 单层吊装（传统模式，默认）
                        double liftHeightModelUnits = UnitsConverter.ConvertFromMeters(_parameters.LiftHeightMeters);
                        pathPoints = generator.GenerateThreeStepHoistingPath(
                            _parameters.StartPoint,
                            _parameters.EndPoint,
                            liftHeightModelUnits);

                        LogManager.Info($"单层吊装路径: 起点=({_parameters.StartPoint.X:F2},{_parameters.StartPoint.Y:F2},{_parameters.StartPoint.Z:F2}), " +
                                       $"终点=({_parameters.EndPoint.X:F2},{_parameters.EndPoint.Y:F2},{_parameters.EndPoint.Z:F2}), " +
                                       $"提升高度={_parameters.LiftHeightMeters:F2}米");
                    }
                }
                else
                {
                    // 空轨：使用现有的空轨吸附逻辑，从点击点生成路径点
                    pathPoints = GenerateRailPathPoints(_parameters.ClickedPoints);

                    LogManager.Info($"空轨路径: 路径点数={pathPoints.Count}");
                }

                // 创建路径对象
                string routeName = _parameters.PathType == PathType.Hoisting 
                    ? $"吊装路径_{DateTime.Now:HHmmss}" 
                    : $"空轨路径_{DateTime.Now:HHmmss}";
                    
                var route = new PathRoute(routeName)
                {
                    PathType = _parameters.PathType,
                    LiftHeight = _parameters.PathType == PathType.Hoisting ? UnitsConverter.ConvertFromMeters(_parameters.LiftHeightMeters) : 0,
                    Points = pathPoints,
                    CreatedTime = DateTime.Now,
                    LastModified = DateTime.Now
                };

                // 设置物体参数（从配置获取，转换为模型单位）
                var config = ConfigManager.Instance.Current;
                route.MaxObjectLength = config.PathEditing.ObjectLength;
                route.MaxObjectWidth = config.PathEditing.ObjectWidth;
                route.MaxObjectHeight = config.PathEditing.ObjectHeight;
                route.SafetyMargin = config.PathEditing.SafetyMargin;

                // 注意：TotalLength 由计算属性实时提供，无需手动设置
                // 它会自动从 Points 计算直线距离

                LogManager.Info($"{pathTypeName}路径创建成功: {route.Name}, 路径点数: {pathPoints.Count}, 总长度: {route.TotalLength:F2}米");

                // 保存路径到数据库
                _pathPlanningManager.AddRoute(route);

                var genericResult = PathPlanningResult<PathRoute>.Success(route, $"{pathTypeName}路径创建成功");
                return Task.FromResult<PathPlanningResult>(genericResult);
            }
            catch (Exception ex)
            {
                LogManager.Error($"创建空中路径失败: {ex.Message}", ex);
                var genericResult = PathPlanningResult<PathRoute>.Failure($"创建空中路径失败: {ex.Message}", ex);
                return Task.FromResult<PathPlanningResult>(genericResult);
            }
        }

        /// <summary>
        /// 验证参数
        /// </summary>
        protected override PathPlanningResult ValidateParameters()
        {
            if (_parameters.PathType == PathType.Hoisting)
            {
                if (_parameters.StartPoint == null)
                    return PathPlanningResult.ValidationFailure("起点不能为空");

                if (_parameters.EndPoint == null)
                    return PathPlanningResult.ValidationFailure("终点不能为空");

                // 单层模式：检查 LiftHeightMeters
                // 多层模式：检查 HoistingLevels
                if (_parameters.HoistingMode == HoistingMode.SingleLevel)
                {
                    if (_parameters.LiftHeightMeters <= 0)
                        return PathPlanningResult.ValidationFailure("提升高度必须大于0");
                }
                else if (_parameters.HoistingMode == HoistingMode.MultiLevel)
                {
                    if (_parameters.HoistingLevels == null || _parameters.HoistingLevels.Count == 0)
                        return PathPlanningResult.ValidationFailure("请至少设置一个吊装层级");
                    
                    // 检查每个层级的高度
                    foreach (var level in _parameters.HoistingLevels)
                    {
                        if (level.HeightInMeters <= 0)
                            return PathPlanningResult.ValidationFailure($"层级{level.Index + 1}的高度必须大于0");
                    }
                }
            }
            else if (_parameters.PathType == PathType.Rail)
            {
                if (_parameters.ClickedPoints == null || _parameters.ClickedPoints.Count == 0)
                    return PathPlanningResult.ValidationFailure("点击点不能为空");
            }

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

        /// <summary>
        /// 从点击点生成空轨路径点（使用现有的空轨吸附逻辑）
        /// </summary>
        private List<PathPoint> GenerateRailPathPoints(List<Point3D> clickedPoints)
        {
            var pathPoints = new List<PathPoint>();

            for (int i = 0; i < clickedPoints.Count; i++)
            {
                var point = clickedPoints[i];
                var pointType = PathPointType.WayPoint;

                if (i == 0)
                    pointType = PathPointType.StartPoint;
                else if (i == clickedPoints.Count - 1)
                    pointType = PathPointType.EndPoint;

                pathPoints.Add(new PathPoint(
                    point,
                    $"路径点{i + 1}",
                    pointType));
            }

            return pathPoints;
        }
    }

    /// <summary>
    /// 空中路径参数
    /// </summary>
    public class AerialPathParameters
    {
        /// <summary>
        /// 路径类型（空轨或吊装）
        /// </summary>
        public PathType PathType { get; set; }

        /// <summary>
        /// 吊装参数：起点（吊起位置）
        /// </summary>
        public Point3D StartPoint { get; set; }

        /// <summary>
        /// 吊装参数：终点（下降位置）
        /// </summary>
        public Point3D EndPoint { get; set; }

        /// <summary>
        /// 吊装参数：提升高度（米）
        /// 单层吊装模式使用，多层模式下该值被忽略
        /// </summary>
        public double LiftHeightMeters { get; set; }

        /// <summary>
        /// 空轨参数：点击点列表
        /// </summary>
        public List<Point3D> ClickedPoints { get; set; }

        /// <summary>
        /// 吊装路径模式（默认单层，向后兼容）
        /// </summary>
        public HoistingMode HoistingMode { get; set; } = HoistingMode.SingleLevel;

        /// <summary>
        /// 多层吊装：层级信息列表（仅多层模式使用）
        /// </summary>
        public List<HoistingLevel> HoistingLevels { get; set; }

        /// <summary>
        /// 默认构造函数
        /// </summary>
        public AerialPathParameters()
        {
            HoistingMode = HoistingMode.SingleLevel;
            HoistingLevels = new List<HoistingLevel>();
            ClickedPoints = new List<Point3D>();
        }
    }
}
