using System;
using System.IO;
using UnityEngine;
using System.Collections.Generic;

namespace ScrewsMaster
{
    public sealed partial class PreferencesMgr : BaseInterfaceManager<PreferencesMgr>
    {
        private Preferences preferences;
        private DataDispatcher dataDispatcher;

        private PlayData c2s_preferencesMsg;

        private ObjectPool<KeyValue> keyValuePool;
        private List<KeyValue> autoSaveList;

        public override void Init()
        {
            base.Init();
            AddListener();

            c2s_preferencesMsg = new PlayData
            {
                data = new Dictionary<string, object>()
            };

            keyValuePool = new ObjectPool<KeyValue>();
            autoSaveList = new List<KeyValue>();
        }

        public override void StartUp()
        {
            base.StartUp();

            dataDispatcher = DataDispatcher.Instance;
            //HACK preferences服务器数据实时存储
            TimerHelper.UnscaleGeneral.AddLoopTimer(10, OnAutoDelaySave);
        }

        public override void DisposeBefore()
        {
            base.DisposeBefore();
            ImmediateSendSave();
        }

        public override void Dispose()
        {
            base.Dispose();
            RemoveListener();

            //autoSaveTimer.Dispose(); 
            keyValuePool.Dispose();
        }

        private void AddListener()
        {
            AppDispatcher.Instance.AddListener(AppMsg.App_Pause_True, ImmediateSendSave);
        }

        private void RemoveListener()
        {
            AppDispatcher.Instance.RemoveListener(AppMsg.App_Pause_True, ImmediateSendSave);
        }

        public void InitPreferences()
        {
            LoginModel loginModel = ModuleManager.Instance.GetModel(ModelConst.LoginModel) as LoginModel;

            preferences = new Preferences();
            if (!loginModel.new_player)
            {
                preferences = ReadServerPreferencesCache();

                var ser_dataVer = loginModel.play_data_ver;
                if (preferences == null || ser_dataVer > preferences.data_ver)
                {
                    preferences = loginModel.preferences;
                }

                if (preferences == null)
                {
                    preferences = new Preferences();
                }
            }
            else
            {
                PlayerPrefs.DeleteAll();
                NetworkKit.SetCacheToken(loginModel.token);
                PlayerPrefs.Save();

            }

            SaveServerPreferencesCache(preferences);

            OnInitPreferences();
        }

        private void AutoSaveList(List<KeyValue> autolist)
        {
            if (autolist == null || autolist.Count == 0) return;
            foreach (KeyValue item in autolist)
            {
                Save(item.key, item.value);
                keyValuePool.Release(item);
            }

            autolist.Clear();
        }

        private void AddDataVer()
        {
            ++Data_ver;
        }

        /// <summary>
        /// 立即发送保存
        /// </summary>
        public void ImmediateSendSave(object arg = null)
        {
            AutoSaveList(autoSaveList);
            PreferencesSendSave();
        }

        private void OnAutoDelaySave(TimerTask timerInfo)
        {
            AutoSaveList(autoSaveList);
            PreferencesSendSave();
        }

        #region 远程存储

        #region 保存方法

        private void AddToAutoDelaySaveList(string key, object value)
        {
            KeyValue item = keyValuePool.Get();
            item.key = key;
            item.value = value;
            autoSaveList.Add(item);

            ImmediateSendSave();
        }

        private void Save<T>(string key, T data)
        {
            c2s_preferencesMsg.data[key] = data;
        }

        #endregion 保存方法

        private void ClearPreferencesDic()
        {
            // c2s_preferencesMsg.data.Clear();
        }

        private long timeSave = 0;
        private long unsaveCount = 0;

        private void PreferencesSendSave()
        {
            if (c2s_preferencesMsg == null || c2s_preferencesMsg.data.Count == 0) return;

            AddDataVer();

            SaveServerPreferencesCache(preferences);
            try
            {
                // if (unsaveCount < 3)
                // {
                //     if (timeSave > 0 && GameHelper.GetNowTime() - timeSave < 3)
                //     {
                //         unsaveCount++;
                //         return;
                //     }
                // }

                // unsaveCount = 0;
                // timeSave = GameHelper.GetNowTime();
                // var data = SerializeUtil.ToObject<Dictionary<string, object>>(SerializeUtil.ToJson(preferences));
                // NetworkDispatcher.Instance.Dispatch(NetworkMsg.SavePlayData, data);
            }
            catch (Exception e)
            {
                Debug.LogError(e);
                throw;
            }

            ClearPreferencesDic();
        }

        #endregion 远程存储

        #region 封装

        public Preferences GetPreferences()
        {
            return preferences;
        }

        /// <summary>
        /// 保存Preferences缓存服务器数据
        /// </summary>
        public static void SaveServerPreferencesCache(Preferences preferences)
        {
            var text = SerializeUtil.ToJson(preferences);
            if (!Directory.Exists(PlayerPrefsConst.CachePath + "/.."))
            {
                Directory.CreateDirectory(PlayerPrefsConst.CachePath + "/..");
            }

            File.WriteAllText(PlayerPrefsConst.CachePath, text);
        }

        /// <summary>
        /// 读取Preferences缓存服务器数据
        /// </summary>
        public static Preferences ReadServerPreferencesCache()
        {
            Preferences preferences = null;
            var path = PlayerPrefsConst.CachePath;
            if (File.Exists(path))
            {
                try
                {
                    string text = File.ReadAllText(path);
                    if (string.IsNullOrEmpty(text))
                    {
                        // Debug.LogError("[JsonEncryptUtil]ReadFormLocalFile decryptedString Fail: " + path);
                        preferences = null;
                    }

                    preferences = SerializeUtil.ToObject<Preferences>(text);
                }
                catch (Exception)
                {
                    // Debug.LogError("[LoginLocalCache]ReadServerPreferencesCache Fail!");
                }
            }

            return preferences;
        }

        #endregion 封装
    }
}