using System;
using System.Collections.Generic;
using System.Xml.Serialization;
using Autodesk.Navisworks.Api;
using System.Text;
using System.Linq;
using System.IO;
using NavisworksTransport.Utils;
using NavisworksTransport.Core.Config;

namespace NavisworksTransport
{
    /// <summary>
    /// 路径编辑状态枚举
    /// </summary>
    public enum PathEditState
    {
        /// <summary>
        /// 无状态 - 默认状态
        /// </summary>
        None,
        
        /// <summary>
        /// 查看状态 - 只能查看路径，不能编辑
        /// </summary>
        Viewing,
        
        /// <summary>
        /// 新建状态 - 正在创建新路径
        /// </summary>
        Creating,
        
        /// <summary>
        /// 编辑状态 - 正在编辑现有路径
        /// </summary>
        Editing,
        
        /// <summary>
        /// 添加路径点状态 - 正在添加路径点
        /// </summary>
        AddingPoints,
        
        /// <summary>
        /// 修改路径点状态 - 正在修改现有路径点
        /// </summary>
        EditingPoint
    }

    /// <summary>
    /// 路径类型枚举 - 分离空轨和吊装为独立类型
    /// </summary>
    public enum PathType
    {
        /// <summary>
        /// 地面路径 - 物体在地面运行
        /// </summary>
        Ground = 0,

        /// <summary>
        /// 空轨路径 - 物体沿空轨移动（可能有坡度），可以获取中心线并吸附
        /// </summary>
        Rail = 1,

        /// <summary>
        /// 吊装路径 - 起点吊起 → 平移 → 终点吊下
        /// </summary>
        Hoisting = 2,

        /// <summary>
        /// 自由路径 - 任意多点，每个路径点即物体包围盒中心，轨迹即物体中心
        /// </summary>
        Free = 3
    }

    /// <summary>
    /// PathType枚举扩展方法
    /// </summary>
    public static class PathTypeExtensions
    {
        /// <summary>
        /// 获取路径类型的中文名称
        /// </summary>
        public static string GetDisplayName(this PathType pathType)
        {
            switch (pathType)
            {
                case PathType.Ground:
                    return "地面";
                case PathType.Rail:
                    return "空轨";
                case PathType.Hoisting:
                    return "吊装";
                case PathType.Free:
                    return "自由";
                default:
                    return "未知";
            }
        }
    }

    /// <summary>
    /// 吊装路径点方向类型
    /// 用于标识吊装路径中每个路径点的移动方向
    /// </summary>
    public enum HoistingPointDirection
    {
        /// <summary>
        /// 垂直移动（起吊/下降）
        /// </summary>
        Vertical,

        /// <summary>
        /// 纵向移动（X轴方向）
        /// </summary>
        Longitudinal,

        /// <summary>
        /// 横向移动（Y轴方向）
        /// </summary>
        Lateral
    }

    /// <summary>
    /// Rail 路径安装方式
    /// </summary>
    public enum RailMountMode
    {
        /// <summary>
        /// 轨下安装
        /// </summary>
        UnderRail = 0,

        /// <summary>
        /// 轨上安装
        /// </summary>
        OverRail = 1
    }

    /// <summary>
    /// Rail 路径的参考线定义方式
    /// </summary>
    public enum RailPathDefinitionMode
    {
        /// <summary>
        /// 旧版兼容模式：路径点即轨下悬挂参考点
        /// </summary>
        LegacySuspensionPoint = 0,

        /// <summary>
        /// 新版模式：路径点表示双轨参考中心线
        /// </summary>
        RailCenterLine = 1
    }

    /// <summary>
    /// 通道检测结果
    /// </summary>
    public class ChannelDetectionResult
    {
        /// <summary>
        /// 是否为有效位置
        /// </summary>
        public bool IsValidLocation { get; set; }
        
        /// <summary>
        /// 检测消息
        /// </summary>
        public string Message { get; set; }
        
        /// <summary>
        /// 检测方法
        /// </summary>
        public string DetectionMethod { get; set; }
    }
    
    /// <summary>
    /// 物流通道检测结果
    /// </summary>
    public class LogisticsChannelDetectionResult
    {
        /// <summary>
        /// 是否为有效通道
        /// </summary>
        public bool IsValidChannel { get; set; }
        
        /// <summary>
        /// 通道类型名称
        /// </summary>
        public string ChannelType { get; set; }
        
        /// <summary>
        /// 检测到的通道模型项
        /// </summary>
        public ModelItem DetectedChannel { get; set; }
        
        /// <summary>
        /// 物流类别
        /// </summary>
        public CategoryAttributeManager.LogisticsElementType? LogisticsCategory { get; set; }
        
        /// <summary>
        /// 检测置信度
        /// </summary>
        public double DetectionConfidence { get; set; }
        
        /// <summary>
        /// 错误消息
        /// </summary>
        public string ErrorMessage { get; set; }
    }
    
    /// <summary>
    /// 几何分析结果
    /// </summary>
    public class GeometryAnalysisResult
    {
        /// <summary>
        /// 是否可能是通道
        /// </summary>
        public bool IsLikelyChannel { get; set; }
        
        /// <summary>
        /// 分析原因
        /// </summary>
        public string Reason { get; set; }
        
        /// <summary>
        /// 最可能的通道模型项
        /// </summary>
        public ModelItem MostLikelyChannel { get; set; }
        
        /// <summary>
        /// 置信度
        /// </summary>
        public double Confidence { get; set; }
    }

    /// <summary>
    /// 路径规划策略枚举
    /// </summary>
    public enum PathStrategy
    {
        /// <summary>
        /// 最短路径 - 标准A*算法，所有边具有相同权重（默认策略）
        /// </summary>
        Shortest = 0,
        
        /// <summary>
        /// 直线优先路径 - 优先选择主方向的路径，减少转弯次数
        /// </summary>
        Straightest = 1,
        
        /// <summary>
        /// 安全优先路径 - 基于障碍物距离选择安全路径，适合大型物体居中行驶
        /// </summary>
        SafestCenter = 2
    }

    /// <summary>
    /// 路径点类型枚举
    /// </summary>
    public enum PathPointType
    {
        /// <summary>
        /// 起点
        /// </summary>
        StartPoint,
        
        /// <summary>
        /// 终点
        /// </summary>
        EndPoint,
        
        /// <summary>
        /// 路径点
        /// </summary>
        WayPoint,
        
        /// <summary>
        /// 中间点
        /// </summary>
        IntermediatePoint
    }

    /// <summary>
    /// 路径点数据模型
    /// </summary>
    [Serializable]
    public class PathPoint
    {
        /// <summary>
        /// 路径点唯一标识符
        /// </summary>
        public string Id { get; set; }

        /// <summary>
        /// 路径点3D位置（不参与XML序列化）
        /// </summary>
        [XmlIgnore]
        public Point3D Position { get; set; }

        /// <summary>
        /// X坐标（用于XML序列化）
        /// </summary>
        [XmlElement("X")]
        public double X 
        { 
            get => Position.X; 
            set 
            {
                if (Position == null)
                    Position = new Point3D(value, 0, 0);
                else
                    Position = new Point3D(value, Position.Y, Position.Z);
            }
        }

        /// <summary>
        /// Y坐标（用于XML序列化）
        /// </summary>
        [XmlElement("Y")]
        public double Y 
        { 
            get => Position.Y; 
            set 
            {
                if (Position == null)
                    Position = new Point3D(0, value, 0);
                else
                    Position = new Point3D(Position.X, value, Position.Z);
            }
        }

        /// <summary>
        /// Z坐标（用于XML序列化）
        /// </summary>
        [XmlElement("Z")]
        public double Z 
        { 
            get => Position.Z; 
            set 
            {
                if (Position == null)
                    Position = new Point3D(0, 0, value);
                else
                    Position = new Point3D(Position.X, Position.Y, value);
            }
        }

        /// <summary>
        /// 路径点名称
        /// </summary>
        public string Name { get; set; }
        
        /// <summary>
        /// 路径点类型
        /// </summary>
        public PathPointType Type { get; set; }
        
        /// <summary>
        /// 创建时间
        /// </summary>
        public DateTime CreatedTime { get; set; }
        
        /// <summary>
        /// 路径点序号
        /// </summary>
        public int Index { get; set; }
        
        /// <summary>
        /// 备注信息
        /// </summary>
        public string Notes { get; set; }
        /// <summary>
        /// 限速（米/秒），0表示未设置限速
        /// </summary>
        public double SpeedLimit { get; set; }

        /// <summary>
        /// 自定义转向半径（模型单位），用于局部急转弯场景
        /// 为 null 时使用全局默认值
        /// </summary>
        public double? CustomTurnRadius { get; set; }

        /// <summary>
        /// 仅用于视图显示的点直径（模型单位）。
        /// 为 null 或非正数时使用默认点类型尺寸。
        /// </summary>
        [XmlIgnore]
        public double? VisualizationDiameter { get; set; }

        /// <summary>
        /// 方向类型（仅吊装路径使用）
        /// 用于标识吊装路径点的移动方向：垂直、纵向（X轴）、横向（Y轴）
        /// </summary>
        public HoistingPointDirection Direction { get; set; } = HoistingPointDirection.Vertical;

        /// <summary>
        /// 构造函数
        /// </summary>
        public PathPoint()
        {
            Id = Guid.NewGuid().ToString();
            Position = new Point3D();
            Name = string.Empty;
            Type = PathPointType.WayPoint;
            CreatedTime = DateTime.Now;
            Index = 0;
            Notes = string.Empty;
            SpeedLimit = 0;
            CustomTurnRadius = null;
            VisualizationDiameter = null;
            Direction = HoistingPointDirection.Vertical;
        }

        /// <summary>
        /// 带参数构造函数
        /// </summary>
        /// <param name="position">3D坐标</param>
        /// <param name="name">名称</param>
        /// <param name="type">类型</param>
        public PathPoint(Point3D position, string name, PathPointType type)
        {
            Id = Guid.NewGuid().ToString();
            Position = position;
            Name = name;
            Type = type;
            CreatedTime = DateTime.Now;
            Index = 0;
            Notes = string.Empty;
            SpeedLimit = 0;
            CustomTurnRadius = null;
            VisualizationDiameter = null;
            Direction = HoistingPointDirection.Vertical;
        }

        /// <summary>
        /// 解析最终用于渲染的点半径（模型单位）。
        /// </summary>
        /// <param name="defaultRadius">默认点半径（模型单位）</param>
        /// <returns>最终半径（模型单位）</returns>
        public double ResolveVisualizationRadius(double defaultRadius)
        {
            if (!VisualizationDiameter.HasValue || VisualizationDiameter.Value <= 0)
            {
                return defaultRadius;
            }

            return VisualizationDiameter.Value * 0.5;
        }

        /// <summary>
        /// 返回路径点描述字符串
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return $"{Name} ({Type}) - X:{Position.X:F2}, Y:{Position.Y:F2}, Z:{Position.Z:F2}";
        }
    }

    /// <summary>
    /// 路径段类型
    /// </summary>
    public enum PathSegmentType
    {
        /// <summary>
        /// 直线段
        /// </summary>
        Straight,

        /// <summary>
        /// 圆弧段
        /// </summary>
        Arc
    }

    /// <summary>
    /// 圆弧轨迹数据
    /// </summary>
    [Serializable]
    public class ArcTrajectory
    {
        /// <summary>
        /// 进入切点
        /// </summary>
        public Point3D Ts { get; set; }

        /// <summary>
        /// 退出切点
        /// </summary>
        public Point3D Te { get; set; }

        /// <summary>
        /// 圆心位置
        /// </summary>
        public Point3D ArcCenter { get; set; }

        /// <summary>
        /// 请求半径（配置的转向半径）
        /// </summary>
        public double RequestedRadius { get; set; }

        /// <summary>
        /// 实际半径（安全截断后）
        /// </summary>
        public double ActualRadius { get; set; }

        /// <summary>
        /// 偏转角（弧度）
        /// </summary>
        public double DeflectionAngle { get; set; }

        /// <summary>
        /// 圆弧长度（米）
        /// </summary>
        public double ArcLength { get; set; }
    }

    /// <summary>
    /// 路径边 - 连接两个连续控制点的物理路径段
    /// </summary>
    [Serializable]
    public class PathEdge
    {
        /// <summary>
        /// 边唯一标识符
        /// </summary>
        public string Id { get; set; }

        /// <summary>
        /// 起始控制点ID
        /// </summary>
        public string StartPointId { get; set; }

        /// <summary>
        /// 结束控制点ID
        /// </summary>
        public string EndPointId { get; set; }

        /// <summary>
        /// 路径段类型
        /// </summary>
        public PathSegmentType SegmentType { get; set; }

        /// <summary>
        /// 圆弧轨迹数据（仅当 SegmentType == Arc 时有效）
        /// </summary>
        public ArcTrajectory Trajectory { get; set; }

        /// <summary>
        /// 边的物理长度（米）
        /// 直线段：两点间距离；圆弧段：直线段长度 + 圆弧长度
        /// </summary>
        public double PhysicalLength { get; set; }

        /// <summary>
        /// 采样点序列（用于碰撞检测和动画）
        /// </summary>
        [XmlIgnore]
        public List<Point3D> SampledPoints { get; set; }

        public PathEdge()
        {
            Id = Guid.NewGuid().ToString();
            SampledPoints = new List<Point3D>();
        }
    }

    /// <summary>
    /// 路径路线数据模型
    /// </summary>
    [Serializable]
    public class PathRoute
    {
        public static bool IsTopReferenceFaceForMountMode(RailMountMode railMountMode)
        {
            return railMountMode == RailMountMode.UnderRail;
        }

        /// <summary>
        /// 路径点集合（控制点）
        /// </summary>
        public List<PathPoint> Points { get; set; }

        /// <summary>
        /// 路径边集合 - 存储物理路径段
        /// </summary>
        public List<PathEdge> Edges { get; set; }

        /// <summary>
        /// 路径名称
        /// </summary>
        public string Name { get; set; }
        
        /// <summary>
        /// 路径ID
        /// </summary>
        public string Id { get; set; }
        
        /// <summary>
        /// 预估时间（秒）
        /// </summary>
        public double EstimatedTime { get; set; }
        
        /// <summary>
        /// 关联通道模型ID集合
        /// </summary>
        public List<string> AssociatedChannelIds { get; set; }
        
        /// <summary>
        /// 路径总长度（米）- 只读计算属性
        /// 
        /// 【重要】此属性实时从几何数据计算，不从数据库存储或加载。
        /// 数据库中的 TotalLength 字段已废弃，保留仅用于兼容旧版本。
        /// 
        /// 计算方式：
        /// - 地面路径(Ground)：从 Edges.PhysicalLength 累加（支持圆弧）
        /// - 空轨路径(Rail)：从 Points 计算直线距离
        /// - 吊装路径(Hoisting)：从 Points 计算直线距离
        /// </summary>
        public double TotalLength 
        { 
            get 
            {
                if (Points.Count < 2) return 0.0;
                
                // 地面路径：优先使用 Edges（支持圆弧），否则从 Points 计算
                if (PathType == PathType.Ground)
                {
                    if (Edges.Count > 0)
                    {
                        double lengthInModelUnits = Edges.Sum(e => e.PhysicalLength);
                        return NavisworksTransport.Utils.UnitsConverter.ConvertToMeters(lengthInModelUnits);
                    }
                    return CalculateLengthFromPoints();
                }
                
                // 空轨/吊装路径：使用直线距离
                if (PathType == PathType.Rail || PathType == PathType.Hoisting)
                {
                    return CalculateLengthFromPoints();
                }
                
                // 未知类型：默认直线计算
                return CalculateLengthFromPoints();
            }
        }
        
        /// <summary>
        /// 从路径点计算直线距离总长度（辅助方法）
        /// </summary>
        private double CalculateLengthFromPoints()
        {
            double totalLength = 0.0;
            var sortedPoints = GetSortedPoints();
            
            for (int i = 0; i < sortedPoints.Count - 1; i++)
            {
                var p1 = sortedPoints[i].Position;
                var p2 = sortedPoints[i + 1].Position;
                
                double dx = p2.X - p1.X;
                double dy = p2.Y - p1.Y;
                double dz = p2.Z - p1.Z;
                double distanceInModelUnits = Math.Sqrt(dx*dx + dy*dy + dz*dz);
                
                totalLength += NavisworksTransport.Utils.UnitsConverter.ConvertToMeters(distanceInModelUnits);
            }
            
            return totalLength;
        }
        
        /// <summary>
        /// 创建时间
        /// </summary>
        public DateTime CreatedTime { get; set; }
        
        /// <summary>
        /// 最后修改时间
        /// </summary>
        public DateTime LastModified { get; set; }
        
        /// <summary>
        /// 路径描述
        /// </summary>
        public string Description { get; set; }

        /// <summary>
        /// 路径是否完整到达终点
        /// </summary>
        public bool IsComplete { get; set; }

        /// <summary>
        /// 原始终点坐标（用于显示灰色未到达点）
        /// </summary>
        public Point3D OriginalEndPoint { get; set; }

        /// <summary>
        /// 实际到达点坐标
        /// </summary>
        public Point3D ActualEndPoint { get; set; }

        /// <summary>
        /// 完成百分比（0-100）
        /// </summary>
        public double CompletionPercentage { get; set; }

        /// <summary>
        /// 关联的网格地图（用于网格可视化）
        /// </summary>
        [XmlIgnore]
        public NavisworksTransport.PathPlanning.GridMap AssociatedGridMap { get; set; }

        /// <summary>
        /// 网格大小（米）
        /// </summary>
        public double GridSize { get; set; }

        /// <summary>
        /// 最大物体长度（米） - 路径适用的物体长度限制
        /// </summary>
        public double MaxObjectLength { get; set; }

        /// <summary>
        /// 最大物体宽度（米） - 路径适用的物体宽度限制
        /// </summary>
        public double MaxObjectWidth { get; set; }

        /// <summary>
        /// 最大物体高度（米） - 路径适用的物体高度限制
        /// </summary>
        public double MaxObjectHeight { get; set; }

        /// <summary>
        /// 安全间隙（米）
        /// </summary>
        public double SafetyMargin { get; set; }

        /// <summary>
        /// 路径转弯半径（模型单位）- 路径允许的最大转弯半径
        /// 物体的最小转弯半径必须小于等于此值
        /// </summary>
        public double TurnRadius { get; set; }

        /// <summary>
        /// 是否已曲线化
        /// </summary>
        public bool IsCurved { get; set; }

        /// <summary>
        /// 路径类型
        /// </summary>
        public PathType PathType { get; set; } = PathType.Ground;

        /// <summary>
        /// 吊装的提升高度（模型单位，仅当 PathType == Hoisting 时有效）
        /// </summary>
        public double LiftHeight { get; set; }

        /// <summary>
        /// 是否为2点纯垂直路径（无水平段，仅 PathType == Hoisting 时有效）
        /// </summary>
        public bool IsTwoPointVertical { get; set; }

        /// <summary>
        /// Rail 路径安装方式（仅当 PathType == Rail 时有效）
        /// </summary>
        public RailMountMode RailMountMode { get; set; }

        /// <summary>
        /// Rail 路径参考线定义方式（仅当 PathType == Rail 时有效）
        /// </summary>
        public RailPathDefinitionMode RailPathDefinitionMode { get; set; }

        /// <summary>
        /// Rail 路径优先法向（宿主坐标）。
        /// 仅在存在显式安装面/业务法向时使用；为空时退回当前默认求解。
        /// </summary>
        public Point3D RailPreferredNormal { get; set; }

        /// <summary>
        /// Rail 安装法向偏移（模型单位）。
        /// 沿 Rail 最终法向对安装参考点施加额外偏移，用于快速微调路径。
        /// </summary>
        public double RailNormalOffset { get; set; }

        // 数据库分析相关属性
        /// <summary>
        /// 碰撞数量（从数据库加载）
        /// </summary>
        public int? CollisionCount { get; set; }

        /// <summary>
        /// 安全评分（从数据库加载）
        /// </summary>
        public double? SafetyScore { get; set; }

        /// <summary>
        /// 效率评分（从数据库加载）
        /// </summary>
        public double? EfficiencyScore { get; set; }

        /// <summary>
        /// 综合评分（从数据库加载）
        /// </summary>
        public double? OverallScore { get; set; }

        /// <summary>
        /// 构造函数
        /// </summary>
        public PathRoute()
        {
            Points = new List<PathPoint>();
            Edges = new List<PathEdge>();
            Name = string.Empty;
            Id = Guid.NewGuid().ToString();
            EstimatedTime = 0.0;
            AssociatedChannelIds = new List<string>();
            // TotalLength：计算属性，自动从几何数据计算，无需初始化
            CreatedTime = DateTime.Now;
            LastModified = DateTime.Now;
            Description = string.Empty;
            TurnRadius = 0.0;  // 0.0 表示未设置，实际使用时从配置获取默认值
            IsCurved = false;
            RailMountMode = RailMountMode.UnderRail;
            RailPathDefinitionMode = RailPathDefinitionMode.LegacySuspensionPoint;
            RailPreferredNormal = null;
            RailNormalOffset = 0.0;
        }

        /// <summary>
        /// 带参数构造函数
        /// </summary>
        /// <param name="name">路径名称</param>
        public PathRoute(string name)
        {
            Points = new List<PathPoint>();
            Edges = new List<PathEdge>();
            Name = name;
            Id = Guid.NewGuid().ToString();
            EstimatedTime = 0.0;
            AssociatedChannelIds = new List<string>();
            // TotalLength：计算属性，自动从几何数据计算，无需初始化
            CreatedTime = DateTime.Now;
            TurnRadius = 0.0;  // 0.0 表示未设置，实际使用时从配置获取默认值
            IsCurved = false;
            LastModified = DateTime.Now;
            Description = string.Empty;
            RailMountMode = RailMountMode.UnderRail;
            RailPathDefinitionMode = RailPathDefinitionMode.LegacySuspensionPoint;
            RailPreferredNormal = null;
            RailNormalOffset = 0.0;
        }

        /// <summary>
        /// 添加路径点
        /// </summary>
        /// <param name="point">路径点</param>
        public void AddPoint(PathPoint point)
        {
            Points.Add(point);
            // 调用统一更新函数（内部会重新设置索引）
            RecalculateAndSaveRoute("添加路径点");
        }

        /// <summary>
        /// 在指定位置插入路径点
        /// </summary>
        /// <param name="point">要插入的路径点</param>
        /// <param name="insertIndex">插入位置索引</param>
        public void InsertPoint(PathPoint point, int insertIndex)
        {
            Points.Insert(insertIndex, point);
            // 调用统一更新函数（内部会重新设置索引）
            RecalculateAndSaveRoute("插入路径点");
        }

        /// <summary>
        /// 移除路径点
        /// </summary>
        /// <param name="point">路径点</param>
        public bool RemovePoint(PathPoint point)
        {
            bool removed = Points.Remove(point);
            if (removed)
            {
                // 调用统一更新函数（内部会重新设置索引）
                RecalculateAndSaveRoute("移除路径点");
            }
            return removed;
        }

        /// <summary>
        /// 根据ID移除路径点
        /// </summary>
        /// <param name="pointId">路径点ID</param>
        /// <returns>是否成功移除</returns>
        public bool RemovePoint(string pointId)
        {
            var point = Points.FirstOrDefault(p => p.Id == pointId);
            if (point != null)
            {
                return RemovePoint(point);
            }
            return false;
        }

        /// <summary>
        /// 清空所有路径点
        /// </summary>
        public void ClearPoints()
        {
            Points.Clear();
            Edges.Clear();
            IsCurved = false;
            // 调用统一更新函数
            RecalculateAndSaveRoute("清空路径点");
        }

        /// <summary>
        /// 获取起点
        /// </summary>
        /// <returns></returns>
        public PathPoint GetStartPoint()
        {
            return Points.Find(p => p.Type == PathPointType.StartPoint);
        }

        /// <summary>
        /// 获取终点
        /// </summary>
        /// <returns></returns>
        public PathPoint GetEndPoint()
        {
            return Points.Find(p => p.Type == PathPointType.EndPoint);
        }

        /// <summary>
        /// 获取所有路径点（按序号排序）
        /// </summary>
        /// <returns></returns>
        public List<PathPoint> GetSortedPoints()
        {
            var sortedPoints = new List<PathPoint>(Points);
            sortedPoints.Sort((p1, p2) => p1.Index.CompareTo(p2.Index));
            return sortedPoints;
        }

        /// <summary>
        /// 重新计算路径数据（不保存到数据库）
        /// 用于路径优化等临时计算场景
        /// </summary>
        /// <param name="context">上下文信息（用于日志）</param>
        public void RecalculateRoute(string context = "路径数据更新")
        {
            if (Points.Count < 2)
            {
                LogManager.Debug($"跳过路径数据计算（路径点不足）: {Name}, 原因: {context}");
                return;
            }

            try
            {
                // 1. 重新设置路径点索引
                for (int i = 0; i < Points.Count; i++)
                {
                    Points[i].Index = i;
                }

                // 2. 根据路径类型决定是否重新计算曲线
                if (PathType == PathType.Ground)
                {
                    // 地面路径：进行曲线化
                    double samplingStep = ConfigManager.Instance.Current.PathEditing.ArcSamplingStep;
                    TurnRadius = ConfigManager.Instance.Current.PathEditing.DefaultPathTurnRadius;
                    List<string> warnings;
                    PathCurveEngine.ApplyCurvatureToRoute(this, samplingStep, out warnings);
                    LogManager.Debug($"地面路径已曲线化: {Name}, 原因: {context}, 转弯半径: {TurnRadius:F2}, 边数: {Edges.Count}");

                    // 如果有警告，记录日志
                    if (warnings != null && warnings.Count > 0)
                    {
                        foreach (var warning in warnings)
                        {
                            LogManager.Warning($"路径曲线化警告: {warning}");
                        }
                    }
                }
                else if (PathType == PathType.Rail || PathType == PathType.Hoisting)
                {
                    // 空轨/吊装路径：使用直线，不需要曲线化
                    Edges.Clear();
                    IsCurved = false;
                    string pathTypeName = PathType == PathType.Rail ? "空轨" : "吊装";
                    LogManager.Debug($"{pathTypeName}路径已更新（直线模式）: {Name}, 原因: {context}");
                }
                else
                {
                    // 未知路径类型：使用直线
                    Edges.Clear();
                    IsCurved = false;
                    LogManager.Debug($"未知路径类型，使用直线模式: {Name}, 原因: {context}");
                }

                // 3. 更新最后修改时间
                LastModified = DateTime.Now;

                LogManager.Debug($"路径数据已计算: {Name}, 原因: {context}, 总长度: {TotalLength:F2}米");
            }
            catch (Exception ex)
            {
                LogManager.Error($"路径数据计算失败（{context}）: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// 重新计算路径数据并保存到数据库
        /// 统一的路径数据更新入口：重新设置索引、更新长度、计算曲线、保存到数据库
        /// </summary>
        /// <param name="context">上下文信息（用于日志）</param>
        public void RecalculateAndSaveRoute(string context = "路径数据更新")
        {
            // 先执行计算
            RecalculateRoute(context);

            // 然后保存到数据库
            try
            {
                if (Points.Count >= 2)
                {
                    var pathPlanningManager = PathPlanningManager.Instance;
                    if (pathPlanningManager != null)
                    {
                        pathPlanningManager.SavePathToDatabase(this);
                        LogManager.Info($"路径数据已保存到数据库: {Name}, 原因: {context}, 总长度: {TotalLength:F2}米");
                    }
                }
            }
            catch (Exception ex)
            {
                LogManager.Error($"路径数据保存失败（{context}）: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// 验证路径有效性
        /// </summary>
        /// <returns></returns>
        public bool IsValid()
        {
            // 至少需要起点和终点
            if (Points.Count < 2) return false;
            
            // 必须有且仅有一个起点和一个终点
            var startPoints = Points.FindAll(p => p.Type == PathPointType.StartPoint);
            var endPoints = Points.FindAll(p => p.Type == PathPointType.EndPoint);
            
            return startPoints.Count == 1 && endPoints.Count == 1;
        }

        /// <summary>
        /// 克隆路径
        /// </summary>
        /// <returns>克隆的路径对象</returns>
        public PathRoute Clone()
        {
            var clonedRoute = new PathRoute(Name + "_Copy")
            {
                Id = Guid.NewGuid().ToString(),
                EstimatedTime = EstimatedTime,
                // TotalLength：计算属性，自动从几何数据计算，克隆时会重新计算
                CreatedTime = DateTime.Now,
                LastModified = DateTime.Now,
                Description = Description,
                AssociatedChannelIds = new List<string>(AssociatedChannelIds),
                IsComplete = IsComplete,
                OriginalEndPoint = OriginalEndPoint,
                ActualEndPoint = ActualEndPoint,
                CompletionPercentage = CompletionPercentage,
                AssociatedGridMap = AssociatedGridMap, // 共享引用，不深拷贝
                GridSize = GridSize,
                MaxObjectLength = MaxObjectLength,
                MaxObjectWidth = MaxObjectWidth,
                MaxObjectHeight = MaxObjectHeight,
                SafetyMargin = SafetyMargin,
                TurnRadius = TurnRadius,
                IsCurved = IsCurved,
                PathType = PathType,
                LiftHeight = LiftHeight,
                RailMountMode = RailMountMode,
                RailPathDefinitionMode = RailPathDefinitionMode,
                RailNormalOffset = RailNormalOffset,
                RailPreferredNormal = RailPreferredNormal
            };

            var pointIdMap = new Dictionary<string, string>();

            // 克隆所有路径点
            foreach (var point in Points)
            {
                var clonedPoint = new PathPoint(point.Position, point.Name, point.Type)
                {
                    Id = Guid.NewGuid().ToString(),
                    Index = point.Index,
                    CreatedTime = point.CreatedTime,
                    Notes = point.Notes,
                    SpeedLimit = point.SpeedLimit,
                    CustomTurnRadius = point.CustomTurnRadius,
                    VisualizationDiameter = point.VisualizationDiameter,
                    Direction = point.Direction
                };
                clonedRoute.Points.Add(clonedPoint);
                pointIdMap[point.Id] = clonedPoint.Id;
            }

            foreach (var edge in Edges)
            {
                var clonedEdge = new PathEdge
                {
                    Id = Guid.NewGuid().ToString(),
                    StartPointId = pointIdMap.ContainsKey(edge.StartPointId) ? pointIdMap[edge.StartPointId] : edge.StartPointId,
                    EndPointId = pointIdMap.ContainsKey(edge.EndPointId) ? pointIdMap[edge.EndPointId] : edge.EndPointId,
                    SegmentType = edge.SegmentType,
                    PhysicalLength = edge.PhysicalLength,
                    Trajectory = edge.Trajectory != null
                        ? new ArcTrajectory
                        {
                            Ts = edge.Trajectory.Ts,
                            Te = edge.Trajectory.Te,
                            ArcCenter = edge.Trajectory.ArcCenter,
                            RequestedRadius = edge.Trajectory.RequestedRadius,
                            ActualRadius = edge.Trajectory.ActualRadius,
                            DeflectionAngle = edge.Trajectory.DeflectionAngle,
                            ArcLength = edge.Trajectory.ArcLength
                        }
                        : null,
                    SampledPoints = edge.SampledPoints != null
                        ? new List<Point3D>(edge.SampledPoints)
                        : new List<Point3D>()
                };

                clonedRoute.Edges.Add(clonedEdge);
            }

            return clonedRoute;
        }

        /// <summary>
        /// 返回路径描述字符串
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return $"{Name} - 点数:{Points.Count}, 长度:{TotalLength:F2}m, 预估时间:{EstimatedTime:F1}s";
        }
    }

    /// <summary>
    /// 2D地图坐标
    /// </summary>
    [Serializable]
    public class MapPoint2D
    {
        /// <summary>
        /// X坐标
        /// </summary>
        public double X { get; set; }
        
        /// <summary>
        /// Y坐标
        /// </summary>
        public double Y { get; set; }

        /// <summary>
        /// 构造函数
        /// </summary>
        public MapPoint2D()
        {
            X = 0.0;
            Y = 0.0;
        }

        /// <summary>
        /// 带参数构造函数
        /// </summary>
        /// <param name="x">X坐标</param>
        /// <param name="y">Y坐标</param>
        public MapPoint2D(double x, double y)
        {
            X = x;
            Y = y;
        }

        /// <summary>
        /// 返回坐标描述字符串
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return $"({X:F2}, {Y:F2})";
        }
    }

    /// <summary>
    /// 通道边界信息
    /// </summary>
    [Serializable]
    public class ChannelBounds
    {
        /// <summary>
        /// 最小坐标点
        /// </summary>
        public Point3D MinPoint { get; set; }
        
        /// <summary>
        /// 最大坐标点
        /// </summary>
        public Point3D MaxPoint { get; set; }
        
        /// <summary>
        /// 中心点
        /// </summary>
        public Point3D Center { get; set; }
        
        /// <summary>
        /// 通道高度（Z轴方向）
        /// </summary>
        public double Height { get; set; }

        /// <summary>
        /// 构造函数
        /// </summary>
        public ChannelBounds()
        {
            MinPoint = new Point3D();
            MaxPoint = new Point3D();
            Center = new Point3D();
            Height = 0.0;
        }

        /// <summary>
        /// 带包围盒参数构造函数
        /// </summary>
        /// <param name="boundingBox">Navisworks包围盒</param>
        public ChannelBounds(BoundingBox3D boundingBox)
        {
            MinPoint = boundingBox.Min;
            MaxPoint = boundingBox.Max;
            Center = new Point3D(
                (MinPoint.X + MaxPoint.X) / 2,
                (MinPoint.Y + MaxPoint.Y) / 2,
                (MinPoint.Z + MaxPoint.Z) / 2
            );
            Height = MaxPoint.Z - MinPoint.Z;
        }

        /// <summary>
        /// 获取2D投影范围
        /// </summary>
        /// <param name="min">最小点</param>
        /// <param name="max">最大点</param>
        public void Get2DProjection(out MapPoint2D min, out MapPoint2D max)
        {
            min = new MapPoint2D(MinPoint.X, MinPoint.Y);
            max = new MapPoint2D(MaxPoint.X, MaxPoint.Y);
        }
    }

    /// <summary>
    /// 通道选择结果
    /// </summary>
    public class ChannelSelectionResult
    {
        /// <summary>
        /// 是否成功
        /// </summary>
        public bool Success { get; set; } = false;

        /// <summary>
        /// 结果消息
        /// </summary>
        public string Message { get; set; } = "";

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

        /// <summary>
        /// 自动检测的通道
        /// </summary>
        public ModelItemCollection AutoDetectedChannels { get; set; } = new ModelItemCollection();

        /// <summary>
        /// 已标记物流属性的模型项
        /// </summary>
        public ModelItemCollection LogisticsMarkedItems { get; set; } = new ModelItemCollection();

        /// <summary>
        /// 可通行区域
        /// </summary>
        public ModelItemCollection TraversableAreas { get; set; } = new ModelItemCollection();

        /// <summary>
        /// 通道类型模型项
        /// </summary>
        public ModelItemCollection ChannelItems { get; set; } = new ModelItemCollection();
    }

    /// <summary>
    /// 通道选择对话框结果
    /// </summary>
    public class ChannelSelectionDialogResult
    {
        /// <summary>
        /// 是否成功
        /// </summary>
        public bool Success { get; set; } = false;

        /// <summary>
        /// 结果消息
        /// </summary>
        public string Message { get; set; } = "";

        /// <summary>
        /// 选中的通道
        /// </summary>
        public ModelItemCollection SelectedChannels { get; set; } = new ModelItemCollection();

        /// <summary>
        /// 选择方法
        /// </summary>
        public ChannelSelectionMethod SelectionMethod { get; set; } = ChannelSelectionMethod.Manual;

        /// <summary>
        /// 高度限制（米）
        /// </summary>
        public double HeightLimit { get; set; } = 3.0;
    }

    /// <summary>
    /// 通道选择方法枚举
    /// </summary>
    public enum ChannelSelectionMethod
    {
        /// <summary>
        /// 手动选择
        /// </summary>
        Manual,

        /// <summary>
        /// 自动检测
        /// </summary>
        AutoDetect,

        /// <summary>
        /// 基于物流属性
        /// </summary>
        LogisticsAttribute,

        /// <summary>
        /// 可通行区域
        /// </summary>
        TraversableAreas,

        /// <summary>
        /// 通道类型
        /// </summary>
        ChannelType
    }

    /// <summary>
    /// 通道选择对话框
    /// </summary>
    public class ChannelSelectionDialog : System.Windows.Forms.Form
    {
        private ChannelSelectionResult _analysisResult;
        private ModelItemCollection _selectedChannels;
        private ChannelSelectionMethod _selectionMethod;
        private double _heightLimit;
        private const string ChannelPreviewHighlightCategory = "channel_preview";

        /// <summary>
        /// 选中的通道
        /// </summary>
        public ModelItemCollection SelectedChannels { get { return _selectedChannels; } }

        /// <summary>
        /// 选择方法
        /// </summary>
        public ChannelSelectionMethod SelectionMethod { get { return _selectionMethod; } }

        /// <summary>
        /// 高度限制（米）
        /// </summary>
        public double HeightLimit { get { return _heightLimit; } }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="analysisResult">通道分析结果</param>
        public ChannelSelectionDialog(ChannelSelectionResult analysisResult)
        {
            _analysisResult = analysisResult ?? new ChannelSelectionResult();
            _selectedChannels = new ModelItemCollection();
            _selectionMethod = ChannelSelectionMethod.Manual;
            _heightLimit = 3.0;

            InitializeComponent();
            LoadAnalysisData();
        }

        // UI控件
        private System.Windows.Forms.TabControl tabControl;
        private System.Windows.Forms.ListView channelListView;
        private System.Windows.Forms.Label statisticsLabel;
        private System.Windows.Forms.NumericUpDown heightLimitNumericUpDown;
        private System.Windows.Forms.Button previewButton;
        private System.Windows.Forms.Button clearHighlightButton;
        private System.Windows.Forms.CheckBox selectAllCheckBox;

        /// <summary>
        /// 初始化对话框组件
        /// </summary>
        private void InitializeComponent()
        {
            this.Text = "通道选择";
            this.Size = new System.Drawing.Size(700, 500);
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
            this.MaximizeBox = false;
            this.MinimizeBox = false;

            // 创建选项卡控件
            tabControl = new System.Windows.Forms.TabControl
            {
                Location = new System.Drawing.Point(10, 10),
                Size = new System.Drawing.Size(670, 350),
                Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | 
                         System.Windows.Forms.AnchorStyles.Right | System.Windows.Forms.AnchorStyles.Bottom
            };

            // 创建通道列表选项卡
            var channelListTab = new System.Windows.Forms.TabPage("通道列表");
            CreateChannelListTab(channelListTab);
            tabControl.TabPages.Add(channelListTab);

            // 创建筛选选项卡
            var filterTab = new System.Windows.Forms.TabPage("筛选选项");
            CreateFilterTab(filterTab);
            tabControl.TabPages.Add(filterTab);

            this.Controls.Add(tabControl);

            // 统计信息标签
            statisticsLabel = new System.Windows.Forms.Label
            {
                Location = new System.Drawing.Point(10, 370),
                Size = new System.Drawing.Size(400, 60),
                Text = "正在加载通道信息...",
                Font = new System.Drawing.Font("微软雅黑", 8),
                Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left
            };
            this.Controls.Add(statisticsLabel);

            // 预览按钮
            previewButton = new System.Windows.Forms.Button
            {
                Text = "预览选中",
                Size = new System.Drawing.Size(80, 25),
                Location = new System.Drawing.Point(420, 370),
                Font = new System.Drawing.Font("微软雅黑", 8),
                Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left
            };
            previewButton.Click += PreviewButton_Click;
            this.Controls.Add(previewButton);

            // 清除高亮按钮
            clearHighlightButton = new System.Windows.Forms.Button
            {
                Text = "清除高亮",
                Size = new System.Drawing.Size(80, 25),
                Location = new System.Drawing.Point(510, 370),
                Font = new System.Drawing.Font("微软雅黑", 8),
                Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left
            };
            clearHighlightButton.Click += ClearHighlightButton_Click;
            this.Controls.Add(clearHighlightButton);

            // 确定按钮
            var okButton = new System.Windows.Forms.Button
            {
                Text = "确定",
                Size = new System.Drawing.Size(75, 30),
                Location = new System.Drawing.Point(520, 440),
                Font = new System.Drawing.Font("微软雅黑", 8),
                DialogResult = System.Windows.Forms.DialogResult.OK,
                Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right
            };
            okButton.Click += OkButton_Click;
            this.Controls.Add(okButton);

            // 取消按钮
            var cancelButton = new System.Windows.Forms.Button
            {
                Text = "取消",
                Size = new System.Drawing.Size(75, 30),
                Location = new System.Drawing.Point(605, 440),
                Font = new System.Drawing.Font("微软雅黑", 8),
                DialogResult = System.Windows.Forms.DialogResult.Cancel,
                Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right
            };
            this.Controls.Add(cancelButton);
        }

        /// <summary>
        /// 创建通道列表选项卡
        /// </summary>
        private void CreateChannelListTab(System.Windows.Forms.TabPage tabPage)
        {
            // 全选复选框
            selectAllCheckBox = new System.Windows.Forms.CheckBox
            {
                Text = "全选",
                Location = new System.Drawing.Point(10, 10),
                Size = new System.Drawing.Size(60, 20),
                Font = new System.Drawing.Font("微软雅黑", 8)
            };
            selectAllCheckBox.CheckedChanged += SelectAllCheckBox_CheckedChanged;
            tabPage.Controls.Add(selectAllCheckBox);

            // 通道列表
            channelListView = new System.Windows.Forms.ListView
            {
                Location = new System.Drawing.Point(10, 35),
                Size = new System.Drawing.Size(640, 280),
                View = System.Windows.Forms.View.Details,
                FullRowSelect = true,
                GridLines = true,
                CheckBoxes = true,
                Font = new System.Drawing.Font("微软雅黑", 8),
                Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | 
                         System.Windows.Forms.AnchorStyles.Right | System.Windows.Forms.AnchorStyles.Bottom
            };

            // 添加列
            channelListView.Columns.Add("名称", 200);
            channelListView.Columns.Add("类型", 80);
            channelListView.Columns.Add("可通行", 60);
            channelListView.Columns.Add("物体尺寸", 80);
            channelListView.Columns.Add("长度(m)", 80);
            channelListView.Columns.Add("宽度(m)", 80);
            channelListView.Columns.Add("高度(m)", 80);

            channelListView.ItemChecked += ChannelListView_ItemChecked;
            tabPage.Controls.Add(channelListView);
        }

        /// <summary>
        /// 创建筛选选项卡
        /// </summary>
        private void CreateFilterTab(System.Windows.Forms.TabPage tabPage)
        {
            // 高度限制选择
            var heightLimitLabel = new System.Windows.Forms.Label
            {
                Text = "高度限制(m):",
                Location = new System.Drawing.Point(10, 20),
                Size = new System.Drawing.Size(80, 20),
                Font = new System.Drawing.Font("微软雅黑", 8)
            };
            tabPage.Controls.Add(heightLimitLabel);

            heightLimitNumericUpDown = new System.Windows.Forms.NumericUpDown
            {
                Location = new System.Drawing.Point(100, 18),
                Size = new System.Drawing.Size(120, 25),
                Font = new System.Drawing.Font("微软雅黑", 8),
                Minimum = 1.0m,
                Maximum = 20.0m,
                DecimalPlaces = 1,
                Value = 3.0m
            };
            heightLimitNumericUpDown.ValueChanged += HeightLimitNumericUpDown_ValueChanged;
            tabPage.Controls.Add(heightLimitNumericUpDown);

            // 筛选方式选择
            var filterMethodLabel = new System.Windows.Forms.Label
            {
                Text = "筛选方式:",
                Location = new System.Drawing.Point(10, 60),
                Size = new System.Drawing.Size(200, 20),
                Font = new System.Drawing.Font("微软雅黑", 8)
            };
            tabPage.Controls.Add(filterMethodLabel);

            var filterOptions = new System.Windows.Forms.RadioButton[]
            {
                new System.Windows.Forms.RadioButton { Text = "显示所有检测到的通道", Location = new System.Drawing.Point(20, 85), Size = new System.Drawing.Size(200, 20), Checked = true },
                new System.Windows.Forms.RadioButton { Text = "仅显示已标记物流属性的通道", Location = new System.Drawing.Point(20, 110), Size = new System.Drawing.Size(200, 20) },
                new System.Windows.Forms.RadioButton { Text = "仅显示可通行区域", Location = new System.Drawing.Point(20, 135), Size = new System.Drawing.Size(200, 20) },
                new System.Windows.Forms.RadioButton { Text = "自动检测通道", Location = new System.Drawing.Point(20, 160), Size = new System.Drawing.Size(200, 20) }
            };

            foreach (var option in filterOptions)
            {
                option.Font = new System.Drawing.Font("微软雅黑", 8);
                option.CheckedChanged += FilterOption_CheckedChanged;
                tabPage.Controls.Add(option);
            }

            // 应用筛选按钮
            var applyFilterButton = new System.Windows.Forms.Button
            {
                Text = "应用筛选",
                Location = new System.Drawing.Point(20, 200),
                Size = new System.Drawing.Size(100, 30),
                Font = new System.Drawing.Font("微软雅黑", 8)
            };
            applyFilterButton.Click += ApplyFilterButton_Click;
            tabPage.Controls.Add(applyFilterButton);
        }

        /// <summary>
        /// 加载分析数据
        /// </summary>
        private void LoadAnalysisData()
        {
            try
            {
                if (channelListView == null) return;

                channelListView.Items.Clear();

                // 根据分析结果填充通道列表
                var channelsToShow = _analysisResult.ChannelItems.Count > 0 
                    ? _analysisResult.ChannelItems 
                    : _analysisResult.AutoDetectedChannels;

                foreach (ModelItem channel in channelsToShow)
                {
                    var item = new System.Windows.Forms.ListViewItem(channel.DisplayName ?? "未命名通道");
                    item.Tag = channel;
                    
                    // 获取通道属性信息
                    string channelType = "通道";
                    string traversable = "是";
                    string objectSize = "标准";
                    
                    try
                    {
                        if (CategoryAttributeManager.HasLogisticsAttributes(channel))
                        {
                            // 这里可以添加更详细的属性读取逻辑
                        }
                    }
                    catch (Exception ex)
                    {
                        LogManager.Debug($"[通道列表] 获取物流属性失败: {ex.Message}");
                    }

                    // 获取尺寸信息
                    double length = 0, width = 0, height = 0;
                    try
                    {
                        var boundingBox = channel.BoundingBox();
                        if (boundingBox != null)
                        {
                            length = Math.Abs(boundingBox.Max.X - boundingBox.Min.X);
                            width = Math.Abs(boundingBox.Max.Y - boundingBox.Min.Y);
                            height = Math.Abs(boundingBox.Max.Z - boundingBox.Min.Z);
                        }
                    }
                    catch (Exception ex)
                    {
                        LogManager.Debug($"[通道列表] 获取包围盒失败: {ex.Message}");
                    }

                    // 添加子项
                    item.SubItems.Add(channelType);
                    item.SubItems.Add(traversable);
                    item.SubItems.Add(objectSize);
                    item.SubItems.Add(length.ToString("F2"));
                    item.SubItems.Add(width.ToString("F2"));
                    item.SubItems.Add(height.ToString("F2"));

                    channelListView.Items.Add(item);
                }

                // 更新统计信息
                UpdateStatistics();

                // 默认选择所有通道
                if (_analysisResult.Success && channelsToShow.Count > 0)
                {
                    _selectedChannels = new ModelItemCollection();
                    foreach (ModelItem channel in channelsToShow)
                    {
                        _selectedChannels.Add(channel);
                    }
                }
            }
            catch (Exception ex)
            {
                if (statisticsLabel != null)
                {
                    statisticsLabel.Text = $"加载通道数据失败: {ex.Message}";
                }
            }
        }

        /// <summary>
        /// 更新统计信息
        /// </summary>
        private void UpdateStatistics()
        {
            if (statisticsLabel == null) return;

            var totalChannels = channelListView.Items.Count;
            var selectedChannels = channelListView.CheckedItems.Count;
            var logisticsMarked = _analysisResult.LogisticsMarkedItems.Count;
            var autoDetected = _analysisResult.AutoDetectedChannels.Count;

            statisticsLabel.Text = $"统计信息:\n" +
                                  $"总通道数: {totalChannels}  已选择: {selectedChannels}\n" +
                                  $"已标记物流属性: {logisticsMarked}  自动检测: {autoDetected}";
        }

        #region 事件处理方法

        /// <summary>
        /// 预览按钮点击事件
        /// </summary>
        private void PreviewButton_Click(object sender, EventArgs e)
        {
            try
            {
                var selectedItems = new ModelItemCollection();
                foreach (System.Windows.Forms.ListViewItem item in channelListView.CheckedItems)
                {
                    if (item.Tag is ModelItem channel)
                    {
                        selectedItems.Add(channel);
                    }
                }

                if (selectedItems.Count > 0)
                {
                    // 高亮显示选中的通道
                    ModelHighlightHelper.HighlightItems(ChannelPreviewHighlightCategory, selectedItems);
                }
            }
            catch (Exception ex)
            {
                System.Windows.Forms.MessageBox.Show($"预览失败: {ex.Message}", "错误", 
                    System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// 清除高亮按钮点击事件
        /// </summary>
        private void ClearHighlightButton_Click(object sender, EventArgs e)
        {
            try
            {
                ModelHighlightHelper.ClearCategory(ChannelPreviewHighlightCategory);
            }
            catch (Exception ex)
            {
                System.Windows.Forms.MessageBox.Show($"清除高亮失败: {ex.Message}", "错误", 
                    System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// 确定按钮点击事件
        /// </summary>
        private void OkButton_Click(object sender, EventArgs e)
        {
            try
            {
                _selectedChannels.Clear();
                
                foreach (System.Windows.Forms.ListViewItem item in channelListView.CheckedItems)
                {
                    if (item.Tag is ModelItem channel)
                    {
                        _selectedChannels.Add(channel);
                    }
                }

                _heightLimit = (double)(heightLimitNumericUpDown?.Value ?? 3.0m);
                _selectionMethod = ChannelSelectionMethod.Manual; // 可以根据选项卡或筛选方式设置

                // 清除高亮
                try
                {
                    ModelHighlightHelper.ClearCategory(ChannelPreviewHighlightCategory);
                }
                catch (Exception ex)
                {
                    LogManager.Debug($"[通道预览] 清除高亮失败: {ex.Message}");
                }
            }
            catch (Exception ex)
            {
                System.Windows.Forms.MessageBox.Show($"确认选择失败: {ex.Message}", "错误", 
                    System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// 全选复选框状态改变事件
        /// </summary>
        private void SelectAllCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            try
            {
                bool isChecked = selectAllCheckBox.Checked;
                
                foreach (System.Windows.Forms.ListViewItem item in channelListView.Items)
                {
                    item.Checked = isChecked;
                }
            }
            catch (Exception ex)
            {
                System.Windows.Forms.MessageBox.Show($"全选操作失败: {ex.Message}", "错误", 
                    System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// 通道列表项选中状态改变事件
        /// </summary>
        private void ChannelListView_ItemChecked(object sender, System.Windows.Forms.ItemCheckedEventArgs e)
        {
            UpdateStatistics();
        }

        /// <summary>
        /// 高度限制数值改变事件
        /// </summary>
        private void HeightLimitNumericUpDown_ValueChanged(object sender, EventArgs e)
        {
            _heightLimit = (double)heightLimitNumericUpDown.Value;
        }

        /// <summary>
        /// 筛选选项改变事件
        /// </summary>
        private void FilterOption_CheckedChanged(object sender, EventArgs e)
        {
            // 可以根据需要实现筛选逻辑
        }

        /// <summary>
        /// 应用筛选按钮点击事件
        /// </summary>
        private void ApplyFilterButton_Click(object sender, EventArgs e)
        {
            try
            {
                // 重新加载数据应用筛选
                LoadAnalysisData();
            }
            catch (Exception ex)
            {
                System.Windows.Forms.MessageBox.Show($"应用筛选失败: {ex.Message}", "错误", 
                    System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
            }
        }

        #endregion
    }

    #region 路径验证与优化相关数据结构

    /// <summary>
    /// 路径验证结果
    /// </summary>
    public class PathValidationResult
    {
        /// <summary>
        /// 路径ID
        /// </summary>
        public string RouteId { get; set; } = "";

        /// <summary>
        /// 路径名称
        /// </summary>
        public string RouteName { get; set; } = "";

        /// <summary>
        /// 验证是否通过
        /// </summary>
        public bool IsValid { get; set; } = false;

        /// <summary>
        /// 验证消息
        /// </summary>
        public string Message { get; set; } = "";

        /// <summary>
        /// 错误列表
        /// </summary>
        public List<string> Errors { get; set; } = new List<string>();

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

        /// <summary>
        /// 验证时间
        /// </summary>
        public DateTime ValidationTime { get; set; } = DateTime.Now;

        /// <summary>
        /// 添加错误信息
        /// </summary>
        /// <param name="error">错误信息</param>
        public void AddError(string error)
        {
            if (!string.IsNullOrEmpty(error) && !Errors.Contains(error))
            {
                Errors.Add(error);
            }
        }

        /// <summary>
        /// 添加警告信息
        /// </summary>
        /// <param name="warning">警告信息</param>
        public void AddWarning(string warning)
        {
            if (!string.IsNullOrEmpty(warning) && !Warnings.Contains(warning))
            {
                Warnings.Add(warning);
            }
        }

        /// <summary>
        /// 获取详细验证报告
        /// </summary>
        /// <returns>验证报告文本</returns>
        public string GetDetailedReport()
        {
            var report = new StringBuilder();
            report.AppendLine($"路径验证报告 - {RouteName} ({RouteId})");
            report.AppendLine($"验证时间: {ValidationTime:yyyy-MM-dd HH:mm:ss}");
            report.AppendLine($"验证结果: {(IsValid ? "通过" : "失败")}");
            report.AppendLine($"消息: {Message}");
            
            if (Errors.Count > 0)
            {
                report.AppendLine("\n错误列表:");
                for (int i = 0; i < Errors.Count; i++)
                {
                    report.AppendLine($"  {i + 1}. {Errors[i]}");
                }
            }

            if (Warnings.Count > 0)
            {
                report.AppendLine("\n警告列表:");
                for (int i = 0; i < Warnings.Count; i++)
                {
                    report.AppendLine($"  {i + 1}. {Warnings[i]}");
                }
            }

            return report.ToString();
        }
    }

    /// <summary>
    /// 路径优化选项
    /// </summary>
    public class PathOptimizationOptions
    {
        /// <summary>
        /// 移除重复点
        /// </summary>
        public bool RemoveDuplicatePoints { get; set; } = true;

        /// <summary>
        /// 路径平滑化
        /// </summary>
        public bool SmoothPath { get; set; } = true;

        /// <summary>
        /// 优化路径角度
        /// </summary>
        public bool OptimizeAngles { get; set; } = true;

        /// <summary>
        /// 调整到通道中心
        /// </summary>
        public bool AdjustToChannels { get; set; } = false;

        /// <summary>
        /// 重复点检测阈值（米）
        /// </summary>
        public double DuplicatePointThreshold { get; set; } = 0.01;

        /// <summary>
        /// 角度优化容差（弧度）
        /// </summary>
        public double AngleOptimizationTolerance { get; set; } = 0.1;

        /// <summary>
        /// 平滑强度（0-1）
        /// </summary>
        public double SmoothingStrength { get; set; } = 0.5;

        /// <summary>
        /// 创建默认优化选项
        /// </summary>
        /// <returns>默认优化选项</returns>
        public static PathOptimizationOptions CreateDefault()
        {
            return new PathOptimizationOptions
            {
                RemoveDuplicatePoints = true,
                SmoothPath = true,
                OptimizeAngles = true,
                AdjustToChannels = false,
                DuplicatePointThreshold = 0.01,
                AngleOptimizationTolerance = 0.1,
                SmoothingStrength = 0.5
            };
        }

        /// <summary>
        /// 创建保守优化选项（仅基础优化）
        /// </summary>
        /// <returns>保守优化选项</returns>
        public static PathOptimizationOptions CreateConservative()
        {
            return new PathOptimizationOptions
            {
                RemoveDuplicatePoints = true,
                SmoothPath = false,
                OptimizeAngles = false,
                AdjustToChannels = false,
                DuplicatePointThreshold = 0.001
            };
        }

        /// <summary>
        /// 创建激进优化选项（所有优化）
        /// </summary>
        /// <returns>激进优化选项</returns>
        public static PathOptimizationOptions CreateAggressive()
        {
            return new PathOptimizationOptions
            {
                RemoveDuplicatePoints = true,
                SmoothPath = true,
                OptimizeAngles = true,
                AdjustToChannels = true,
                DuplicatePointThreshold = 0.05,
                AngleOptimizationTolerance = 0.2,
                SmoothingStrength = 0.8
            };
        }
    }

    /// <summary>
    /// 路径优化结果
    /// </summary>
    public class PathOptimizationResult
    {
        /// <summary>
        /// 优化是否成功
        /// </summary>
        public bool Success { get; set; } = false;

        /// <summary>
        /// 优化消息
        /// </summary>
        public string Message { get; set; } = "";

        /// <summary>
        /// 原始路径
        /// </summary>
        public PathRoute OriginalRoute { get; set; }

        /// <summary>
        /// 优化后的路径
        /// </summary>
        public PathRoute OptimizedRoute { get; set; }

        /// <summary>
        /// 原始路径长度
        /// </summary>
        public double OriginalLength { get; set; } = 0.0;

        /// <summary>
        /// 优化后路径长度
        /// </summary>
        public double OptimizedLength { get; set; } = 0.0;

        /// <summary>
        /// 长度减少量
        /// </summary>
        public double LengthReduction { get; set; } = 0.0;

        /// <summary>
        /// 长度减少百分比
        /// </summary>
        public double LengthReductionPercentage => OriginalLength > 0 ? (LengthReduction / OriginalLength) * 100 : 0;

        /// <summary>
        /// 原始点数
        /// </summary>
        public int OriginalPointCount { get; set; } = 0;

        /// <summary>
        /// 优化后点数
        /// </summary>
        public int OptimizedPointCount { get; set; } = 0;

        /// <summary>
        /// 点数减少量
        /// </summary>
        public int PointReduction { get; set; } = 0;

        /// <summary>
        /// 点数减少百分比
        /// </summary>
        public double PointReductionPercentage => OriginalPointCount > 0 ? ((double)PointReduction / OriginalPointCount) * 100 : 0;

        /// <summary>
        /// 优化步骤记录
        /// </summary>
        public List<string> OptimizationSteps { get; set; } = new List<string>();

        /// <summary>
        /// 优化时间
        /// </summary>
        public DateTime OptimizationTime { get; set; } = DateTime.Now;

        /// <summary>
        /// 优化耗时（毫秒）
        /// </summary>
        public long ElapsedMilliseconds { get; set; } = 0;

        /// <summary>
        /// 添加优化步骤记录
        /// </summary>
        /// <param name="step">优化步骤描述</param>
        public void AddOptimizationStep(string step)
        {
            if (!string.IsNullOrEmpty(step))
            {
                OptimizationSteps.Add($"[{DateTime.Now:HH:mm:ss}] {step}");
            }
        }

        /// <summary>
        /// 获取详细优化报告
        /// </summary>
        /// <returns>优化报告文本</returns>
        public string GetDetailedReport()
        {
            var report = new StringBuilder();
            report.AppendLine($"路径优化报告");
            report.AppendLine($"优化时间: {OptimizationTime:yyyy-MM-dd HH:mm:ss}");
            report.AppendLine($"耗时: {ElapsedMilliseconds} 毫秒");
            report.AppendLine($"优化结果: {(Success ? "成功" : "失败")}");
            report.AppendLine($"消息: {Message}");
            
            if (Success)
            {
                report.AppendLine($"\n原始路径:");
                report.AppendLine($"  长度: {OriginalLength:F3} 米");
                report.AppendLine($"  点数: {OriginalPointCount}");
                
                report.AppendLine($"\n优化后路径:");
                report.AppendLine($"  长度: {OptimizedLength:F3} 米");
                report.AppendLine($"  点数: {OptimizedPointCount}");
                
                report.AppendLine($"\n优化效果:");
                report.AppendLine($"  长度减少: {LengthReduction:F3} 米 ({LengthReductionPercentage:F1}%)");
                report.AppendLine($"  点数减少: {PointReduction} 个 ({PointReductionPercentage:F1}%)");
            }

            if (OptimizationSteps.Count > 0)
            {
                report.AppendLine("\n优化步骤:");
                for (int i = 0; i < OptimizationSteps.Count; i++)
                {
                    report.AppendLine($"  {i + 1}. {OptimizationSteps[i]}");
                }
            }

            return report.ToString();
        }

        /// <summary>
        /// 获取优化摘要
        /// </summary>
        /// <returns>优化摘要文本</returns>
        public string GetSummary()
        {
            if (!Success)
            {
                return $"优化失败: {Message}";
            }

            return $"优化成功: 长度减少 {LengthReduction:F3}m ({LengthReductionPercentage:F1}%), " +
                   $"点数减少 {PointReduction} 个 ({PointReductionPercentage:F1}%), " +
                   $"共执行 {OptimizationSteps.Count} 个优化步骤";
        }
    }

    #endregion

    /// <summary>
    /// 路径点标记类型
    /// </summary>
    public enum PathPointMarkerType
    {
        /// <summary>
        /// 文本标注
        /// </summary>
        TextLabel
    }

    /// <summary>
    /// 路径点3D标记信息
    /// </summary>
    public class PathPointMarker
    {
        /// <summary>
        /// 关联的路径点
        /// </summary>
        public PathPoint PathPoint { get; set; }
        
        /// <summary>
        /// 标记类型
        /// </summary>
        public PathPointMarkerType MarkerType { get; set; }
        
        /// <summary>
        /// 标注文本
        /// </summary>
        public string LabelText { get; set; }
        
        /// <summary>
        /// 标注位置
        /// </summary>
        public Point3D LabelPosition { get; set; }
        
        /// <summary>
        /// 创建时间
        /// </summary>
        public DateTime CreatedTime { get; set; } = DateTime.Now;
    }

    /// <summary>
    /// 路径历史记录项
    /// </summary>
    [Serializable]
    public class PathHistoryEntry
    {
        /// <summary>
        /// 历史记录唯一标识符
        /// </summary>
        public string Id { get; set; }
        
        /// <summary>
        /// 关联的路径ID
        /// </summary>
        public string RouteId { get; set; }
        
        /// <summary>
        /// 操作类型
        /// </summary>
        public PathHistoryOperationType OperationType { get; set; }
        
        /// <summary>
        /// 路径快照（操作前的状态）
        /// </summary>
        public PathRoute RouteSnapshot { get; set; }
        
        /// <summary>
        /// 操作时间
        /// </summary>
        public DateTime OperationTime { get; set; }
        
        /// <summary>
        /// 操作描述
        /// </summary>
        public string Description { get; set; }
        
        /// <summary>
        /// 版本号
        /// </summary>
        public int Version { get; set; }
        
        public PathHistoryEntry()
        {
            Id = Guid.NewGuid().ToString();
            OperationTime = DateTime.Now;
            Description = string.Empty;
            Version = 1;
        }
        
        public PathHistoryEntry(string routeId, PathHistoryOperationType operationType, PathRoute routeSnapshot, string description = "")
        {
            Id = Guid.NewGuid().ToString();
            RouteId = routeId;
            OperationType = operationType;
            RouteSnapshot = routeSnapshot?.Clone(); // 创建副本
            OperationTime = DateTime.Now;
            Description = description;
            Version = 1;
        }
    }
    
    /// <summary>
    /// 路径历史操作类型
    /// </summary>
    public enum PathHistoryOperationType
    {
        /// <summary>
        /// 创建路径
        /// </summary>
        Created,
        
        /// <summary>
        /// 编辑路径
        /// </summary>
        Edited,
        
        /// <summary>
        /// 删除路径点
        /// </summary>
        PointRemoved,
        
        /// <summary>
        /// 添加路径点
        /// </summary>
        PointAdded,
        
        /// <summary>
        /// 路径优化
        /// </summary>
        Optimized,
        
        /// <summary>
        /// 手动保存
        /// </summary>
        ManualSave
    }
    
    /// <summary>
    /// 路径历史管理器
    /// </summary>
    public class PathHistoryManager
    {
        private Dictionary<string, List<PathHistoryEntry>> _routeHistories;
        private int _maxHistoryCount;
        
        /// <summary>
        /// 历史记录变更事件
        /// </summary>
        public event EventHandler<PathHistoryEntry> HistoryEntryAdded;
        
        public PathHistoryManager(int maxHistoryCount = 50)
        {
            _routeHistories = new Dictionary<string, List<PathHistoryEntry>>();
            _maxHistoryCount = maxHistoryCount;
        }
        
        /// <summary>
        /// 保存路径到历史记录
        /// </summary>
        public void SaveToHistory(PathRoute route)
        {
            if (route != null)
            {
                var entry = new PathHistoryEntry(route.Id, PathHistoryOperationType.ManualSave, route, "手动保存");
                AddHistoryEntry(entry);
            }
        }
        
        /// <summary>
        /// 添加历史记录
        /// </summary>
        public void AddHistoryEntry(PathHistoryEntry entry)
        {
            if (string.IsNullOrEmpty(entry.RouteId)) return;
            
            if (!_routeHistories.ContainsKey(entry.RouteId))
            {
                _routeHistories[entry.RouteId] = new List<PathHistoryEntry>();
            }
            
            var histories = _routeHistories[entry.RouteId];
            
            // 设置版本号
            entry.Version = histories.Count + 1;
            
            histories.Add(entry);
            
            // 限制历史记录数量
            if (histories.Count > _maxHistoryCount)
            {
                histories.RemoveAt(0);
                
                // 重新计算版本号
                for (int i = 0; i < histories.Count; i++)
                {
                    histories[i].Version = i + 1;
                }
            }
            
            HistoryEntryAdded?.Invoke(this, entry);
        }
        
        /// <summary>
        /// 获取路径的历史记录
        /// </summary>
        public List<PathHistoryEntry> GetRouteHistory(string routeId)
        {
            return _routeHistories.ContainsKey(routeId) ? 
                new List<PathHistoryEntry>(_routeHistories[routeId]) : 
                new List<PathHistoryEntry>();
        }
        
        /// <summary>
        /// 获取最新的历史记录
        /// </summary>
        public PathHistoryEntry GetLatestHistory(string routeId)
        {
            var histories = GetRouteHistory(routeId);
            return histories.LastOrDefault();
        }
        
        /// <summary>
        /// 清理路径的历史记录
        /// </summary>
        public void ClearRouteHistory(string routeId)
        {
            if (_routeHistories.ContainsKey(routeId))
            {
                _routeHistories.Remove(routeId);
            }
        }
        
        /// <summary>
        /// 获取所有路径的历史记录统计
        /// </summary>
        public Dictionary<string, int> GetHistoryStatistics()
        {
            return _routeHistories.ToDictionary(
                kvp => kvp.Key, 
                kvp => kvp.Value.Count
            );
        }
        
        /// <summary>
        /// 获取所有历史记录
        /// </summary>
        /// <returns>所有历史记录的列表，按时间倒序排列</returns>
        public List<PathHistoryEntry> GetAllHistoryEntries()
        {
            var allEntries = new List<PathHistoryEntry>();
            foreach (var routeHistory in _routeHistories.Values)
            {
                allEntries.AddRange(routeHistory);
            }
            
            // 按操作时间倒序排列（最新的在前）
            return allEntries.OrderByDescending(entry => entry.OperationTime).ToList();
        }
    }

    /// <summary>
    /// 路径文件序列化帮助类
    /// </summary>
    public static class PathFileSerializer
    {
        /// <summary>
        /// 将路径保存为XML文件
        /// </summary>
        public static bool SaveToXml(PathRoute route, string filePath)
        {
            try
            {
                var serializer = new XmlSerializer(typeof(PathRoute));
                using (var writer = new StreamWriter(filePath, false, Encoding.UTF8))
                {
                    serializer.Serialize(writer, route);
                }
                return true;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"保存XML文件失败: {ex.Message}");
                return false;
            }
        }
        
        /// <summary>
        /// 从XML文件加载路径
        /// </summary>
        public static PathRoute LoadFromXml(string filePath)
        {
            try
            {
                var serializer = new XmlSerializer(typeof(PathRoute));
                using (var reader = new StreamReader(filePath, Encoding.UTF8))
                {
                    return (PathRoute)serializer.Deserialize(reader);
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"加载XML文件失败: {ex.Message}");
                return null;
            }
        }
        
        /// <summary>
        /// 将路径保存为JSON文件（简化版）
        /// </summary>
        public static bool SaveToJson(PathRoute route, string filePath)
        {
            try
            {
                // 使用简单的字符串格式化代替JSON序列化
                var json = new StringBuilder();
                json.AppendLine("{");
                json.AppendLine($"  \"Id\": \"{route.Id}\",");
                json.AppendLine($"  \"Name\": \"{route.Name}\",");
                json.AppendLine($"  \"Description\": \"{route.Description}\",");
                json.AppendLine($"  \"CreatedTime\": \"{route.CreatedTime:yyyy-MM-dd HH:mm:ss}\",");
                json.AppendLine($"  \"TotalLength\": {route.TotalLength},");
                json.AppendLine($"  \"EstimatedTime\": {route.EstimatedTime},");
                json.AppendLine("  \"Points\": [");
                
                for (int i = 0; i < route.Points.Count; i++)
                {
                    var point = route.Points[i];
                    json.AppendLine("    {");
                    json.AppendLine($"      \"Id\": \"{point.Id}\",");
                    json.AppendLine($"      \"Name\": \"{point.Name}\",");
                    json.AppendLine($"      \"Type\": \"{point.Type}\",");
                    json.AppendLine($"      \"Position\": {{\"X\": {point.Position.X}, \"Y\": {point.Position.Y}, \"Z\": {point.Position.Z}}},");
                    json.AppendLine($"      \"CreatedTime\": \"{point.CreatedTime:yyyy-MM-dd HH:mm:ss}\",");
                    json.AppendLine($"      \"Index\": {point.Index},");
                    json.AppendLine($"      \"Notes\": \"{point.Notes}\"");
                    json.AppendLine(i < route.Points.Count - 1 ? "    }," : "    }");
                }
                
                json.AppendLine("  ]");
                json.AppendLine("}");
                
                File.WriteAllText(filePath, json.ToString(), Encoding.UTF8);
                return true;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"保存JSON文件失败: {ex.Message}");
                return false;
            }
        }
        
        /// <summary>
        /// 从JSON文件加载路径（简化版，仅支持基本格式）
        /// </summary>
        public static PathRoute LoadFromJson(string filePath)
        {
            try
            {
                // 简化实现：仅支持基本的JSON格式
                // 由于不依赖外部JSON库，这里使用XML格式作为fallback
                System.Diagnostics.Debug.WriteLine("JSON加载功能简化，建议使用XML格式");
                return null;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"加载JSON文件失败: {ex.Message}");
                return null;
            }
        }
        
        /// <summary>
        /// 将多个路径保存为XML文件
        /// </summary>
        public static bool SaveRoutesToXml(List<PathRoute> routes, string filePath)
        {
            try
            {
                var container = new PathRouteContainer { Routes = routes };
                var serializer = new XmlSerializer(typeof(PathRouteContainer));
                using (var writer = new StreamWriter(filePath, false, Encoding.UTF8))
                {
                    serializer.Serialize(writer, container);
                }
                return true;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"保存多路径XML文件失败: {ex.Message}");
                return false;
            }
        }
        
        /// <summary>
        /// 从XML文件加载多个路径
        /// </summary>
        public static List<PathRoute> LoadRoutesFromXml(string filePath)
        {
            try
            {
                var serializer = new XmlSerializer(typeof(PathRouteContainer));
                using (var reader = new StreamReader(filePath, Encoding.UTF8))
                {
                    var container = (PathRouteContainer)serializer.Deserialize(reader);
                    return container?.Routes ?? new List<PathRoute>();
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"加载多路径XML文件失败: {ex.Message}");
                return new List<PathRoute>();
            }
        }
        
        /// <summary>
        /// 检测文件格式
        /// </summary>
        public static string DetectFileFormat(string filePath)
        {
            var extension = Path.GetExtension(filePath).ToLowerInvariant();
            switch (extension)
            {
                case ".xml":
                    return "XML";
                case ".json":
                    return "JSON";
                default:
                    // 尝试检测内容
                    try
                    {
                        var content = File.ReadAllText(filePath).Trim();
                        if (content.StartsWith("<") && content.EndsWith(">"))
                            return "XML";
                        if (content.StartsWith("{") && content.EndsWith("}"))
                            return "JSON";
                    }
                    catch (Exception ex)
                    {
                        LogManager.Debug($"[路径格式检测] 读取文件失败: {ex.Message}");
                    }
                    return "未知";
            }
        }
    }
    
    /// <summary>
    /// 路径容器（用于保存多个路径）
    /// </summary>
    [Serializable]
    public class PathRouteContainer
    {
        public List<PathRoute> Routes { get; set; } = new List<PathRoute>();
        public DateTime CreatedTime { get; set; } = DateTime.Now;
        public string Version { get; set; } = "1.0";
        public string Description { get; set; } = "";
    }

    #region 多层阶梯式吊装路径数据模型

    /// <summary>
    /// 吊装路径模式枚举
    /// </summary>
    public enum HoistingMode
    {
        /// <summary>
        /// 单层吊装（传统模式，向后兼容）
        /// </summary>
        SingleLevel,

        /// <summary>
        /// 多层阶梯式吊装
        /// </summary>
        MultiLevel
    }

    /// <summary>
    /// 吊装层级信息 - 表示多层吊装中的一个水平移动层级
    /// </summary>
    [Serializable]
    public class HoistingLevel
    {
        /// <summary>
        /// 层级序号（从0开始）
        /// </summary>
        public int Index { get; set; }

        /// <summary>
        /// 该层级的高度（相对于起吊点的垂直高度，米）
        /// </summary>
        public double HeightInMeters { get; set; }

        /// <summary>
        /// 该层级的水平移动目标点（XY位置，Z坐标会被忽略）
        /// </summary>
        public Point3D HorizontalTarget { get; set; }

        /// <summary>
        /// 运动方向：true=从上一位置上升到此高度，false=从上一位置下降到此高度
        /// </summary>
        public bool IsRise { get; set; }

        /// <summary>
        /// 层级描述（如"桁车移动层"、"避让层"等）
        /// </summary>
        public string Description { get; set; }

        /// <summary>
        /// 创建时间
        /// </summary>
        public DateTime CreatedTime { get; set; }

        /// <summary>
        /// 默认构造函数
        /// </summary>
        public HoistingLevel()
        {
            Index = 0;
            HeightInMeters = 0.0;
            HorizontalTarget = new Point3D();
            IsRise = true;
            Description = string.Empty;
            CreatedTime = DateTime.Now;
        }

        /// <summary>
        /// 带参数构造函数
        /// </summary>
        /// <param name="index">层级序号</param>
        /// <param name="heightInMeters">高度（米）</param>
        /// <param name="horizontalTarget">水平目标点</param>
        /// <param name="isRise">是否为上升</param>
        /// <param name="description">描述</param>
        public HoistingLevel(int index, double heightInMeters, Point3D horizontalTarget, bool isRise = true, string description = "")
        {
            Index = index;
            HeightInMeters = heightInMeters;
            HorizontalTarget = horizontalTarget ?? new Point3D();
            IsRise = isRise;
            Description = description ?? string.Empty;
            CreatedTime = DateTime.Now;
        }

        /// <summary>
        /// 返回层级描述字符串
        /// </summary>
        public override string ToString()
        {
            string direction = IsRise ? "上升" : "下降";
            return $"层级{Index + 1}: {direction}到{HeightInMeters:F2}米，目标({HorizontalTarget.X:F2}, {HorizontalTarget.Y:F2}) {(string.IsNullOrEmpty(Description) ? "" : $"- {Description}")}";
        }
    }

    #endregion
} 
