using System.Collections;
using System.Threading;

namespace Guru
{
	using UnityEngine;
	using com.adjust.sdk;
	using System.Threading.Tasks;
	
	
	public static class AdjustService
	{
		public const string Version = "1.6.0";
		public static readonly string LOG_TAG = "Adjust";
		public static readonly float DelayTime = 1f; // 延迟启动时间

		public const string K_IAP_PURCHASE = "iap_purchase"; // 固定点位事件
		public const string K_SUB_PURCHASE = "sub_purchase"; // 固定点位事件
		

		private static string _adId = "";
		public static string AdId
		{
			get
			{
				if(string.IsNullOrEmpty(_adId)) FetchGoogleAdId();
				return _adId; // Google AdId
			}
		}

		private static string _adjustId = "";
		public static string AdjustId
		{
			get
			{
				if (string.IsNullOrEmpty(_adjustId)) _adjustId = Adjust.getAdid();
				return _adjustId; // Adjust AdId;
			}
		}
		
		#region 启动服务

		/// <summary>
		/// Adjust启动服务
		/// </summary>
		/// <param name="appToken"></param>
		/// <param name="fbAppId">MIR 追踪 AppID</param>
		public static void StartService(string appToken, string fbAppId = "")
		{
			if (string.IsNullOrEmpty(appToken))
			{
				Log.E(LOG_TAG, "Adjust没有设置token，无法进行初始化");
				return;
			}

			InstallEvent(IPMConfig.FIREBASE_ID, IPMConfig.IPM_DEVICE_ID); // 注入启动参数

			AdjustEnvironment environment = GetAdjustEnvironment();
			AdjustConfig config = new AdjustConfig(appToken, environment);
			config.setLogLevel(GetAdjustLogLevel());
			config.setDelayStart(DelayTime);

#if UNITY_ANDROID
			if (!string.IsNullOrEmpty(fbAppId)) config.setFbAppId(fbAppId); // 注入 MIR ID
#endif
			

#if UNITY_EDITOR || DEBUG
			config.setLogDelegate(log => Log.I(LOG_TAG, log));
			config.setEventSuccessDelegate(OnEventSuccessCallback);
			config.setEventFailureDelegate(OnEventFailureCallback);
			config.setSessionSuccessDelegate(OnSessionSuccessCallback);
			config.setSessionFailureDelegate(OnSessionFailureCallback);
			config.setAttributionChangedDelegate(OnAttributionChangedCallback);
#endif
			// 检查场景实例
			SetupInstance();
			Adjust.start(config);
			
			// 缓存标准属性
			_adjustId = Adjust.getAdid(); // 获取AdjustID
			
			// 异步加载AdId
			FetchGoogleAdId(); 
		}

		public static void FetchGoogleAdId()
		{
			Adjust.getGoogleAdId(gid =>
			{
				if (!string.IsNullOrEmpty(gid))
				{
					_adId = gid; // 获取Google AD ID 
				}
			});
		}

		/// <summary>
		/// 确保 Adjust 实例在场景中
		/// </summary>
		private static void SetupInstance()
		{
			var go = UnityEngine.GameObject.Find(nameof(Adjust));
			if (go == null)
			{
				go = new GameObject(nameof(Adjust));
				var ins = go.AddComponent<Adjust>();
				ins.startManually = true;
				ins.launchDeferredDeeplink = true;
				ins.sendInBackground = true;
			}
		}
		
		#endregion
		
		#region 关键属性上报

		/// <summary>
		/// 安装事件上报
		/// 该事件只有第一次上报有效
		/// pseudoId 为空时不上报
		/// deviceId 为空时也不上报 (一般不会为空)
		/// </summary>
		/// <param name="pseudoId"></param>
		/// <param name="deviceId"></param>
		public static void InstallEvent(string pseudoId, string deviceId)
		{
			if (string.IsNullOrEmpty(pseudoId))
			{
				Debug.LogWarning($">> Pseudo ID is Empty, skip install event reporting");
				return;
			}

			if (string.IsNullOrEmpty(deviceId))
			{
				Debug.LogWarning($">> Device ID is Empty, skip install event reporting");
				return;
			}
			Debug.LogWarning($"{LOG_TAG} --- addSessionCallbackParameter:  user_pseudo_id:{pseudoId}, device_id:{deviceId}");
			Adjust.addSessionCallbackParameter("user_pseudo_id", pseudoId);
			Adjust.addSessionCallbackParameter("device_id", deviceId);
		}


		#endregion
		
		#region 事件回调函数

		private static void OnAttributionChangedCallback(AdjustAttribution attributionData)
		{
			Log.I(LOG_TAG, "Attribution changed!");

			if (attributionData.trackerName != null)
			{
				Log.I(LOG_TAG, "Tracker name: " + attributionData.trackerName);
			}

			if (attributionData.trackerToken != null)
			{
				Log.I(LOG_TAG, "Tracker token: " + attributionData.trackerToken);
			}

			if (attributionData.network != null)
			{
				Log.I(LOG_TAG, "Network: " + attributionData.network);
			}

			if (attributionData.campaign != null)
			{
				Log.I(LOG_TAG, "Campaign: " + attributionData.campaign);
			}

			if (attributionData.adgroup != null)
			{
				Log.I(LOG_TAG, "Adgroup: " + attributionData.adgroup);
			}

			if (attributionData.creative != null)
			{
				Log.I(LOG_TAG, "Creative: " + attributionData.creative);
			}

			if (attributionData.clickLabel != null)
			{
				Log.I(LOG_TAG , "Click label: " + attributionData.clickLabel);
			}

			if (attributionData.adid != null)
			{
				Log.I(LOG_TAG, "ADID: " + attributionData.adid);
			}
		}

		private static void OnEventSuccessCallback(AdjustEventSuccess eventSuccessData)
		{
			Log.I(LOG_TAG, "Event tracked successfully!");

			if (eventSuccessData.Message != null)
			{
				Log.I(LOG_TAG, "Message: " + eventSuccessData.Message);
			}

			if (eventSuccessData.Timestamp != null)
			{
				Log.I(LOG_TAG, "Timestamp: " + eventSuccessData.Timestamp);
			}

			if (eventSuccessData.Adid != null)
			{
				Log.I(LOG_TAG, "Adid: " + eventSuccessData.Adid);
			}

			if (eventSuccessData.EventToken != null)
			{
				Log.I(LOG_TAG, "EventToken: " + eventSuccessData.EventToken);
			}

			if (eventSuccessData.CallbackId != null)
			{
				Log.I(LOG_TAG, "CallbackId: " + eventSuccessData.CallbackId);
			}

			if (eventSuccessData.JsonResponse != null)
			{
				Log.I(LOG_TAG, "JsonResponse: " + eventSuccessData.GetJsonResponse());
			}
		}

		private static void OnEventFailureCallback(AdjustEventFailure eventFailureData)
		{
			Log.I(LOG_TAG, "Event tracking failed!");

			if (eventFailureData.Message != null)
			{
				Log.I(LOG_TAG, "Message: " + eventFailureData.Message);
			}

			if (eventFailureData.Timestamp != null)
			{
				Log.I(LOG_TAG, "Timestamp: " + eventFailureData.Timestamp);
			}

			if (eventFailureData.Adid != null)
			{
				Log.I(LOG_TAG, "Adid: " + eventFailureData.Adid);
			}

			if (eventFailureData.EventToken != null)
			{
				Log.I(LOG_TAG, "EventToken: " + eventFailureData.EventToken);
			}

			if (eventFailureData.CallbackId != null)
			{
				Log.I(LOG_TAG, "CallbackId: " + eventFailureData.CallbackId);
			}

			if (eventFailureData.JsonResponse != null)
			{
				Log.I(LOG_TAG, "JsonResponse: " + eventFailureData.GetJsonResponse());
			}

			Log.I(LOG_TAG, "WillRetry: " + eventFailureData.WillRetry.ToString());
		}

		private static void OnSessionSuccessCallback(AdjustSessionSuccess sessionSuccessData)
		{
			Log.I(LOG_TAG,"Session tracked successfully!");

			if (sessionSuccessData.Message != null)
			{
				Log.I(LOG_TAG,"Message: " + sessionSuccessData.Message);
			}

			if (sessionSuccessData.Timestamp != null)
			{
				Log.I(LOG_TAG,"Timestamp: " + sessionSuccessData.Timestamp);
			}

			if (sessionSuccessData.Adid != null)
			{
				Log.I(LOG_TAG, "Adid: " + sessionSuccessData.Adid);
			}

			if (sessionSuccessData.JsonResponse != null)
			{
				Log.I(LOG_TAG, "JsonResponse: " + sessionSuccessData.GetJsonResponse());
			}
		}

		private static void OnSessionFailureCallback(AdjustSessionFailure sessionFailureData)
		{
			Log.I(LOG_TAG,"Session tracking failed!");

			if (sessionFailureData.Message != null)
			{
				Log.I(LOG_TAG,"Message: " + sessionFailureData.Message);
			}

			if (sessionFailureData.Timestamp != null)
			{
				Log.I(LOG_TAG,"Timestamp: " + sessionFailureData.Timestamp);
			}

			if (sessionFailureData.Adid != null)
			{
				Log.I(LOG_TAG,"Adid: " + sessionFailureData.Adid);
			}

			if (sessionFailureData.JsonResponse != null)
			{
				Log.I(LOG_TAG,"JsonResponse: " + sessionFailureData.GetJsonResponse());
			}

			Log.I(LOG_TAG,"WillRetry: " + sessionFailureData.WillRetry.ToString());
		}

		#endregion
		
		#region IAP收入上报
		
		/// <summary>
		/// IAP支付事件上报
		/// </summary>
		/// <param name="revenue"></param>
		/// <param name="productID"></param>
		public static void TrackIAPPurchase(double revenue, string productID)
		{
			string tokenID = Analytics.GetAdjustEventToken(K_IAP_PURCHASE);
			if (string.IsNullOrEmpty(tokenID))
				return;
			
			AdjustEvent adjustEvent = new AdjustEvent(tokenID);
			adjustEvent.setRevenue(revenue,"USD");
			adjustEvent.AddEventParameter("platform", Analytics.IAPPlatform);
			adjustEvent.AddEventParameter("product_id", productID);
			adjustEvent.AddEventParameter("value", $"{revenue}");
			Adjust.trackEvent(adjustEvent);
		}
		
		/// <summary>
		/// IAP订阅支付事件上报
		/// </summary>
		/// <param name="revenue"></param>
		/// <param name="productID"></param>
		public static void TrackSubPurchase(double revenue, string productID)
		{
			string tokenID = Analytics.GetAdjustEventToken(K_SUB_PURCHASE);
			if (string.IsNullOrEmpty(tokenID))
				return;

			AdjustEvent adjustEvent = new AdjustEvent(tokenID);
			adjustEvent.setRevenue(revenue,"USD");
			adjustEvent.AddEventParameter("platform", Analytics.IAPPlatform);
			adjustEvent.AddEventParameter("product_id", productID);
			adjustEvent.AddEventParameter("value", $"{revenue}");
			Adjust.trackEvent(adjustEvent);
		}
		
		/// <summary>
		/// 广告收入上报 (Adjust 特有的接口)
		/// </summary>
		/// <param name="adInfo"></param>
		public static void TrackADRevenue(MaxSdkBase.AdInfo adInfo)
		{
			if (adInfo == null)
				return;
			
			var adRevenue = new AdjustAdRevenue(AdjustConfig.AdjustAdRevenueSourceAppLovinMAX);
			adRevenue.setRevenue(adInfo.Revenue, "USD");
			adRevenue.setAdRevenueNetwork(adInfo.NetworkName);
			adRevenue.setAdRevenueUnit(adInfo.AdUnitIdentifier);
			adRevenue.setAdRevenuePlacement(adInfo.Placement);
			Adjust.trackAdRevenue(adRevenue);
		}
		
		
		
		

		#endregion

		#region 关键属性上报
		
		/// <summary>
		/// 上报PseudoId
		/// </summary>
		/// <param name="firebaseId"></param>
		public static void ReportPseudoID(string firebaseId)
		{
			if (!string.IsNullOrEmpty(firebaseId))
			{
				Adjust.addSessionCallbackParameter("user_pseudo_id", firebaseId); // 关联 user_pseudo_id
			}
		}

		/// <summary>
		/// 上报DeviceId
		/// </summary>
		/// <param name="deviceId"></param>
		public static void ReportDeviceId(string deviceId)
		{
			if (!string.IsNullOrEmpty(deviceId))
			{
				Adjust.addSessionCallbackParameter("device_id", deviceId); // 关联 user_pseudo_id
			}
		}

		#endregion

		#region 工具接口

		private static AdjustEnvironment GetAdjustEnvironment()
		{
#if UNITY_EDITOR || DEBUG
			return AdjustEnvironment.Sandbox;
#else
			return AdjustEnvironment.Production;
#endif
		}

		private static AdjustLogLevel GetAdjustLogLevel()
		{
#if UNITY_EDITOR || DEBUG
			return AdjustLogLevel.Verbose;
#else
			return AdjustLogLevel.Suppress;
#endif
		}
		
		#endregion
		
	}
}