using BepuUtilities;
using Plugins.JNGame.Sync.Frame.AStar;
using Plugins.JNGame.Sync.Frame.AStar.Entity;
using Plugins.JNGame.Sync.Frame.AStar.Entity.Tile;
using UnityEngine;

namespace Game.Plugins.JNGame.Sync.Frame.AStar.Navmesh
{
    /// <summary>由三角形表示的节点</summary>  
    public class TriangleMeshNode : GraphNode   
    {  
        // /// <summary>使用AstarPath对象初始化TriangleMeshNode实例</summary>  
        // /// <param name="astar">AstarPath对象</param>  
        // public TriangleMeshNode(AstarPath astar) : base(astar) { }  
      
        /// <summary>第一个顶点的内部顶点索引</summary>  
        public int v0;  
      
        /// <summary>第二个顶点的内部顶点索引</summary>  
        public int v1;  
      
        /// <summary>第三个顶点的内部顶点索引</summary>  
        public int v2;  
        
        // /// <summary>  
        // /// 保存所有图索引的INavmeshHolder引用，以便以高性能的方式访问它们  
        // /// </summary>  
        // protected static INavmeshHolder[] _navmeshHolders = new INavmeshHolder[0];

        /// <summary>存储所有图形索引的INavmeshHolder引用，以便以高性能的方式访问它们</summary>  
        /// <remarks>  
        /// 这个静态数组用于存储INavmeshHolder的引用，其中每个索引对应一个图形。  
        /// 数组的大小可以动态调整以适应更多的图形索引。  
        /// </remarks>  
        protected static INavmeshHolder[] _navmeshHolders = new INavmeshHolder[0];  
        //
        // /// <summary>用于同步访问<see cref="_navmeshHolders"/>数组的锁对象</summary>  
        // /// <remarks>  
        // /// 当多个线程尝试访问或修改_navmeshHolders数组时，lockObject确保这些操作是线程安全的。  
        // /// </remarks>  
        // protected static readonly System.Object lockObject = new System.Object();  
        //
        // /// <summary>  
        // /// 根据给定的图形索引获取内部的INavmeshHolder。  
        // /// </summary>  
        // /// <param name="graphIndex">图形索引</param>  
        // /// <returns>对应索引的INavmeshHolder对象</returns>  
        // public static INavmeshHolder GetNavmeshHolder(uint graphIndex)  
        // {  
        //     return _navmeshHolders[(int)graphIndex];  
        // }  
      
        /// <summary>  
        /// 为给定的图形索引设置内部的INavmeshHolder。  
        /// 警告：这是一个内部方法。  
        /// </summary>  
        /// <param name="graphIndex">图形索引</param>  
        /// <param name="graph">INavmeshHolder对象</param>  
        /// <remarks>  
        /// 这个方法用于设置特定图形索引的INavmeshHolder。  
        /// 由于可能涉及数组大小的调整，因此需要使用lockObject确保线程安全。  
        /// </remarks>  
        public static void SetNavmeshHolder(int graphIndex, INavmeshHolder graph)  
        {  
            if (graphIndex >= _navmeshHolders.Length)  
            {  
                // 如果graphIndex超出了当前数组的长度，则扩展数组  
                var gg = new INavmeshHolder[graphIndex + 1];  
                _navmeshHolders.CopyTo(gg, 0);  
                _navmeshHolders = gg;  
            }  
            // 设置指定索引位置的INavmeshHolder  
            _navmeshHolders[graphIndex] = graph;  
        }
        
        public static INavmeshHolder GetNavmeshHolder (uint graphIndex) {
            return _navmeshHolders[(int)graphIndex];
        }
        
        // /// <summary>  
        // /// 返回此节点在世界空间中的所有3个顶点  
        // /// </summary>  
        // public void GetVertices (out Int3 v0, out Int3 v1, out Int3 v2) {  
        //     // 获取保存此节点顶点数据的对象  
        //     // 这通常是一个图或一个重新生成的图块  
        //     var holder = GetNavmeshHolder(GraphIndex);  
        //
        //     v0 = holder.GetVertex(this.v0);  
        //     v1 = holder.GetVertex(this.v1);  
        //     v2 = holder.GetVertex(this.v2);  
        // }
        
        // public override Vector3 ClosestPointOnNode(Vector3 p)
        // {
        //     Int3 a, b, c;
        //
        //     GetVertices(out a, out b, out c);
        //     return Pathfinding.Polygon.ClosestPointOnTriangle((Vector3)a, (Vector3)b, (Vector3)c, p);
        // }

        // /// <summary>  
        // /// 在图空间中，找到给定点在节点三角形上的最近点。  
        // /// </summary>  
        // /// <param name="p">给定的点。</param>  
        // /// <returns>在节点三角形上的最近点。</returns>  
        // internal Int3 ClosestPointOnNodeXZInGraphSpace(Vector3 p) {  
        //     // 获取构成三角形的顶点  
        //     Int3 a, b, c;  
        //     GetVerticesInGraphSpace(out a, out b, out c);  
        //
        //     // 将点p转换为图空间  
        //     p = GetNavmeshHolder(GraphIndex).transform.InverseTransform(p);  
        //
        //     // 从上方查看三角形时，找到三角形上离点p最近的点  
        //     var closest = Pathfinding.Polygon.ClosestPointOnTriangleXZ((Vector3)a, (Vector3)b, (Vector3)c, p);  
        //
        //     // 确保点实际上在节点内部  
        //     var i3closest = (Int3)closest;  
        //     if (ContainsPointInGraphSpace(i3closest)) {  
        //         // 常规情况，最近点已经在节点内部  
        //         return i3closest;  
        //     } else {  
        //         // 讨厌的情况...  
        //         // 当从浮点坐标转换为整数坐标时，最近的点实际上不在节点内部。  
        //         // 对于某些方法（例如Linecast）来说，这个点需要在节点内部才能正常工作。  
        //
        //         // 尝试最近点周围的8个整数坐标  
        //         // 并检查它们中的任何一个是否完全在节点内部。  
        //         // 由于它应该非常接近，因此这很可能成功。  
        //         for (int dx = -1; dx <= 1; dx++) {  
        //             for (int dz = -1; dz <= 1; dz++) {  
        //                 if ((dx != 0 || dz != 0)) {  
        //                     var candidate = new Int3(i3closest.x + dx, i3closest.y, i3closest.z + dz);  
        //                     if (ContainsPointInGraphSpace(candidate)) return candidate;  
        //                 }  
        //             }  
        //         }  
        //
        //         // 很少发生的情况。  
        //         // 选择三角形的最近顶点。  
        //         // 顶点保证在三角形内部。  
        //         var da = (a - i3closest).sqrMagnitudeLong;  
        //         var db = (b - i3closest).sqrMagnitudeLong;  
        //         var dc = (c - i3closest).sqrMagnitudeLong;  
        //         return da < db ? (da < dc ? a : c) : (db < dc ? b : c);  
        //     }  
        // }
        public TriangleMeshNode(JNAStarPath astar) : base(astar)
        {
        }

        public override Vector3 ClosestPointOnNode(Vector3 p)
        {
            throw new System.NotImplementedException();
        }

        public override void ClearConnections(bool alsoReverse)
        {
            throw new System.NotImplementedException();
        }
    }
}