using System;
using System.Globalization;
using UnityEngine;

namespace Guru
{
	/// <summary>
	/// 中台配置信息参数
	/// </summary>
	public static class IPMConfig
	{
		public static string IPM_X_APP_ID => GuruSettings.Instance.IPMSetting.AppId;
		public static int TOKEN_VALID_TIME => GuruSettings.Instance.IPMSetting.TokenValidTime;
		public static readonly int FIREBASE_TOKEN_VALID_TIME = TimeUtil.HOUR_TO_SECOND;
		public static bool UsingUUID = GuruSettings.Instance.UsingUUID();
		

		public static readonly string Header_Param_APPID = "X-APP-ID";
		public static readonly string Header_Param_DEVICE_INFO = "X-DEVICE-INFO";
		public static readonly string Header_Param_UID = "X-UID";
		public static readonly string Header_Param_ACCESS_TOKEN = "X-ACCESS-TOKEN";
		public static readonly string Header_Param_ContentType = "Content-Type";
		public static readonly string Header_Value_ContentType = "application/json";
		public static readonly string POST_Param_AccessToken = "accessToken";
		public static readonly string POST_Param_IDToken = "idToken";
		public static readonly string POST_Param_Token = "token";
		public static readonly string POST_Param_Provider = "provider";
		public static readonly string POST_Param_ClientType = "clientType";
		public static readonly string POST_Param_TokenSecret = "tokenSecret";
		
		public static string IPM_APP_PACKAGE_NAME = Application.identifier;
		public static string IPM_APP_VERSION = Application.version;
		public static string IPM_IOS_APP_GROUP = "group." + Application.identifier;
		public static string IPM_BRAND = "";
		public static string IPM_LANGUAGE = "";
		public static string IPM_MODEL = "";
		public static string IPM_TIMEZONE = "";
		public static string IPM_LOCALE  = "";
		public static string IPM_COUNTRY_CODE = RegionInfo.CurrentRegion.TwoLetterISORegionName;
		public static bool IPM_NEWUSER = false;
		
		/// <summary>
		/// 中台设备 ID
		/// </summary>
		public static string IPM_DEVICE_ID
		{
			get
			{
				if (string.IsNullOrEmpty(SavedDeviceId))
				{
					GenDeviceId();
				}
				
				return SavedDeviceId; // 优先使用缓存的 DeviceID
			}
		}
		
		private static bool IsValidDeviceId(string deviceId)
		{
			return !(string.IsNullOrEmpty(deviceId) || deviceId.Contains("0000-0000-0000"));
		}

		/// <summary>
		/// 用生成设备ID (V1)
		/// 使用 Unity 的 SystemInfo.deviceUniqueIdentifier 作为设备 ID
		/// </summary>
		/// <returns></returns>
		private static string GenerateDeviceIdV1()
		{
			var did = SystemInfo.deviceUniqueIdentifier;
			if (!IsValidDeviceId(did))
			{
				//空串, 或者IOS 生成了无效的 IDFV, 则使用 DeviceIDHelper 代替
				did = DeviceIDHelper.UUID;
			}
			return did;
		}
		
		/// <summary>
		/// 用生成设备ID (V2)
		/// 直接使用 DeviceIDHelper 作为设备的唯一标识
		/// </summary>
		/// <returns></returns>
		private static string GenerateDeviceIdV2() => DeviceIDHelper.UUID;

		
		/// <summary>
		/// 缓存设备ID
		/// </summary>
		private static string SavedDeviceId
		{
			get => PlayerPrefs.GetString(nameof(SavedDeviceId), "");  
			set => PlayerPrefs.SetString(nameof(SavedDeviceId), value);
		}
		
		public static void GenDeviceId()
		{
			if (UsingUUID)
			{
				SavedDeviceId = GenerateDeviceIdV2();
			}
			else
			{
				SavedDeviceId = GenerateDeviceIdV1();
			}
			Debug.Log($"[SDK] Gen DeviceID with UUID:{UsingUUID} : {SavedDeviceId}");
		}
		
		/// <summary>
		/// 设置 DeviceID, 此处设计覆写原则
		/// </summary>
		/// <param name="deviceId"></param>
		/// <param name="overwrite"></param>
		public static void SetDeviceId(string deviceId, bool overwrite  = false)
		{
			// 不写入空字符串
			if (string.IsNullOrEmpty(deviceId)) return;
			// 如果设备ID无效 或 需要覆盖写入
			if (!IsValidDeviceId(SavedDeviceId) || overwrite)
				SavedDeviceId = deviceId;
		}
		
#if DEBUG
		public static readonly string IPM_URL = "https://dev.saas.castbox.fm/";
#else
		public static readonly string IPM_URL = "https://saas.castbox.fm/";
#endif
		public static readonly string IPM_EVENT_URL = IPM_URL + "push/api/v1/push/app/event";

		
		public static string IPM_UUID
		{
			get => PlayerPrefs.GetString(nameof(IPM_UUID), "");
			set => PlayerPrefs.SetString(nameof(IPM_UUID), value);
		}
		
		public static string IPM_UID
		{
			get => PlayerPrefs.GetString(nameof(IPM_UID), "");
			set => PlayerPrefs.SetString(nameof(IPM_UID), value);
		}
		
		public static long IPM_UID_INT
		{
			get => Convert.ToInt64(PlayerPrefs.GetString(nameof(IPM_UID_INT), "0"));
			set => PlayerPrefs.SetString(nameof(IPM_UID_INT), value.ToString());
		}
		
		public static string IPM_TOKEN
		{
			get => PlayerPrefs.GetString(nameof(IPM_TOKEN), "");
			set => PlayerPrefs.SetString(nameof(IPM_TOKEN), value);
		}
		
		public static int IPM_TOKEN_TIME
		{
			get => PlayerPrefs.GetInt(nameof(IPM_TOKEN_TIME), 0);
			set => PlayerPrefs.SetInt(nameof(IPM_TOKEN_TIME), value);
		}
		
		public static string IPM_FIREBASE_TOKEN
		{
			get => PlayerPrefs.GetString(nameof(IPM_FIREBASE_TOKEN), "");
			set => PlayerPrefs.SetString(nameof(IPM_FIREBASE_TOKEN), value);
		}
		
		public static string IPM_PUSH_TOKEN
		{
			get => PlayerPrefs.GetString(nameof(IPM_PUSH_TOKEN), "");
			set => PlayerPrefs.SetString(nameof(IPM_PUSH_TOKEN), value);
		}
		
		//是否已经成功上报过设备信息
		public static bool IS_UPLOAD_DEVICE_SUCCESS
		{
			get => PlayerPrefs.GetInt(nameof(IS_UPLOAD_DEVICE_SUCCESS), 0) == 1;
			set => PlayerPrefs.SetInt(nameof(IS_UPLOAD_DEVICE_SUCCESS), true ? 1 : 0);
		}
		
		public static int IPM_FIREBASE_TOKEN_TIME
		{
			get => PlayerPrefs.GetInt(nameof(IPM_FIREBASE_TOKEN_TIME), 0);
			set => PlayerPrefs.SetInt(nameof(IPM_FIREBASE_TOKEN_TIME), value);
		}
		
		public static long IPM_CREATED_TIMESTAMP
		{
			get => Convert.ToInt64(PlayerPrefs.GetString(nameof(IPM_CREATED_TIMESTAMP), "0"));
			set => PlayerPrefs.SetString(nameof(IPM_CREATED_TIMESTAMP), value.ToString());
		}
		
		public static string GetCountryCode()
		{
#if UNITY_EDITOR
			return "US";
#else
			return IPM_COUNTRY_CODE.ToUpper();
#endif
		}

		public static string GetDeviceType()
		{
			#if UNITY_IOS
				return "iOS";
			#else
				return "android";
			#endif
		}
		
		//------------ 2023-04 new IDs --------------
		public static string FIREBASE_ID
		{
			get => PlayerPrefs.GetString(nameof(FIREBASE_ID), "");
			set => PlayerPrefs.SetString(nameof(FIREBASE_ID), value);
		}
		public static string FIREBASE_APP_ID
		{
			get => PlayerPrefs.GetString(nameof(FIREBASE_APP_ID), "");
			set => PlayerPrefs.SetString(nameof(FIREBASE_APP_ID), value);
		}
		
		public static string ADJUST_ID
		{
			get
			{
#if UNITY_EDITOR
				return "editor_fake_adjust_id";
#endif
				return PlayerPrefs.GetString(nameof(ADJUST_ID), "");
			}
			set => PlayerPrefs.SetString(nameof(ADJUST_ID), value);
		}

		public static string ADJUST_ADID
		{
			get
			{
#if UNITY_IOS
				return "not_for_ios";
#endif
				return PlayerPrefs.GetString(nameof(ADJUST_ADID), "");
			}
			set => PlayerPrefs.SetString(nameof(ADJUST_ADID), value);
		}


		public static string ADJUST_IDFA
		{
			get => PlayerPrefs.GetString(nameof(ADJUST_IDFA), "");
			set => PlayerPrefs.SetString(nameof(ADJUST_IDFA), value);
		}
		
		public static string ADJUST_IDFV
		{
			get => PlayerPrefs.GetString(nameof(ADJUST_IDFV), "");
			set => PlayerPrefs.SetString(nameof(ADJUST_IDFV), value);
		}
		
		public static string ADJUST_GOOGLE_ADID
		{
			get => PlayerPrefs.GetString(nameof(ADJUST_GOOGLE_ADID), "");
			set => PlayerPrefs.SetString(nameof(ADJUST_GOOGLE_ADID), value);
		}
		
		public static string FIRST_OPEN_TIME
		{
			get
			{
				var value = PlayerPrefs.GetString(nameof(FIRST_OPEN_TIME), "");
				if (string.IsNullOrEmpty(value))
				{
					value = TimeUtil.GetCurrentTimeStamp().ToString();
					FIRST_OPEN_TIME = value;
				}
				return value;
			}
			set => PlayerPrefs.SetString(nameof(FIRST_OPEN_TIME), value);
		}
	}
}