namespace Guru
{
    using System.Linq;
    using System;
    using System.Collections.Generic;
    using Firebase.RemoteConfig;
    using Newtonsoft.Json;
    using UnityEngine;
    
    /// 
    /// ABTEST 管理器
    /// 
    public class ABTestManager : Singleton
    {
        public const string Version = "1.0.2";
        private FirebaseRemoteConfig _remoteConfig;
        private List _params;
        
        
        internal static void LogCrashlytics(string msg) => Analytics.LogCrashlytics(msg);
        
        internal static void LogCrashlytics(Exception ex) => Analytics.LogCrashlytics(ex);
        
        #region 初始化
        
        /// 
        ///  初始化
        /// 
        public static void Init()
        {
            try
            {
                Instance.Setup();
            }
            catch (Exception e)
            {
                LogCrashlytics(e);
                Debug.LogError(e);
            }
            
        }
        
        /// 
        /// 安装服务
        /// 
        private void Setup()
        {
            Debug.Log($"[AB] --- ABTest Init");
            _params = new List();
            
            _remoteConfig = FirebaseRemoteConfig.DefaultInstance;
            
            Debug.Log($"[AB] --- remoteConfig Counts: {_remoteConfig.Keys.Count()}");
            
            string strValue;
            foreach (var key in _remoteConfig.Keys)
            {
                strValue = _remoteConfig.GetValue(key).StringValue;
                Debug.Log($"[AB] --- raw config: [{key}] : {strValue}");
                AddParam(strValue);
            }
            
            // ------- ABTest -----------
            // Debug.Log($" --- start parse test string --- ");
            // var testStr = @"{""enabled"":true,""value"":2,""id"":""B"",""guru_ab_23100715"":""B""}";
            // AddParam(testStr);
            
            if (_params.Count > 0)
            {
                for (int i = 0; i < _params.Count; i++)
                {
                    // 上报实验AB属性
                    GuruAnalytics.SetUserProperty(_params[i].id, _params[i].group);
#if UNITY_EDITOR
                    Debug.Log($"[AB] --- Add AB Param {_params[i].ToString()}");
#else
                    Debug.Log($"[AB] --- Add AB Param {_params[i].ToString()}");
#endif
                }
            }
        
        }
        
        #endregion
        
        #region 添加AB参数
        /// 
        /// 添加AB参数
        /// 
        /// 
        private void AddParam(string value)
        {
            if (!string.IsNullOrEmpty(value) && value.Contains("guru_ab_"))
            {
                var p = ABParamData.Parse(value);
                if(p != null) _params.Add(p); // 添加参数
            }
        }
        
        #endregion
        #region 单元测试
        public static void TestConfig(string json)
        {
            var p = ABParamData.Parse(json);
            if (p == null)
            {
                Debug.LogError($"Could not parse config: {json}");
                return;
            }
            if (!string.IsNullOrEmpty(p.group))
            {
                Debug.Log($"ID: {p.id}");
                Debug.Log($"Group: {p.group}");
                Debug.Log($"Value: {p.value}");
            }
        }
        
        #endregion
    }
    
    [Serializable]
    internal class ABParamData
    {
        private const int PARAM_NAME_LENGTH = 23; // 从开始"ab_" 计算, 往后20个字符
        
        public string id;
        public string group;
        public string value;
        
        public static ABParamData Parse(string value)
        {
            Debug.Log($"--- ABParamData.Parse: {value}");
            try
            {
                // 发现Guru AB测试标志位
                // var dict = JsonMapper.ToObject>(value);
                var dict =  JsonConvert.DeserializeObject>(value);
                if (null != dict)
                {
                    foreach (var k in dict.Keys)
                    {
                        if (k.StartsWith("guru_ab"))
                        {
                            return new ABParamData()
                            {
                                id = GetItemKey(k),
                                group = dict[k].ToString(),
                                value = value
                            };
                        }
                    }
                }
            }
            catch (Exception e)
            {
                string msg = $"[AB] --- Parse AB Param Error -> Value: {value}\n{e.Message}";
                ABTestManager.LogCrashlytics(msg);
                Debug.Log(msg);
            }
            return null;
        }
        private static string GetItemKey(string raw)
        {
            int ln = "guru_".Length;
            var key = raw.Substring(ln, Mathf.Min(PARAM_NAME_LENGTH, raw.Length - ln)); // 最大长度23
            return key; 
        }
        /// 
        /// 输出字符串
        /// 
        /// 
        public override string ToString()
        {
            return $"{id} : {group}";
        }
    }
}