#if UNITY_WEBGL
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;
using Seayoo.LitJson;

namespace Combo.Platform
{
    public class NativeWebGL : MonoBehaviour
    {
        private static Action<Result<SetupResult>> setupFinishedAction;
        private static Action<Result<LoginResult>> loginFinishedAction;
        private static Action<Result<PurchaseResult>> purchaseFinishedAction;
        private static Action<Result<PreloadAdResult>> preloadAdFinishedAction;
        private static Action<Result<ShowAdResult>> showAdFinishedAction;

        [DllImport("__Internal")]
        private static extern void freeMemory(IntPtr pointer);

        [DllImport("__Internal")]
        private static extern void setup(string strJsonData);
        public static void Setup(SetupOptions opts, Action<Result<SetupResult>> callback)
        {
            GameObject obj = GameObject.Find("ComboSDKWebGL");

            if (obj == null)
            {
                obj = new GameObject("ComboSDKWebGL", typeof(NativeWebGL));
                DontDestroyOnLoad(obj);
            }
            setupFinishedAction = callback;
            setup(opts.ToJson());
        }

        [DllImport("__Internal")]
        private static extern void login();
        public static void Login(Action<Result<LoginResult>> callback)
        {
            loginFinishedAction = callback;
            login();
        }

        [DllImport("__Internal")]
        private static extern IntPtr getParameters();
        public static Dictionary<string, string> GetParameters()
        {
            var resultPtr = getParameters();
            string jsonString = Marshal.PtrToStringAuto(resultPtr);
            var parameters = JsonMapper.ToObject<Dictionary<string, string>>(jsonString);
            freeMemory(resultPtr);
            return parameters;
        }

        [DllImport("__Internal")]
        public static extern void purchase(string strJsonData);
        public static void Purchase(PurchaseOptions opts, Action<Result<PurchaseResult>> callback)
        {
            purchaseFinishedAction = callback;
            purchase(opts.ToJson());
        }

        [DllImport("__Internal")]
        public static extern bool isFeatureAvailable(int feature);
        public static bool IsFeatureAvailable(Feature feature)
        {
            return isFeatureAvailable((int)feature);
        }

        [DllImport("__Internal")]
        public static extern void contactSupport();
        public static void ContactSupport()
        {
            contactSupport();
        }

        [DllImport("__Internal")]
        public static extern IntPtr getLoginInfo();
        public static LoginInfo GetLoginInfo()
        {
            var resultPtr = getLoginInfo();
            string jsonString = Marshal.PtrToStringAuto(resultPtr);
            var info = JsonMapper.ToObject<LoginInfo>(jsonString);
            freeMemory(resultPtr);
            return info;
        }

        [DllImport("__Internal")]
        public static extern IntPtr getUserId();
        public static string GetUserId()
        {
            var resultPtr = getUserId();
            string jsonString = Marshal.PtrToStringAuto(resultPtr);
            freeMemory(resultPtr);
            return jsonString;
        }

        [DllImport("__Internal")]
        public static extern IntPtr getDistro();
        public static string GetDistro()
        {
            var resultPtr = getDistro();
            string jsonString = Marshal.PtrToStringAuto(resultPtr);
            freeMemory(resultPtr);
            return jsonString;
        }

        [DllImport("__Internal")]
        public static extern IntPtr getVersion();
        public static string GetVersion()
        {
            var resultPtr = getVersion();
            string jsonString = Marshal.PtrToStringAuto(resultPtr);
            freeMemory(resultPtr);
            return jsonString;
        }

        [DllImport("__Internal")]
        public static extern IntPtr getDeviceId();
        public static string GetDeviceId()
        {
            var resultPtr = getDeviceId();
            string jsonString = Marshal.PtrToStringAuto(resultPtr);
            freeMemory(resultPtr);
            return jsonString;
        }

        [DllImport("__Internal")]
        private static extern void reportCreateRole(string strJsonData);
        public static void ReportCreateRole(RoleInfo roleInfo)
        {
            reportCreateRole(roleInfo.ToJson());
        }

        [DllImport("__Internal")]
        private static extern void preloadAd(string strJsonData);
        public static void PreloadAd(PreloadAdOptions opts, Action<Result<PreloadAdResult>> callback)
        {
            preloadAdFinishedAction = callback;
            preloadAd(opts.ToJson());
        }   

        [DllImport("__Internal")]
        private static extern void showAd(string strJsonData);
        public static void ShowAd(ShowAdOptions opts, Action<Result<ShowAdResult>> callback)
        {
            showAdFinishedAction = callback;
            showAd(opts.ToJson());
        }

        public void _SetupSucceed(string msg)
        {
            var result = Result<SetupResult>.CreateSuccessFromJson(msg);
            setupFinishedAction?.Invoke(result);
        }

        public void _SetupFailed(string msg)
        {
            var result = Result<SetupResult>.CreateFailFromJson(msg);
            setupFinishedAction?.Invoke(result);
        }

        public void _LoginSucceed(string msg)
        {
            var result = Result<LoginResult>.CreateSuccessFromJson(msg);
            loginFinishedAction?.Invoke(result);
        }

        public void _LoginFailed(string msg)
        {
            var result = Result<LoginResult>.CreateFailFromJson(msg);
            loginFinishedAction?.Invoke(result);
        }

        public void _PurchaseSucceed(string msg)
        {
            var result = Result<PurchaseResult>.CreateSuccessFromJson(msg);
            purchaseFinishedAction?.Invoke(result);
        }

        public void _PurchaseFailed(string msg)
        {
            var result = Result<PurchaseResult>.CreateFailFromJson(msg);
            purchaseFinishedAction?.Invoke(result);
        }

        public void _PreloadAdSucceed(string msg)
        {
            var result = Result<PreloadAdResult>.CreateSuccessFromJson(msg);
            preloadAdFinishedAction?.Invoke(result);
        }

        public void _PreloadAdFailed(string msg)
        {
            var result = Result<PreloadAdResult>.CreateFailFromJson(msg);
            preloadAdFinishedAction?.Invoke(result);
        }

        public void _ShowAdSucceed(string msg)
        {
            var result = Result<ShowAdResult>.CreateSuccessFromJson(msg);
            showAdFinishedAction?.Invoke(result);
        }

        public void _ShowAdFailed(string msg)
        {
            var result = Result<ShowAdResult>.CreateFailFromJson(msg);
            showAdFinishedAction?.Invoke(result);
        }
    }
}
#endif