using System;
using System.Collections.Generic;
using Autodesk.Navisworks.Api;
using NavisworksTransport.Utils;

namespace NavisworksTransport.PathPlanning
{
    /// <summary>
    /// 时标计算服务
    /// 基于路径点的限速和距离计算各路段的时间数据
    /// </summary>
    public class TimeMarkerCalculationService
    {
        /// <summary>
        /// 路段时间数据
        /// </summary>
        public class SegmentTimeData
        {
            /// <summary>
            /// 起点名称
            /// </summary>
            public string StartPointName { get; set; }

            /// <summary>
            /// 终点名称
            /// </summary>
            public string EndPointName { get; set; }

            /// <summary>
            /// 路段距离（米）
            /// </summary>
            public double Distance { get; set; }

            /// <summary>
            /// 限速（米/秒）
            /// </summary>
            public double SpeedLimit { get; set; }

            /// <summary>
            /// 路段时间（秒）
            /// </summary>
            public double Time { get; set; }

            /// <summary>
            /// 累计时间（秒）
            /// </summary>
            public double CumulativeTime { get; set; }

            /// <summary>
            /// 是否有效（有限速设置）
            /// </summary>
            public bool IsValid { get; set; }
        }

        /// <summary>
        /// 时标计算结果
        /// </summary>
        public class TimeMarkerResult
        {
            /// <summary>
            /// 路段时间数据列表
            /// </summary>
            public List<SegmentTimeData> Segments { get; set; } = new List<SegmentTimeData>();

            /// <summary>
            /// 总距离（米）
            /// </summary>
            public double TotalDistance { get; set; }

            /// <summary>
            /// 总时间（秒）
            /// </summary>
            public double TotalTime { get; set; }

            /// <summary>
            /// 有效路段数量（有限速设置的路段）
            /// </summary>
            public int ValidSegmentCount { get; set; }

            /// <summary>
            /// 是否计算成功
            /// </summary>
            public bool IsSuccessful { get; set; }

            /// <summary>
            /// 错误信息
            /// </summary>
            public string ErrorMessage { get; set; }
        }

        /// <summary>
        /// 计算路径的时标数据
        /// </summary>
        /// <param name="route">路径</param>
        /// <returns>时标计算结果</returns>
        public TimeMarkerResult CalculateTimeMarkers(PathRoute route)
        {
            var result = new TimeMarkerResult();

            try
            {
                if (route == null)
                {
                    result.ErrorMessage = "路径不能为空";
                    return result;
                }

                if (route.Points.Count < 2)
                {
                    result.ErrorMessage = "路径必须包含至少2个点";
                    return result;
                }

                LogManager.Info($"[时标计算] 开始计算路径 '{route.Name}' 的时标，包含 {route.Points.Count} 个点");

                double cumulativeTime = 0;
                double totalDistance = 0;
                int validSegments = 0;

                // 遍历相邻的路径点对，计算每段的时间
                for (int i = 0; i < route.Points.Count - 1; i++)
                {
                    var startPoint = route.Points[i];
                    var endPoint = route.Points[i + 1];

                    // 计算路段距离
                    var distance = CalculateDistance(startPoint.Position, endPoint.Position);
                    totalDistance += distance;

                    // 确定该路段的限速
                    var speedLimit = DetermineSegmentSpeedLimit(startPoint, endPoint);

                    var segmentData = new SegmentTimeData
                    {
                        StartPointName = startPoint.Name,
                        EndPointName = endPoint.Name,
                        Distance = distance,
                        SpeedLimit = speedLimit,
                        IsValid = speedLimit > 0
                    };

                    // 计算路段时间
                    if (segmentData.IsValid)
                    {
                        segmentData.Time = distance / speedLimit;
                        cumulativeTime += segmentData.Time;
                        validSegments++;
                    }
                    else
                    {
                        segmentData.Time = 0;
                        LogManager.Warning($"[时标计算] 路段 {startPoint.Name}->{endPoint.Name} 无限速设置，跳过时间计算");
                    }

                    segmentData.CumulativeTime = cumulativeTime;
                    result.Segments.Add(segmentData);

                    LogManager.Debug($"[时标计算] 路段 {i+1}: {startPoint.Name}->{endPoint.Name}, 距离:{distance:F2}m, 限速:{speedLimit:F2}m/s, 时间:{segmentData.Time:F2}s");
                }

                // 设置总计结果
                result.TotalDistance = totalDistance;
                result.TotalTime = cumulativeTime;
                result.ValidSegmentCount = validSegments;
                result.IsSuccessful = validSegments > 0;

                if (result.IsSuccessful)
                {
                    LogManager.Info($"[时标计算] 计算完成: 总距离 {totalDistance:F2}m, 总时间 {cumulativeTime:F2}s, 有效路段 {validSegments}/{result.Segments.Count}");
                }
                else
                {
                    result.ErrorMessage = "没有找到任何有效的限速设置，无法计算时间";
                    LogManager.Warning($"[时标计算] {result.ErrorMessage}");
                }

                return result;
            }
            catch (Exception ex)
            {
                result.ErrorMessage = $"计算时标时发生错误: {ex.Message}";
                LogManager.Error($"[时标计算] {result.ErrorMessage}", ex);
                return result;
            }
        }

        /// <summary>
        /// 确定路段的限速
        /// 使用起点和终点限速的最小值作为路段限速
        /// </summary>
        /// <param name="startPoint">起点</param>
        /// <param name="endPoint">终点</param>
        /// <returns>路段限速（米/秒）</returns>
        private double DetermineSegmentSpeedLimit(PathPoint startPoint, PathPoint endPoint)
        {
            // 如果起点或终点任一没有限速设置，返回0
            if (startPoint.SpeedLimit <= 0 || endPoint.SpeedLimit <= 0)
            {
                return 0;
            }

            // 使用两点限速的最小值作为路段限速（更安全的策略）
            return Math.Min(startPoint.SpeedLimit, endPoint.SpeedLimit);
        }

        /// <summary>
        /// 计算两点间距离
        /// </summary>
        /// <param name="point1">第一个点</param>
        /// <param name="point2">第二个点</param>
        /// <returns>距离（米）</returns>
        private double CalculateDistance(Point3D point1, Point3D point2)
        {
            var dx = point1.X - point2.X;
            var dy = point1.Y - point2.Y;
            var dz = point1.Z - point2.Z;
            var distanceInModelUnits = Math.Sqrt(dx * dx + dy * dy + dz * dz);
            return UnitsConverter.ConvertToMeters(distanceInModelUnits);
        }

        /// <summary>
        /// 格式化时间为可读字符串
        /// </summary>
        /// <param name="timeInSeconds">时间（秒）</param>
        /// <returns>格式化的时间字符串</returns>
        public static string FormatTime(double timeInSeconds)
        {
            if (timeInSeconds <= 0)
                return "0秒";

            var timeSpan = TimeSpan.FromSeconds(timeInSeconds);

            if (timeSpan.TotalHours >= 1)
            {
                return $"{timeSpan.Hours}小时{timeSpan.Minutes}分{timeSpan.Seconds}秒";
            }
            else if (timeSpan.TotalMinutes >= 1)
            {
                return $"{timeSpan.Minutes}分{timeSpan.Seconds}秒";
            }
            else
            {
                return $"{timeSpan.TotalSeconds:F1}秒";
            }
        }

        /// <summary>
        /// 生成时标计算报告
        /// </summary>
        /// <param name="result">计算结果</param>
        /// <returns>报告字符串</returns>
        public static string GenerateReport(TimeMarkerResult result)
        {
            if (result == null || !result.IsSuccessful)
            {
                return $"时标计算失败: {result?.ErrorMessage ?? "未知错误"}";
            }

            var report = "=== 路径时标计算报告 ===\n";
            report += $"总距离: {result.TotalDistance:F2}米\n";
            report += $"总时间: {FormatTime(result.TotalTime)}\n";
            report += $"有效路段: {result.ValidSegmentCount}/{result.Segments.Count}\n\n";

            report += "路段详情:\n";
            for (int i = 0; i < result.Segments.Count; i++)
            {
                var segment = result.Segments[i];
                var status = segment.IsValid ? "" : " (无限速)";
                report += $"{i + 1}. {segment.StartPointName} -> {segment.EndPointName}\n";
                report += $"   距离: {segment.Distance:F2}m, 限速: {segment.SpeedLimit:F2}m/s, 时间: {FormatTime(segment.Time)}{status}\n";
                report += $"   累计时间: {FormatTime(segment.CumulativeTime)}\n\n";
            }

            return report;
        }
    }
}