using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using LitJson;

#if UNITY_EDITOR
using UnityEditor;
#endif

using UnityEngine;

namespace MPStudio
{
    [System.Serializable]
    public class TestData
    {
        public int 年龄 = 0;

        public long money = 0;
        public float rankBig = 0;
        public float rankSmall = 0;
        //-1表示自动加载
        public int languageID = -1;
        public int diamond = 0;
        //体力
        public int stamina = 0;
        public bool isShake = true;
        public long timeStamp = 0;
        public int pageID = 1;
        //关卡id
        public int lvID = 1;
        //新手引导id
        public int guideID = 1;
        //登陆天
        public int loginDay = 1;
        public string userName = "";
        
        //備用key
        public string key1;
        public string key2;
        public string key3;
        public string key4;
        public string key5;
        public string key6;
        public string key7;
        public string key8;
        public string key9;
    }

    [DisallowMultipleComponent]
    [DefaultExecutionOrder(-1)]
    public class SaveManager : MonoBehaviour
    {

        public RollingMoney _rollingMoney;
        
        public bool isTest = false;

        public static SaveManager Inst { get; private set; }
        
        public TestData testData { get; private set; }

        public List<string> savePathList { get; private set; }
        
        public GameSet gameSet { get; private set; }
        
        public VerObj verObj { get; private set; }

        protected virtual void Awake()
        {
            if (Inst == null)
            {
                Inst = this;
            }
            else if (Inst != this)
            {
                Destroy(gameObject);
            }

            verObj= GetComponent<ResManager>().LoadJsonObj<VerObj>("ver");
           // print(verObj.versions[0].English);
            gameSet = GetComponent<ResManager>().LoadScriptableObject<GameSet>("GameSet");
            //print(gameSet.vk);
            print(GetVersion());
            
            savePathList = new List<string>();
            testData = LoadData<TestData>();
            
            SendMessage("InitLanguage",SendMessageOptions.DontRequireReceiver);
        }

        public string GetVersion()
        {
            return verObj.GetVersionStr() + " "+gameSet.GetVersionFlag();
        }

        protected T LoadData<T>() where T : new()
        {
            T res = default;

            var filePath = Path.Combine(Application.persistentDataPath, typeof(T).Name + ".txt");

            if (File.Exists(filePath) == false)
            {
                res = new T();
                SaveData(res);
            }
            else
            {
              
                res = JsonMapper.ToObject<T>(XOREncryptDecrypt(File.ReadAllText(filePath, new UTF8Encoding(false)),"ytn_game_success"));
            }

            if (savePathList.Contains(filePath) == false)
            {
                savePathList.Add(filePath);
            }

            return res;
        }

        public void PrintData<T>(T data)
        {
            var saveStr = JsonMapper.ToJson(data,true);
            Debug.Log(saveStr);
        }

        public void PrintTestData()
        {
            PrintData(testData);
        }

        public void SaveData<T>(T data)
        {
            var saveStr = JsonMapper.ToJson(data);
            var filePath = Path.Combine(Application.persistentDataPath, typeof(T).Name + ".txt");

            saveStr=XOREncryptDecrypt(saveStr, "ytn_game_success");
            File.WriteAllText(filePath, saveStr, new UTF8Encoding(false));
        }
        
        // XOR加密/解密方法
        private string XOREncryptDecrypt(string input, string key)
        {
            StringBuilder output = new StringBuilder(input.Length);
            for (int i = 0; i < input.Length; i++)
            {
                output.Append((char)(input[i] ^ key[i % key.Length]));
            }
            return output.ToString();
        }

#if UNITY_EDITOR
        [MenuItem("MPStudioManagers/SaveManager/OpenSavePath")]
        public static void OpenSavePath()
        {
            Application.OpenURL(Application.persistentDataPath);
        }
#endif

        public void clearData<T>()
        {
            var filePath = Path.Combine(Application.persistentDataPath, typeof(T).Name + ".txt");
            File.Delete(filePath);
        }

        public void DeleteAllData(string[] files)
        {
            for (var index = files.Length - 1; index >= 0; index--)
            {
                var file = files[index];
                string extension = Path.GetExtension(file).ToLower();
                if (extension == ".txt")
                {
                    // print(file);
                    File.Delete(file);
                }
            }
        }

        public void DeleteAllDataByList()
        {
            DeleteAllData(savePathList.ToArray());
        }

        public void DeleteAllDataByExtension()
        {
            DeleteAllData(Directory.GetFiles(Application.persistentDataPath));
        }

        // Start is called before the first frame update
        protected virtual void Start()
        {

        }

        protected virtual void OnApplicationQuit()
        {
        }

        public void SaveTestData()
        {
            SaveData(testData);
        }

        // Update is called once per frame
        protected virtual void Update()
        {
#if UNITY_EDITOR

            if (isTest == true)
            {
                if (Input.GetKeyDown(KeyCode.Alpha1))
                {
                    testData.年龄 += 1;
                    print("testData Age is " + testData.年龄);
                }
                else if (Input.GetKeyDown(KeyCode.Alpha2))
                {
                    SaveTestData();
                }
                else if (Input.GetKeyDown(KeyCode.Alpha3))
                {
                    clearData<TestData>();
                }
                else if (Input.GetKeyDown(KeyCode.Alpha4))
                {
                    DeleteAllDataByList();
                }
                else if (Input.GetKeyDown(KeyCode.Alpha5))
                {
                    print("al5");
                    _rollingMoney.AddMoney(300);
                }else if (Input.GetKeyDown(KeyCode.Alpha6))
                {
                    _rollingMoney.ReduceMoney(200);
                }else if (Input.GetKeyDown(KeyCode.Alpha7))
                {
                    var go = GameObject.Instantiate(ResManager.Inst.LoadGameObject("ReduceText"));
                    
                    go.GetComponent<ReduceText>().UpdateText("-10000");
                    go.transform.SetParent(GameObject.Find("Canvas/Text (Legacy)").transform,false);
                }
            }


#endif
        }
    }
}