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

#if UNITY_EDITOR
using UnityEditor;
#endif

using UnityEngine;

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

        public long money = 0;

        
        //備用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; }

        protected virtual void Awake()
        {
            if (Inst == null)
            {
                Inst = this;
            }
            else if (Inst != this)
            {
                Destroy(gameObject);
            }
            
            savePathList = new List<string>();
            testData = LoadData<TestData>();
        }

        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 = JsonUtility.FromJson<T>(XOREncryptDecrypt(File.ReadAllText(filePath, new UTF8Encoding(false)),"ytn_game_success"));
            }

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

            return res;
        }

        public void SaveData<T>(T data)
        {
            var saveStr = JsonUtility.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("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
        }
    }
}