using System;
#if UNITY_WEBGL && !UNITY_EDITOR
using System.Runtime.InteropServices;
#endif
using UnityEngine;
using AOT;

namespace Arkadium
{
	public interface IArkadiumPersistence
	{
		void GetLocalStorageItem(string key, Action<string> cb);
		void SetLocalStorageItem(string key, string value, Action<bool> cb);
		void RemoveLocalStorageItem(string key, Action<bool> cb);
		void GetCookie(string key, Action<string> cb);
		void GetRemoteStorageItem(string key, Action<string> cb);
		void SetRemoteStorageItem(string key, string value, Action<bool> cb);
		void RemoveRemoteStorageItem(string key, Action<bool> cb);
	}

	public class ArkadiumPersistence : IArkadiumPersistence
	{
	#if UNITY_WEBGL && !UNITY_EDITOR
		[DllImport("__Internal")]
		private static extern void _GetLocalStorageItem(string key, Action<string> cb);
		[DllImport("__Internal")]
		private static extern void _SetLocalStorageItem(string key, string value, Action<int> cb);
		[DllImport("__Internal")]
		private static extern void _RemoveLocalStorageItem(string key, Action<int> cb);
		[DllImport("__Internal")]
		private static extern void _GetCookie(string key, Action<string> cb);
		[DllImport("__Internal")]
		private static extern void _GetRemoteStorageItem(string key, Action<string> cb);
		[DllImport("__Internal")]
		private static extern void _SetRemoteStorageItem(string key, string value, Action<int> cb);
		[DllImport("__Internal")]
		private static extern void _RemoveRemoteStorageItem(string key, Action<int> cb);
	#else
		private void _GetLocalStorageItem(string key, Action<string> cb) { cb?.Invoke("lsItem"); }
		private void _SetLocalStorageItem(string key, string value, Action<int> cb) { cb?.Invoke(1); }
		private void _RemoveLocalStorageItem(string key, Action<int> cb) { cb?.Invoke(1); }
		private void _GetCookie(string key, Action<string> cb) { cb?.Invoke("cookie"); }
		private void _GetRemoteStorageItem(string key, Action<string> cb) { cb?.Invoke("rsItem"); }
		private void _SetRemoteStorageItem(string key, string value, Action<int> cb) { cb?.Invoke(1); }
		private void _RemoveRemoteStorageItem(string key, Action<int> cb) { cb?.Invoke(1); }
	#endif

		private static Action<string> _getLocalStorageItemCb;
		private static Action<bool> _setLocalStorageItemCb;
		private static Action<bool> _removeLocalStorageItemCb;
		private static Action<string> _getCookieCb;
		private static Action<string> _getRemoteStorageItemCb;
		private static Action<bool> _setRemoteStorageItemCb;
		private static Action<bool> _removeRemoteStorageItemCb;

		public void GetLocalStorageItem(string key, Action<string> cb)
		{
			_getLocalStorageItemCb = cb;
			_GetLocalStorageItem(key, GetLocalStorageItemCb);
		}
		public void SetLocalStorageItem(string key, string value, Action<bool> cb)
		{
			_setLocalStorageItemCb = cb;
			_SetLocalStorageItem(key, value, SetLocalStorageItemCb);
		}
		public void RemoveLocalStorageItem(string key, Action<bool> cb)
		{
			_removeLocalStorageItemCb = cb;
			_RemoveLocalStorageItem(key, RemoveLocalStorageItemCb);
		}
		public void GetCookie(string key, Action<string> cb)
		{
			_getCookieCb = cb;
			_GetCookie(key, GetCookieCb);
		}
		public void GetRemoteStorageItem(string key, Action<string> cb)
		{
			_getRemoteStorageItemCb = cb;
			_GetRemoteStorageItem(key, GetRemoteStorageItemCb);
		}
		public void SetRemoteStorageItem(string key, string value, Action<bool> cb)
		{
			_setRemoteStorageItemCb = cb;
			_SetRemoteStorageItem(key, value, SetRemoteStorageItemCb);
		}
		public void RemoveRemoteStorageItem(string key, Action<bool> cb)
		{
			_removeRemoteStorageItemCb = cb;
			_RemoveRemoteStorageItem(key, RemoveRemoteStorageItemCb);
		}

		[MonoPInvokeCallback(typeof(Action<string>))]
		private static void GetLocalStorageItemCb(string result) {
			ArkadiumSDK.Instance.Log($"get local storage returned {result}");
			_getLocalStorageItemCb?.Invoke(result);
			_getLocalStorageItemCb = null;
		}

		[MonoPInvokeCallback(typeof(Action<int>))]
		private static void SetLocalStorageItemCb(int result) {
			var success = result == 1;
			ArkadiumSDK.Instance.Log($"set local storage returned {success}");
			_setLocalStorageItemCb?.Invoke(success);
			_setLocalStorageItemCb = null;
		}

		[MonoPInvokeCallback(typeof(Action<int>))]
		private static void RemoveLocalStorageItemCb(int result) {
			var success = result == 1;
			ArkadiumSDK.Instance.Log($"remove local storage returned {success}");
			_removeLocalStorageItemCb?.Invoke(success);
			_removeLocalStorageItemCb = null;
		}

		[MonoPInvokeCallback(typeof(Action<string>))]
		private static void GetCookieCb(string result) {
			ArkadiumSDK.Instance.Log($"get cookie returned {result}");
			_getCookieCb?.Invoke(result);
			_getCookieCb = null;
		}

		[MonoPInvokeCallback(typeof(Action<string>))]
		private static void GetRemoteStorageItemCb(string result) {
			ArkadiumSDK.Instance.Log($"get remote storage returned {result}");
			_getRemoteStorageItemCb?.Invoke(result);
			_getRemoteStorageItemCb = null;
		}

		[MonoPInvokeCallback(typeof(Action<int>))]
		private static void SetRemoteStorageItemCb(int result) {
			var success = result == 1;
			ArkadiumSDK.Instance.Log($"set remote storage returned {success}");
			_setRemoteStorageItemCb?.Invoke(success);
			_setRemoteStorageItemCb = null;
		}

		[MonoPInvokeCallback(typeof(Action<int>))]
		private static void RemoveRemoteStorageItemCb(int result) {
			var success = result == 1;
			ArkadiumSDK.Instance.Log($"remove remote storage returned {success}");
			_removeRemoteStorageItemCb?.Invoke(success);
			_removeRemoteStorageItemCb = null;
		}
	}
}