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

namespace Arkadium
{
	public enum ArkadiumLifecycleEvent
	{
		PauseGame = 7,
		ResumeGame = 8
	}

	public interface IArkadiumLifecycle
	{
		void OnTestReady();
		void OnInteract();
		void OnGameStart();
		void OnGameEnd();
		void OnPauseReady();
		void OnGamePause();
		void OnGameResume();
		void OnChangeScore(int score);
		void OnGemsUpdate();
		void OnLevelStart(int level);
		void OnLevelEnd(int level);
		void RegisterEventCallback(ArkadiumLifecycleEvent eventId, Action cb);
	}

	public class ArkadiumLifecycle : IArkadiumLifecycle
	{
#if UNITY_WEBGL && !UNITY_EDITOR
		[DllImport("__Internal")]
		private static extern void _OnTestReady();
		[DllImport("__Internal")]
		private static extern void _OnInteract();
		[DllImport("__Internal")]
		private static extern void _OnGameStart();
		[DllImport("__Internal")]
		private static extern void _OnGameEnd();
		[DllImport("__Internal")]
		private static extern void _OnPauseReady();
		[DllImport("__Internal")]
		private static extern void _OnGamePause();
		[DllImport("__Internal")]
		private static extern void _OnGameResume();
		[DllImport("__Internal")]
		private static extern void _OnChangeScore(int score);
		[DllImport("__Internal")]
		private static extern void _OnGemsUpdate();
		[DllImport("__Internal")]
		private static extern void _OnLevelStart(int level);
		[DllImport("__Internal")]
		private static extern void _OnLevelEnd(int level);
		[DllImport("__Internal")]
		private static extern void _RegisterEventCallback(int eventId, Action<int> cb);
#else
		private void _OnTestReady() { }
		private void _OnInteract() { }
		private void _OnGameStart() { }
		private void _OnGameEnd() { }
		private void _OnPauseReady() { }
		private void _OnGamePause() { }
		private void _OnGameResume() { }
		private void _OnChangeScore(int score) { }
		private void _OnGemsUpdate() { }
		private void _OnLevelStart(int level) { }
		private void _OnLevelEnd(int level) { }
		private void _RegisterEventCallback(int eventId, Action<int> cb) { }
#endif

		public void OnTestReady()
		{
			_OnTestReady();
		}

		public void OnInteract()
		{
			_OnInteract();
		}

		public void OnGameStart()
		{
			_OnGameStart();
		}

		public void OnGameEnd()
		{
			_OnGameEnd();
		}

		public void OnPauseReady()
		{
			_OnPauseReady();
		}

		public void OnGamePause()
		{
			_OnGamePause();
		}

		public void OnGameResume()
		{
			_OnGameResume();
		}

		public void OnChangeScore(int score)
		{
			_OnChangeScore(score);
		}

		public void OnGemsUpdate()
		{
			_OnGemsUpdate();
		}

		public void OnLevelStart(int level)
		{
			_OnLevelStart(level);
		}

		public void OnLevelEnd(int level)
		{
			_OnLevelEnd(level);
		}

		private static Dictionary<int, Action> _eventCallbacks = new Dictionary<int, Action>();

		public void RegisterEventCallback(ArkadiumLifecycleEvent eventId, Action cb)
		{
			int eventIdInt = (int)eventId;
			if (!_eventCallbacks.ContainsKey(eventIdInt))
			{
				_eventCallbacks.Add(eventIdInt, cb);
			}
			else
			{
				_eventCallbacks[eventIdInt] = cb;
			}
			_RegisterEventCallback(eventIdInt, RegisterEventCallbackCb);
		}

		[MonoPInvokeCallback(typeof(Action<int>))]
		private static void RegisterEventCallbackCb(int eventId)
		{
			ArkadiumSDK.Instance.Log($"[Lifecycle] calling event callback for eventId {eventId}");
			_eventCallbacks[eventId]?.Invoke();
		}
	}
}