using System;
using System.Collections.Generic;
using Game.Plugins.JNGame.Sync.Frame.AStar.Entity.Graph;
using UnityEngine;

namespace Plugins.JNGame.Sync.Frame.AStar.Entity
{
    
    public class AStarData : MonoBehaviour
    {
        
        /// <summary>  
        /// 所有Graph。  
        /// 该数组仅在反序列化完成后填充。  
        /// 如果图形已被移除，则可能包含空条目。  
        /// </summary>  
        // 这通常用于防止某些字段被序列化，因为它们可能包含不需要或不能序列化的数据。  
        public List<NavGraph> graphs = new(); // 声明一个 NavGraph 类型的数组，初始化为长度为 0 的数组。
        
        /// <summary>  
        /// 所有图表和设置的序列化数据。  
        /// 以Base64编码的字符串形式存储，因为否则Unity的Undo系统有时会损坏字节数据（因为它只存储增量）。  
        ///  
        /// 可以通过<see cref="data"/>属性以字节数组的形式访问此数据。  
        /// </summary>  
        [SerializeField]  
        [HideInInspector]
        string dataString;
        
        /// <summary>  
        /// 所有图表和设置的序列化数据  
        /// </summary>  
        private byte[] data {  
            // 获取data的值  
            get {  
                // 如果dataString不为null，则将dataString从Base64字符串转换为字节数组并返回  
                return dataString != null ? Convert.FromBase64String(dataString) : null;  
            }  
            // 设置data的值  
            set {  
                // 如果value不为null，则将value从字节数组转换为Base64字符串并赋值给dataString  
                dataString = value != null ? Convert.ToBase64String(value) : null;  
            }  
        }
        
        /// <summary>  
        /// 所有支持的图形类型。  
        /// 通过反射搜索填充  
        /// </summary>  
        public Type[] graphTypes { get; private set; }
        
        //数据初始化
        public void Init()
        {
            graphs = new();
            AddGraph(new RecastGraph(this));
            DeserializeGraphs();
        }
        
        /// <summary>从<see cref="data"/>反序列化图形</summary>  
        /// <remarks>  
        /// 此方法从给定的数据源（可能是文件或内存中的对象）反序列化图形数据。  
        /// 如果<see cref="data"/>不为null，它将调用另一个重载的DeserializeGraphs方法，  
        /// 该方法可能包含具体的反序列化逻辑。  
        /// </remarks>  
        public void DeserializeGraphs () {  
            if (data != null) {  
                // DeserializeGraphs(data);  
            }  
        }  
  
        /// <summary>销毁所有图形并将图形设置为null</summary>  
        /// <remarks>  
        /// 此方法负责销毁当前所有的图形对象，并将图形数组重置为null。  
        /// 在销毁每个图形之前，它会调用图形的<see cref="IGraphInternals.OnDestroy"/>方法，  
        /// 该方法可能包含图形销毁前的清理逻辑。  
        /// 一旦所有图形都被销毁，它将重置<see cref="graphs"/>数组为一个新的空数组，  
        /// 并调用<see cref="UpdateShortcuts"/>方法来更新任何相关的快捷方式或缓存。  
        /// </remarks>  
        void ClearGraphs () {  
            // if (graphs == null) return;  
            // for (int i = 0; i < graphs.Length; i++) {  
            //     if (graphs[i] != null) {  
            //         ((IGraphInternals)graphs[i]).OnDestroy();  
            //         graphs[i].active = null;  
            //     }  
            // }  
            // graphs = new NavGraph[0];  
            // UpdateShortcuts();  
        }
        
        
        // /// <summary>  
        // /// 从内存中加载图表，如果存在缓存的图表，则加载缓存的图表  
        // /// </summary>  
        // public void Awake() {  
        //     
        //     // 初始化一个空的NavGraph数组，用于存储图表  
        //     graphs = new NavGraph[0];  
        //
        //     // // 检查是否设置了在启动时加载缓存，并且存在缓存的启动文件  
        //     // if (cacheStartup && file_cachedStartup != null) {  
        //     //     // 如果满足条件，则从缓存中加载图表  
        //     //     LoadFromCache();  
        //     // } else {  
        //     //     // 如果不满足条件，则反序列化图表（可能是从文件或其他数据源加载）  
        //     //     DeserializeGraphs();  
        //     // } 
        //     
        // }
          
        /// 将指定的图形添加到 <see cref="graphs"/> 数组中
        public void AddGraph (NavGraph graph) {
            //
            // // Make sure to not interfere with pathfinding
            // var graphLock = AssertSafe(true);

            // // Try to fill in an empty position
            // bool foundEmpty = false;

            graphs.Add(graph);
            for (int i = 0; i < graphs.Count; i++) {
                if (graphs[i] == null) {
                    graphs[i] = graph;
                    graph.graphIndex = (uint)i;
                    // foundEmpty = true;
                    break;
                }
            }

            // if (!foundEmpty) {
            //     if (graphs != null && graphs.Length >= GraphNode.MaxGraphIndex) {
            //         throw new Exception("Graph Count Limit Reached. You cannot have more than " + GraphNode.MaxGraphIndex + " graphs.");
            //     }
            //
            //     // Add a new entry to the list
            //     var graphList = new List<NavGraph>(graphs ?? new NavGraph[0]);
            //     graphList.Add(graph);
            //     graphs = graphList.ToArray();
            //     graph.graphIndex = (uint)(graphs.Length-1);
            //     
            // }
            
            //
            // UpdateShortcuts();
            // // graph.active = active;
            // graphLock.Release();
            
        }
        
        /// <summary>  
        /// 创建一个新的类型为type的图形实例  
        /// 参见：<see cref="CreateGraph(string)"/>  
        /// </summary>  
        internal NavGraph CreateGraph (Type type) {  
            // 使用type类型的构造函数创建一个新的实例，并将其转型为NavGraph类型  
            var graph = Activator.CreateInstance(type) as NavGraph;  
            // // 将新创建的图形的active属性设置为当前对象的active属性的值  
            // graph.active = active;  
            // 返回新创建的图形实例  
            return graph;  
        }
        
        /// <summary>  
        /// 获取 NavGraph 在 <see cref="graphs"/> 数组中的索引  
        /// </summary>  
        /// <param name="graph">要查找索引的 NavGraph 对象</param>  
        /// <returns>NavGraph 在数组中的索引，如果未找到则返回 -1</returns>  
        public int GetGraphIndex(NavGraph graph) {  
            // 如果传入的 graph 参数为空，则抛出空引用异常  
            if (graph == null) throw new ArgumentNullException("graph");  
  
            // 初始化索引值为 -1，表示默认情况下未找到 NavGraph  
            var index = -1;  
  
            // 如果 graphs 数组不为空  
            if (graphs != null) {  
                // 使用 Array.IndexOf 方法查找 graph 在 graphs 数组中的索引  
                index = Array.IndexOf(graphs.ToArray(), graph);  
  
                // 如果索引值为 -1，则表示 graphs 数组中不存在该 graph，打印错误日志  
                if (index == -1) Debug.LogError("Graph doesn't exist");  
            }  
  
            // 返回找到的索引值，或者返回 -1（表示未找到）  
            return index;  
        }
        
    }
}