using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
using UnityEngine;


namespace Guru
{
    
    public class GuruAnalytics
    {
        // Plugin Version
        public const string Version = "1.8.4";
        
        public static readonly string Tag = "[ANA]"; 
        private static IAnalyticsAgent _agent;

        public static IAnalyticsAgent Agent
        {
            get
            {
                if (_agent == null)
                {
    #if UNITY_EDITOR
                    _agent = new AnalyticsAgentStub();
    #elif UNITY_ANDROID
                    _agent = new AnalyticsAgentAndroid();
    #elif UNITY_IOS
                    _agent = new AnalyticsAgentIOS();
    #endif
                }
                return _agent;
            }
        }

        private static Dictionary<string, string> _userProperties;
        /// <summary>
        /// 用户属性缓存字典
        /// </summary>
        public static Dictionary<string, string> UserProperties
        {
            get
            {
                if (_userProperties == null)
                {
                    _userProperties = new Dictionary<string, string>(10);
                }
                return _userProperties;
            }
        }

        private static bool _autoSyncProperties = false;

        #region 公用接口
        
        /// <summary>
        /// 初始化接口
        /// </summary>
        public static void Init(string appId, string deviceInfo, bool isDebug = false, bool syncProperties = false)
        {
            _autoSyncProperties = syncProperties;
            Agent?.Init(appId, deviceInfo, isDebug);
        }

        /// <summary>
        /// 设置视图名称
        /// </summary>
        /// <param name="screenName"></param>
        public static void SetScreen(string screenName)
        {
            CacheUserProperty($"screen_name", screenName);
            Agent?.SetScreen(screenName);
        }

        /// <summary>
        /// 设置广告ID
        /// </summary>
        /// <param name="id"></param>
        public static void SetAdId(string id)
        {
            CacheUserProperty($"ad_id", id);
            Agent?.SetAdId(id);
        }

        /// <summary>
        /// 设置用户属性
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public static void SetUserProperty(string key, string value)
        {
            CacheUserProperty(key, value); // 添加用户属性
            Agent?.SetUserProperty(key, value);
        }
        /// <summary>
        /// 设置Firebase ID
        /// </summary>
        /// <param name="id"></param>
        public static void SetFirebaseId(string id)
        {
            CacheUserProperty($"firebase_id", id);
            Agent?.SetFirebaseId(id);
        }

        /// <summary>
        /// 设置Adjust ID
        /// </summary>
        /// <param name="id"></param>
        public static void SetAdjustId(string id)
        {
            CacheUserProperty($"adjust_id", id);
            Agent?.SetAdjustId(id);
        }

        /// <summary>
        /// 设置设备ID
        /// </summary>
        /// <param name="deviceId"></param>
        public static void SetDeviceId(string deviceId)
        {
            CacheUserProperty($"device_id", deviceId);
            Agent?.SetDeviceId(deviceId);
        }


        public static void SetAndroidID(string androidId)
        {
            CacheUserProperty(Analytics.PropertyAndroidID, androidId);
        }
        
        public static void SetIDFV(string idfv)
        {
            CacheUserProperty(Analytics.PropertyIDFV, idfv);
        }


        /// <summary>
        /// 设置用户ID
        /// </summary>
        /// <param name="uid"></param>
        public static void SetUid(string uid)
        {
            CacheUserProperty($"uid", uid);
            Agent?.SetUid(uid);
        }

        /// <summary>
        /// 上报事件成功率
        /// </summary>
        public static void ReportEventSuccessRate() => Agent?.ReportEventSuccessRate();

        /// <summary>
        /// 上报打点事件
        /// </summary>
        /// <param name="eventName">事件名称</param>
        /// <param name="data">INT类型的值</param>
        public static void LogEvent(string eventName, Dictionary<string, dynamic> data = null)
        {
            if(_autoSyncProperties)
                UpdateAllUserProperties(); // 每次打点更新用户属性
            
            string raw = "";
            if (data != null && data.Count > 0)
            {
                raw = BuildParamsJson(data);
            }
            Debug.Log($"{Tag} event:{eventName} | raw: {raw}");
            Agent?.LogEvent(eventName, raw);
        }

        private static string BuildParamsString(Dictionary<string, dynamic> data)
        {
            string raw = "";
            List<string> strList = new List<string>(data.Count);
            foreach (var kvp in data)
            {
                strList.Add(BuildStringValue(kvp));
                raw = string.Join(",", strList);
            }
            return raw;
        }

        private static string BuildParamsJson(Dictionary<string, dynamic> data)
        {
            try
            {
                //  强制转换加入国家设置
                return JsonConvert.SerializeObject(data, new JsonSerializerSettings()
                {
                    Culture = new CultureInfo("en-US"),
                });
            }
            catch (Exception e)
            {
                Debug.LogError(e);
            }

            return "";
        }

        /// <summary>
        /// 构建带有类型格式的Str值
        /// </summary>
        /// <param name="kvp"></param>
        /// <returns></returns>
        private static string BuildStringValue(KeyValuePair<string, dynamic> kvp)
        {
            if (kvp.Value is int || kvp.Value is long)
            {
                return $"{kvp.Key}:i{kvp.Value}";
            }
            
            if (kvp.Value is double || kvp.Value is float)
            {
                double dValue = (double)((object)kvp.Value);
                return $"{kvp.Key}:d{dValue.ToString("F11", new CultureInfo("en-US"))}";  // 保留精度进行转换
            }

            return $"{kvp.Key}:s{kvp.Value}";
        }

        /// <summary>
        /// 设置太极02值
        /// </summary>
        /// <param name="value"></param>
        public static void SetTch02Value(double value)
        {
            Debug.Log($"{Tag} set tch_02_value:{value}");
            Agent?.SetTch02Value(value);
        }

        #endregion

        #region iOS独有接口

#if UNITY_IOS
        // 触发测试崩溃埋点
        public static void TestCrash() => AnalyticsAgentIOS.TestCrashEvent();
#endif

        #endregion

        #region 用户属性

        /// <summary>
        /// 记录用户属性
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        private static void CacheUserProperty(string key, string value)
        {
            bool needUpdate = !UserProperties.ContainsKey(key) || UserProperties[key] != value;
            UserProperties[key] = value;

            // if (needUpdate) UpdateAllUserProperties();
        }


        private static void UpdateAllUserProperties()
        {
            if (UserProperties != null && UserProperties.Count > 0)
            {
                var keys = UserProperties.Keys.ToArray();
                int i = 0;
                string key = "";
                while (i < keys.Length)
                {
                    key = keys[i];
                    if(!string.IsNullOrEmpty(key)) SetUserProperty(key, UserProperties[key]);
                    i++;
                }
                keys = null;
            }
        }


        #endregion
    }
}

