namespace Guru
{
	using System;
	using System.Collections.Generic;
	using Firebase.Analytics;
	using Firebase.Crashlytics;
	using Firebase.Extensions;
	using UnityEngine;
	
	/// <summary>
    /// 自打点逻辑
    /// </summary>
    public partial class Analytics
    {
	    private static bool _hasGotFirebaseId;  //已取得FirebaseId
	    private static bool _hasGotAdId; // 已取得AdId
	    private static bool _hasGotAdjustId; // 已取得AdjustId
	    private static bool _hasGotDeviceId; // 已取得DeviceId
	    private static bool _hasGotUid; // 已取得UID
	    private static DateTime _lastReportRateDate; //上次上报信息的日期
	    private static double _reportSuccessInterval; // 上报频率
	    
	    private const string VALUE_NOT_FOR_IOS = "not_support_for_ios";

	    public static bool IsDebug { get; set; } = false;

	    private static bool _hasInited = false;

	    public static bool IsReady => _hasInited;

	    /// <summary>
	    /// 初始化Guru自打点系统 (请优先于 Firebase 初始化调用)
	    /// </summary>
	    public static void InstallGuruAnalytics(bool isDebug = false)
	    {
		    if (_hasInited) return;
		    
	        try
	        {
#if UNITY_EDITOR
        		IsDebug = true;
#else
				IsDebug = isDebug;
#endif
		        string appId = IPMConfig.IPM_X_APP_ID;
		        string deviceInfo = new DeviceInfoData().ToString();
		        GuruAnalytics.Init(appId, deviceInfo, IsDebug); // 初始化(带Header) 
		        
		        _hasGotFirebaseId = false;
		        _hasGotAdId = false;
		        _hasGotAdjustId = false;
		        _hasGotDeviceId = false;
		        _hasGotUid = false;
		        _lastReportRateDate = DateTime.Now;
				_reportSuccessInterval = 120; // 2分钟上报一次
	        
		        UpdateAllValues();

		        _hasInited = true;
	        }
	        catch (Exception e)
	        {
        		Crashlytics.LogException(e);
	        }
	    }

		#region 各ID上报信息

		/// <summary>
		/// 设置用户ID
		/// </summary>
		private static void SetUid()
		{
			if (_hasGotUid) return;
			
			if (!string.IsNullOrEmpty(IPMConfig.IPM_UID))
			{
				Debug.Log($"---[ANA] UID: {IPMConfig.IPM_UID}");
				GuruAnalytics.SetUid(IPMConfig.IPM_UID);
				_hasGotUid = true;
			}

		}

		/// <summary>
		/// 设置设备ID
		/// </summary>
		private static void SetDeviceId()
		{
			if (_hasGotDeviceId) return;
			
			if (!string.IsNullOrEmpty(IPMConfig.IPM_DEVICE_ID))
			{
				GuruAnalytics.SetDeviceId(IPMConfig.IPM_DEVICE_ID);
				_hasGotDeviceId = true;
			}
		}
		
		/// <summary>
		/// 设置 AdjustId 
		/// </summary>
		private static void SetAdjustId()
		{
			if (_hasGotAdjustId) return;

			string adjustId = AdjustService.AdjustId;
			if (!string.IsNullOrEmpty(adjustId))
			{
				IPMConfig.ADJUST_ID = adjustId;
			}

			if (!string.IsNullOrEmpty(IPMConfig.ADJUST_ID))
			{
				GuruAnalytics.SetAdjustId(IPMConfig.ADJUST_ID);
				_hasGotAdjustId = true;
			}
			else
			{
				Debug.Log($"--- [ANA] AdjustId is Empty..");
			}

		}
		
		/// <summary>
		/// 设置 AdId
		/// </summary>
		private static void SetAdId()
		{
			if (_hasGotAdId) return;
			
#if UNITY_ANDROID
			var adId = AdjustService.AdId;
			if (!string.IsNullOrEmpty(adId))
			{
				// Debug.Log($"---[ANA] ADID: {adId}");
				IPMConfig.ADJUST_ADID = adId;
			}
#else
			// ============= ADID is not supported on Adjust iOS API ==============
			IPMConfig.ADJUST_ADID = VALUE_NOT_FOR_IOS;;
#endif
			
			if (!string.IsNullOrEmpty(IPMConfig.ADJUST_ADID))
			{
				GuruAnalytics.SetAdId(IPMConfig.ADJUST_ADID);
				_hasGotAdId = true;
			}
			
		}

		/// <summary>
		/// 设置FirebaseId
		/// </summary>
		private static void SetFirebaseId()
		{
			if (_hasGotFirebaseId) return;
			
			if (!string.IsNullOrEmpty(IPMConfig.FIREBASE_ID))
			{
				GuruAnalytics.SetFirebaseId(IPMConfig.FIREBASE_ID);
				_hasGotFirebaseId = true;
			}
			else
			{
				FetchFirebaseId();
			}
		}

		/// <summary>
		/// 获取FirebaseID
		/// </summary>
		private static void FetchFirebaseId()
		{
			FirebaseAnalytics.GetAnalyticsInstanceIdAsync()
				.ContinueWithOnMainThread(task =>
			{
				if (task != null && task.IsCompleted)
				{
					var fid = task.Result;
					if (!string.IsNullOrEmpty(fid) 
					    && string.IsNullOrEmpty(IPMConfig.FIREBASE_ID))
					{
						IPMConfig.FIREBASE_ID = fid;
					}
				}
			});
		}

#if UNITY_IOS	
	    /// <summary>
	    /// 更新ATT状态 (Only IOS 有效)
	    /// </summary>
	    private static void SetATTStatus()
	    {
		    string status = ATTManager.GetStatus();
		    GuruAnalytics.SetUserProperty(ParameterATTStatus, status);
	    }

	    private static void SetIDFV()
	    {
		    GuruAnalytics.SetIDFV(DeviceIDHelper.IDFV);
	    }
	    
#endif

#if UNITY_ANDROID 
		/// <summary>
	    /// 更新 Android ID 的参数
	    /// </summary>
	    private static void SetAndroidId()
	    {
		    GuruAnalytics.SetAndroidID(DeviceIDHelper.AndroidID);
	    }
#endif	    
	    
		/// <summary>
		/// 获取全部ID
		/// </summary>
		private static void UpdateAllValues()
		{
			SetUid();
			SetDeviceId();
			SetAdjustId();
			SetFirebaseId();
			SetAdId();
			
#if UNITY_ANDROID
			SetAndroidId();
#endif
			
#if UNITY_IOS
			SetATTStatus();
			SetIDFV();
#endif  
			ReportEventSuccessRate();
		}

		/// <summary>
		/// 上报事件成功率
		/// </summary>
		private static void ReportEventSuccessRate()
		{
			var interval = (DateTime.Now - _lastReportRateDate).TotalSeconds;
			if (interval > _reportSuccessInterval)
			{
				GuruAnalytics.ReportEventSuccessRate();
				_lastReportRateDate = DateTime.Now;
			}
		}

		#endregion
		
		#region 自定义打点

		/// <summary>
		/// 自定义设置用户属性
		/// </summary>
		/// <param name="key"></param>
		/// <param name="value"></param>
		private static void CustomSetUserProperty(string key, string value)
		{
			try
			{
				GuruAnalytics.SetUserProperty(key, value);
				UpdateAllValues(); // 同步所有的ID
			}
			catch (Exception e)
			{
				Crashlytics.LogException(e);
			}
			
		}
		
	    /// <summary>
	    /// 自定义事件打点
	    /// </summary>
	    /// <param name="key"></param>
	    /// <param name="data"></param>
	    private static void CustomLogEvent(string key, Dictionary<string, dynamic> data = null)
	    {
		    try
		    {
			    if (data == null) data = new Dictionary<string, dynamic>();
			    GuruAnalytics.LogEvent(key, data);
			    UpdateAllValues(); // 同步所有的ID
		    }
		    catch (Exception e)
		    {
			    Crashlytics.LogException(e);
		    }
	    }
	    
	    /// <summary>
	    /// 设置太极02阀值
	    /// </summary>
	    /// <param name="value"></param>
	    public static void SetTch02TargetValue(double value)
	    {
		    try
		    {
			    if (value > 0)
			    {
				    EnableTch02Event = true; // 自动开启太极02打点设置
				    if (Math.Abs(_tch02TargetValue - value) > 0.001d)
				    {
					    _tch02TargetValue = value;
					    GuruAnalytics.SetTch02Value(value);
				    }
			    }
		    }
		    catch (Exception e)
		    {
			    Crashlytics.LogException(e);
		    }
	    }

	    #endregion
    }
}