using Thousandto.Core.Base;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using System.Text;
using PathUtils = UnityEngine.Gonbest.MagicCube.PathUtils;
using UnityEngine.Gonbest.MagicCube;

namespace Thousandto.Code.Logic
{
    public class BetterLua
    {
        //key秘钥
        private static string key = "BgIAAACkAABSU0ExAAQAAAEAAQBtKN";
        //所有lua脚本
        private static Dictionary<string, byte[]> allLuaFile = new Dictionary<string, byte[]>();
        //bytes整体偏移
        private static int offset = 1;
        private static int _loadCnt = 0;

        public static bool IsLoaded()
        {
            return _loadCnt >= 2;
        }
        //初始化
        public static void Init(string lan = null)
        {
            Debug.LogError("开始初始化Lua代码....");
            _loadCnt = 0;
            var BetterLuaPath = PathUtils.GetConfigFilePath("Lua.bytes");
            var StringDefinesPath = PathUtils.GetConfigFilePath(string.Format("LuaData_{0}.bytes", (lan == null ? LanguageSystem.Lang : lan)));
#if UNITY_WEBGL
            //if (Application.platform == RuntimePlatform.WebGLPlayer)
            {
                //WebUtils.ReadBytes(BetterLuaPath, x =>
                FFileReader.ReadBytesAsync(BetterLuaPath, x =>
                {
                    if (x != null)
                    {
                        using (MemoryStream stream = new MemoryStream(x))
                        {
                            ReadFile(stream);
                            stream.Close();
                        }
                        _loadCnt++;
                    }
                    else
                    {
                        Debug.LogError("Lua1文件加载失败!:"+ BetterLuaPath);
                    }
                });

                //WebUtils.ReadBytes(StringDefinesPath, x =>
               FFileReader.ReadBytesAsync(StringDefinesPath, x =>
                {
                    if (x != null)
                    {
                        using (MemoryStream stream = new MemoryStream(x))
                        {
                            ReadFile(stream);
                            stream.Close();
                        }
                        _loadCnt++;
                    }
                    else
                    {
                        Debug.LogError("Lua2文件加载失败!:" + StringDefinesPath);
                    }
                });
            }
            //else
#else
            {
                if (File.Exists(BetterLuaPath))
                {
                    using (FileStream stream = new FileStream(BetterLuaPath, FileMode.Open, FileAccess.Read))
                    {
                        ReadFile(stream);
                        stream.Close();
                    }
                   _loadCnt++;
                }

                if (File.Exists(StringDefinesPath))
                {
                    using (FileStream stream = new FileStream(StringDefinesPath, FileMode.Open, FileAccess.Read))
                    {
                        ReadFile(stream);
                        stream.Close();
                    }
                   _loadCnt++;
                }
            }
#endif
        }

        //1.内容长度:4个字节    2.key长度:4个字节   3.key:3+keyLength   4.lua内容
        //lua内容: 1>title总长度:8个字节    2>所有lua文件总览,用分隔符分开,每3个一组【文件路径;文件开始位置;文件长度;】  3>所有lua文件内容
        private static void ReadFile(Stream stream)
        {
            using (BinaryReader reader = new BinaryReader(stream))
            {
                int contentLength = reader.ReadInt32();
                int keyLength = reader.ReadInt32();
                //key
                stream.Seek(11, SeekOrigin.Begin);
                var keyBytes = new byte[keyLength - 3];
                stream.Read(keyBytes, 0, keyLength - 3);
                DecryptKey(ref keyBytes);
                //秘钥是否正确
                if (Encoding.UTF8.GetString(keyBytes) == key)
                {
                    offset = 8 + keyLength;
                    var titleCountBytes = new byte[8];
                    stream.Seek(offset, SeekOrigin.Begin);
                    stream.Read(titleCountBytes, 0, 8);
                    DecryptContent(ref titleCountBytes);
                    int titleCount = int.Parse(Encoding.UTF8.GetString(titleCountBytes));

                    var titleBytes = new byte[titleCount];
                    stream.Seek(offset + 8, SeekOrigin.Begin);
                    stream.Read(titleBytes, 0, titleCount);

                    var titleStrArr = Encoding.UTF8.GetString(titleBytes).Split(';');
                    var titleStrArrLength = titleStrArr.Length;
                    for (int i = 0; i < titleStrArrLength - 1; i += 3)
                    {
                        var startIndex = int.Parse(titleStrArr[i + 1]) + offset;
                        var length = int.Parse(titleStrArr[i + 2]);
                        var bytes = new byte[length];
                        stream.Seek(startIndex, SeekOrigin.Begin);
                        stream.Read(bytes, 0, length);
                        DecryptContent(ref bytes);
                        allLuaFile.Add(titleStrArr[i], bytes);
                    }
                }
                reader.Close();
            }
        }

        //解密key
        public static void DecryptKey(ref byte[] bytes)
        {
            for (int i = 0; i < bytes.Length; i++)
            {
                bytes[i] = (byte)(bytes[i] ^ -82);
                bytes[i] += 106;
            }
        }

        //解密文本
        public static void DecryptContent(ref byte[] bytes)
        {
            var bytesLength = bytes.Length;
            for (int i = 0; i < bytesLength; i++)
            {
                bytes[i] = (byte)(bytes[i] ^ -74);
                //bytes[i] += 95;
            }
        }

        //加载lua文件
        public static byte[] BetterLuaLoader(ref string fileName)
        {
            if (allLuaFile.ContainsKey(fileName))
            {
                var bytes = allLuaFile[fileName];
                //配置表lua加载以后,这里可以把内存腾出来
                if (fileName.StartsWith("config/data/"))
                {
                    allLuaFile.Remove(fileName);
                }
                return bytes;
            }
            else
            {
                Debug.LogError("no file :" + fileName);
                return null;
            }
        }
    }
}