using Autodesk.Navisworks.Api;
using static NavisworksTransport.CategoryAttributeManager;

namespace NavisworksTransport.PathPlanning
{
    /// <summary>
    /// 体素单元类 - 表示3D网格中的单个体素
    /// 用于体素网格路径规划，存储体素的属性和状态信息
    /// </summary>
    public class VoxelCell
    {
        /// <summary>
        /// 体素类型（对应物流元素分类）
        /// </summary>
        public LogisticsElementType Type { get; set; }

        /// <summary>
        /// 是否可通行
        /// true: 该体素为自由空间，可以通行
        /// false: 该体素为障碍物或不可通行区域
        /// </summary>
        public bool IsPassable { get; set; }

        /// <summary>
        /// 到最近障碍物的距离（模型单位）
        /// 使用Signed Distance Field (SDF)计算
        /// 正值：自由空间，数值表示到最近障碍物的距离
        /// 负值：障碍物内部，数值表示到障碍物表面的距离
        /// 零值：障碍物表面
        /// </summary>
        public double Distance { get; set; }

        /// <summary>
        /// 速度限制（米/秒）
        /// 根据体素所在区域的特性设置（如通道、电梯等）
        /// 0.0 表示无速度限制（使用默认速度）
        /// </summary>
        public double SpeedLimit { get; set; }

        /// <summary>
        /// 源模型元素
        /// 如果该体素对应某个BIM模型元素，存储其引用
        /// 用于追溯体素属性的来源
        /// </summary>
        public ModelItem SourceItem { get; set; }

        /// <summary>
        /// 通行成本
        /// 用于A*路径规划算法
        /// 考虑因素：距离、速度限制、碰撞风险等
        /// 值越大表示通行代价越高
        /// </summary>
        public double Cost { get; set; }

        /// <summary>
        /// 构造函数 - 创建默认的可通行体素
        /// </summary>
        public VoxelCell()
        {
            Type = LogisticsElementType.通道;
            IsPassable = true;
            Distance = double.MaxValue; // 初始化为无限远（远离障碍物）
            SpeedLimit = 0.0; // 无速度限制
            SourceItem = null;
            Cost = 1.0; // 默认通行成本
        }

        /// <summary>
        /// 构造函数 - 创建指定属性的体素
        /// </summary>
        /// <param name="isPassable">是否可通行</param>
        /// <param name="type">体素类型</param>
        /// <param name="distance">到最近障碍物的距离</param>
        public VoxelCell(bool isPassable, LogisticsElementType type = LogisticsElementType.通道, double distance = double.MaxValue)
        {
            Type = type;
            IsPassable = isPassable;
            Distance = distance;
            SpeedLimit = 0.0;
            SourceItem = null;
            Cost = isPassable ? 1.0 : double.MaxValue; // 不可通行区域成本为无穷大
        }

        /// <summary>
        /// 克隆体素单元
        /// </summary>
        /// <returns>体素单元的深拷贝</returns>
        public VoxelCell Clone()
        {
            return new VoxelCell
            {
                Type = this.Type,
                IsPassable = this.IsPassable,
                Distance = this.Distance,
                SpeedLimit = this.SpeedLimit,
                SourceItem = this.SourceItem,
                Cost = this.Cost
            };
        }

        /// <summary>
        /// 设置为障碍物体素
        /// </summary>
        /// <param name="sourceItem">源模型元素</param>
        public void SetAsObstacle(ModelItem sourceItem = null)
        {
            IsPassable = false;
            Type = LogisticsElementType.障碍物;
            Distance = 0.0; // 障碍物表面距离为0
            Cost = double.MaxValue;
            SourceItem = sourceItem;
        }

        /// <summary>
        /// 设置为自由空间体素
        /// </summary>
        /// <param name="distance">到最近障碍物的距离</param>
        public void SetAsFreeSpace(double distance = double.MaxValue)
        {
            IsPassable = true;
            Type = LogisticsElementType.通道;
            Distance = distance;
            Cost = 1.0;
        }

        /// <summary>
        /// 根据距离更新通行成本
        /// 距离障碍物越近，成本越高（避免贴边行走）
        /// </summary>
        /// <param name="safetyMargin">安全边距（模型单位）</param>
        public void UpdateCostFromDistance(double safetyMargin)
        {
            if (!IsPassable)
            {
                Cost = double.MaxValue;
                return;
            }

            if (Distance < safetyMargin)
            {
                // 在安全边距内，成本线性增加
                double ratio = Distance / safetyMargin;
                Cost = 1.0 + (1.0 - ratio) * 10.0; // 成本范围：1.0 ~ 11.0
            }
            else
            {
                Cost = 1.0; // 安全距离外，标准成本
            }
        }

        /// <summary>
        /// 返回体素单元的字符串表示
        /// </summary>
        public override string ToString()
        {
            string passableStr = IsPassable ? "可通行" : "障碍";
            return $"VoxelCell[{passableStr}, Type={Type}, Dist={Distance:F2}, Cost={Cost:F2}]";
        }
    }
}
