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

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

        private PlayData c2s_preferencesMsg;

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

        private static string CachePath = Application.persistentDataPath + "/Cache/CacheLocalPreferences.txt";

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

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

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

        public override void StartUp()
        {
            base.StartUp();
            dataDispatcher = DataDispatcher.Instance;
            TimerHelper.UnscaleGeneral.AddLoopTimer(10, OnAutoDelaySave);
        }

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

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

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

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

        public void InitPreferences()
        {
            /*if (ModuleManager.Instance.GetModel(ModelConst.LoginModel) is LoginModel loginModel)
            {
                preferences = loginModel.preferences ?? ReadServerPreferencesCache();
            }*/

            preferences = ReadServerPreferencesCache();
            // Debug.Log(preferences.uid);
            // Debug.Log(GameHelper.GetLoginModel().uid);
            if (preferences == null || preferences.uid != GameHelper.GetLoginModel().uid)
            {
                preferences = new Preferences();
                preferences.uid = GameHelper.GetLoginModel().uid;
            }
            else
            {
                SaveServerPreferencesCache(preferences);
            }

            OnInitPreferences();
        }

        private void AutoSaveList(List<KeyValue> autolist)
        {
            if (autolist == null || autolist.Count == 0) return;
            foreach (var 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(Psvsagh timerInfo)
        {
            AutoSaveList(autoSaveList);
            PreferencesSendSave();
        }

        #region 远程存储

        #region 保存方法

        private void AddToAutoDelaySaveList(string key, object value)
        {
            var 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()
        {
        }

        private long timeSave;
        private long unsaveCount;

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

            AddDataVer();

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

                unsaveCount = 0;
                timeSave = GameHelper.GetNowTime();
                var data = Havva.ToObject<Dictionary<string, object>>(Havva.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 = Havva.ToJson(preferences);
            if (!Directory.Exists(CachePath + "/.."))
            {
                Directory.CreateDirectory(CachePath + "/..");
            }

            File.WriteAllText(CachePath, text);
        }

        /// <summary>
        /// 读取Preferences缓存服务器数据
        /// </summary>
        public static Preferences ReadServerPreferencesCache()
        {
            Preferences preferences = null;
            var path = 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 = Havva.ToObject<Preferences>(text);
                }
                catch (Exception)
                {
                    Debug.LogError("[LoginLocalCache]ReadServerPreferencesCache Fail!");
                }
            }

            return preferences;
        }

        #endregion 封装
    }
}