using Thousandto.Core.Base;
using Thousandto.Plugins.Common;
using System;
using System.Collections.Generic;
using UnityEngine;
using XLua;
using System.Collections;
using PathUtils = UnityEngine.Gonbest.MagicCube.PathUtils;
using CoroutinePool = UnityEngine.Gonbest.MagicCube.CoroutinePool;
using StringUtils = UnityEngine.Gonbest.MagicCube.StringUtils;
using Thousandto.Core.Asset;

namespace Thousandto.Code.Logic
{
    public delegate void LuaUpdateDelegate(float deltaTime);
    public delegate void LuaUpdatePlussDelegate(float deltaTime, float realtimeSinceStartup, float frameCount);
    //Lua系统
    public class LuaSystem
    {
        #region //私有变量
        private LuaEnv _luaEnv;
        private LuaTable _luaGlobal;
        private bool _isLogicInit = false;
        private LuaUpdatePlussDelegate updateEvent;


        //public List<Action> EvtLuaSystemInitList = new List<Action>();
        //public List<Action> EvtLuaSystemDisposeList = new List<Action>();
        public LuaEnv LuaEnv { get { return _luaEnv; } }

        private LuaAdaptor _adaptor;
        public LuaAdaptor Adaptor
        {
            get
            {
                if(_adaptor == null)
                {
                    _adaptor = new LuaAdaptor();
                }
                return _adaptor;
            }
        }
        private LuaSetting _setting;
        public LuaSetting Setting
        {
            get
            {
                if (_setting == null)
                {
                    _setting = new LuaSetting();
                }
                return _setting;
            }
        }

        public bool IsInit
        {
            get { return _isLogicInit; }
        }

       

#if UNITY_EDITOR && !FUNCELL_LAUNCHER
        //是否使用Bytes来读取lua
        private bool _isUseBytes = false;
#endif
        #endregion

        #region //函数
        public LuaSystem()
        {
            //PC耗时281ms
            _luaEnv = new LuaEnv();
            _luaGlobal = _luaEnv.Global;
        }

        //初始化
        public IEnumerator CoreInitialize()
        {
            Debug.Log("=======【LuaSystem】 CoreInitialize Start========");
            //清除读表缓存
            CfgBinaryData.RemoveAll();
            Debug.LogError("开始初始化PB....");
            //ProtoBuffer的加载
            LuaProtoBuff.Init();
            yield return new WaitUntil(LuaProtoBuff.IsLoaded);
            Debug.LogError("初始化PB完毕!!!");

#if !UNITY_EDITOR || FUNCELL_LAUNCHER
            //PC耗时38ms
            BetterLua.Init();
            yield return new WaitUntil(BetterLua.IsLoaded);
#endif

            //Thousandto.Code.Logic.RunTimeProfiler2.instance.isRunProfiler = true;
            //增加自定义Loader
            _luaEnv.AddLoader(LuaLoader);
            Setting.Initialize(_luaEnv);
#if UNITY_EDITOR && !FUNCELL_LAUNCHER
            _isUseBytes = Setting.Get("UseLuaBytes") > 0;
            if (_isUseBytes)
            {
                //这里可以填写语言,比如:TH,那么他就会读取Config目录下的LuaData_TH.bytes文件.
                BetterLua.Init();
                yield return new WaitUntil(BetterLua.IsLoaded);
            }
#endif

            

            //加载Lua端Main.lua
            _luaEnv.DoString("Main = require 'Main'");
            _luaEnv.Global.GetInPath<Action<float>>("Main.Start")(Time.realtimeSinceStartup);

            //_luaEnv.Global.GetInPath<Action>("Main.Start")();
            Adaptor.RequireGlobalCS();
            yield return null;
            //PC耗时81ms
            Adaptor.RequireGlobalLua();
            yield return null;
            Adaptor.RequireStringDefines();
            yield return null;
            Adaptor.CoreInitialize();
            yield return null;
            //LogicInitialize();
            //yield return null;
            //if (EvtLuaSystemInitList.Count > 0)
            //{
            //    for (int i = 0; i < EvtLuaSystemInitList.Count; i++)
            //    {
            //        EvtLuaSystemInitList[i]();
            //    }
            //}

            Networker.Instance.ResLuaMessageEvent = Adaptor.GetDoResMessage();
            MsgExtend.SharedInstance.ResLuaMsgIDMap = Adaptor.GetResLuaMsgMap();
            MsgExtend.SharedInstance.ResLuaExtendMsgIDMap = Adaptor.GetResLuaExtendMsgMap();
            FGameObjectAnim.TranslateAnimNameHandle = Adaptor.GetTranslateAnimName();
            if (Setting.Get("UseLuaShaderSwitch") > 0)
            {
                FGameObjectModel.OnShaderSWitchHandler = Adaptor.OnFGameObjectShaderSwitch;
            }
            else
            {
                FGameObjectModel.OnShaderSWitchHandler = FGOShaderSwitcher.Process;
            }

            Debug.Log("=======【LuaSystem】 CoreInitialize End========");
        }

        public void CoreUnInitialize()
        {
            Adaptor.CoreUninitialize();
        }

        public void LogicInitialize(bool clearLoginData)
        {
            if (!_isLogicInit)
            {
                Adaptor.LogicInitialize(clearLoginData);
                updateEvent = _luaGlobal.GetInPath<LuaUpdatePlussDelegate>("Main.Update");
                _isLogicInit = true;
            }
        }

        public void LogicUnInitialize(bool clearLoginData)
        { 
            if (_isLogicInit)
            {
                updateEvent = null;
                Adaptor.LogicUninitialize(clearLoginData);
                _isLogicInit = false;
            }
        }

        //Lua文件的加载器
        public byte[] LuaLoader(ref string fileName)
        {
            fileName = fileName.Replace(".", "/");
            //删除配置中的缓存数据
            if (fileName.StartsWith("Config/Data/Data"))
            {
                var cfgName = fileName.Replace("Config/Data/Data", "");
                CfgBinaryData.Remove(cfgName);
            }
            fileName = fileName.ToLower();
#if UNITY_EDITOR && !FUNCELL_LAUNCHER
            var filepath = PathUtils.GetResourcePath("Lua/" + fileName + ".lua");
            //Debug.LogError("LuaSystem:"+ filepath+":::"+_isUseBytes);
            //editor目录下的文件,不会去读取bytes中的文件.
            if (System.IO.File.Exists(filepath) && (!_isUseBytes || fileName.StartsWith("editor/")))
            {
                //Debug.Log("LuaCustomLoader:" + filepath);
                //适配在Unity上面读取多语言的翻译文件,方便调试 丁华强 2020/12/24
                string lan = UnityEngine.Gonbest.MagicCube.FLanguage.Default;
                if (!string.IsNullOrEmpty(lan) && filepath.IndexOf("stringdefines") > 0)
                {
                    string _lanStringDefinesPath = string.Format("{0}.{1}", filepath, lan);
                    if (System.IO.File.Exists(_lanStringDefinesPath))
                    {
                        return System.IO.File.ReadAllBytes(_lanStringDefinesPath);
                    }
                }
                return System.IO.File.ReadAllBytes(filepath);
            }
            else
            {
                return BetterLua.BetterLuaLoader(ref fileName);
            }
#else
            return BetterLua.BetterLuaLoader(ref fileName);
#endif
        }

        //获取lua全局变量
        public T GetGlobal<T>(string str)
        {
            return _luaGlobal.Get<T>(str);
        }

        //根据路径获取lua全局变量
        public T GetGlobalInPath<T>(string str)
        {
            return _luaGlobal.GetInPath<T>(str);
        }

        //执行lua代码
        public object[] DoString(string str)
        {
            return _luaEnv.DoString(str);
        }

        public void Tick()
        {
            _luaEnv.Tick();
        }

        public void Update(float deltaTime)
        {
            if(null != updateEvent)
            {
                updateEvent(deltaTime,Time.realtimeSinceStartup,Time.frameCount);
            }
        }

        //public void AddInitListener(Action act)
        //{
        //    EvtLuaSystemInitList.Add(act);
        //}
        //public void AddDisposetListener(Action act)
        //{
        //    EvtLuaSystemDisposeList.Add(act);
        //}
        //public void RemoveInitListener(Action act)
        //{
        //    EvtLuaSystemInitList.Remove(act);
        //}
        //public void RemoveDisposetListener(Action act)
        //{
        //    EvtLuaSystemDisposeList.Remove(act);
        //}
        public void Dispose()
        {
            updateEvent = null;

            //if (EvtLuaSystemDisposeList.Count > 0)
            //{
            //    for (int i = 0; i < EvtLuaSystemDisposeList.Count; i++)
            //    {
            //        EvtLuaSystemDisposeList[i]();
            //    }
            //}
            _luaEnv.Dispose();
            _luaEnv = null;
            Debug.Log("=============================[XLua 已卸载]==============================");
        }

        //垃圾回收
        public void Sweep()
        {
            _luaEnv.FullGc();
        }
#endregion
    }
}