#if UNITY_ANDROID

using System;
using LitJson;
using UnityEngine;

namespace EngineSdkConverter.Unity.SDK
{

    public class UnityCallback : AndroidJavaProxy
    {
        public UnityCallback() : base("com.tuyoo.sdk.sdk_inter_layer.interfaces.LocalDeliverListener") { }

        public void notifyDeliver(string param, AndroidJavaObject callback)
        {
            Debug.Log($"Event received: {param}");
            Action onConfirm = () =>
            {
                NativeCallBack.Enqueue(() =>
                {
                    callback.Call("onConfirm");
                });
            };

            Action<string, string> onCancel = (code, errorInfo) =>
            {
                NativeCallBack.Enqueue(() =>
                {
                    callback.Call("onCancel", code, errorInfo);
                });
            };

            NativeCallBack.setDeliverResultCallback(param, onConfirm, onCancel);
        }
    }

    public class AndroidInterface : ISDKInterface
    {

        public override void Init()
        {

        }

        public override void Login(Action<string> callback)
        {

        }

        public override void InitSDK(Action<string> callback)
        {
            InitEventBuilder.InitEvent initEvent = new InitEventBuilder.InitEvent();
            InitSDK(initEvent, callback);
        }

        public override void InitSDK(InitEventBuilder.InitEvent initEvent, Action<string> callback)
        {
            NativeCallBack.initResultCallback = callback;
            NativeCallBack.autoLogoutResultCallback = initEvent.autoLogoutCallback;
            initEvent.autoLogoutCallback = null;
            string initEventInfo = JsonMapper.ToJson(initEvent);
            Debug.Log($"InitSDK called with event: {initEventInfo}");//AutoLogoutResult
            UnityPlayerUtils.invokeWithAll("init", initEventInfo, "InitResult");
        }

        public override void UpdateServerUrl(string serverUrl)
        {
            UnityPlayerUtils.invokeWithParams("updateServerUrl", serverUrl);
        }

        public override void UpdateServerUrlList(string[] serverUrlList)
        {
            string serverUrlListJson = JsonMapper.ToJson(serverUrlList);
            UnityPlayerUtils.invokeWithParams("updateServerUrlList", serverUrlListJson);
        }

        public override void SilentLogin(Action<string> callback)
        {
            NativeCallBack.silentLoginResultCallback = callback;
            UnityPlayerUtils.invokeWithCallback("silentLogin", "SilentLoginResult");
        }

        public override void SilentLoginWithParam(LoginEventBuilder.LoginEvent loginEvent, Action<string> callback)
        {
            NativeCallBack.silentLoginResultCallback = callback;
            string loginEventInfo = JsonMapper.ToJson(loginEvent);
            UnityPlayerUtils.invokeWithAll("silentLoginWithParam", loginEventInfo, "SilentLoginResult");
        }

        public override void LoginByType(LoginEventBuilder.LoginEvent loginEvent, Action<string> callback)
        {
            NativeCallBack.loginResultCallback = callback;
            if (loginEvent.loginType == "auto")
            {
                UnityPlayerUtils.invokeWithCallback("login", "LoginResult");
            }
            else if (loginEvent.loginType == "uidPwd" || loginEvent.loginType == SDKType.EMAIL_CODE || loginEvent.loginType == SDKType.EMAIL_PWD)
            {
                string loginEventInfo = JsonMapper.ToJson(loginEvent);
                Debug.Log($"LoginByType called with event: {loginEventInfo}");
                UnityPlayerUtils.invokeWithTwoParamOneCallback("loginByTypeWithExtra", loginEvent.loginType, loginEventInfo, "LoginResult");
            }
            else
            {
                UnityPlayerUtils.invokeWithAll("loginByType", loginEvent.loginType, "LoginResult");
            }
        }

        public override void SendCode(LoginEventBuilder.LoginEvent loginEvent, Action<string> callback)
        {
            NativeCallBack.sendCodeResultCallback = callback;
            string loginEventInfo = JsonMapper.ToJson(loginEvent);
            UnityPlayerUtils.invokeWithAll("sendCode", loginEventInfo, "SendCodeResult");
        }

        public override void Charge(PayEventBuilder.PayEvent payEvent, Action<string> callback)
        {
            NativeCallBack.chargeResultCallback = callback;
            string payEventInfo = JsonMapper.ToJson(payEvent);
            UnityPlayerUtils.invokeWithTwoParams("charge", payEventInfo, "ChargeResult");
        }

        public override void Pay(PayEventBuilder.PayEvent payEvent, Action<string> callback)
        {
            NativeCallBack.payResultCallback = callback;
            if (payEvent.chargeService.Equals("auto"))
            {
                payEvent.chargeService = "";
            }
            string payEventInfo = JsonMapper.ToJson(payEvent);
            UnityPlayerUtils.invokeWithAll("pay", payEventInfo, "PayResult");
        }

        public override void GetLocalProductInfo(Action<string> callback)
        {
            NativeCallBack.getLocalProductInfoCallback = callback;
            UnityPlayerUtils.invokeWithCallback("getSkuDetailList", "GetLocalProductInfoResult");
        }

        public override void SetPushResultHandler(Action<string> onReceive, Action<string> onClick)
        {
            NativeCallBack.onPushResultReceiveCallback = onReceive;
            NativeCallBack.onPushResultClickCallback = onClick;
            UnityPlayerUtils.invokeWithTwoCallback("setMessageListener", "onPushResultReceive", "onPushResultClick");
        }

        public override void Logout(Action<string> callback)
        {
            NativeCallBack.logoutResultCallback = callback;
            UnityPlayerUtils.invokeWithCallback("logout", "LogoutResult");
        }

        public override void LogoutChannel(LoginEventBuilder.LoginEvent logoutEvent, Action<string> callback)
        {
            NativeCallBack.logoutChannelResultCallback = callback;
            UnityPlayerUtils.invokeWithParams("clearChannelLoginState", logoutEvent.loginType);
        }

        public override void ExitGame(Action<string> callback)
        {
            NativeCallBack.exitGameResultCallback = callback;
            UnityPlayerUtils.invokeWithCallback("exitGame", "ExitGameResult");
        }

        public override void AppsFlyerEventReport(ReportEventBuilder.ReportEvent reportEvent)
        {
            UnityPlayerUtils.invokeWithTwoParams("appsFlyerEventReport", reportEvent.eventName, JsonMapper.ToJson(reportEvent.reportEvent));
        }

        public override void GetAppsFlyerDeviceId(Action<string> callback)
        {
            NativeCallBack.getAFDeviceIdCallback = callback;
            UnityPlayerUtils.invokeWithCallback("getAppsFlyerDeviceId", "GetAFDeviceId");
        }

        public override void SetAppsFlyerCommonParam(ReportEventBuilder.ReportEvent reportEvent)
        {
            string reportEventInfo = JsonMapper.ToJson(reportEvent.reportEvent);
            UnityPlayerUtils.invokeWithParams("setAppsFlyerCommonParam", reportEventInfo);
        }

        public override void SetFirebaseUserProperty(ReportEventBuilder.ReportEvent reportEvent)
        {
            string reportEventInfo = JsonMapper.ToJson(reportEvent.reportEvent);
            UnityPlayerUtils.invokeWithParams("setFirebaseUserProperty", reportEventInfo);
        }

        public override void SetFirebaseCommonParam(ReportEventBuilder.ReportEvent reportEvent)
        {
            string reportEventInfo = JsonMapper.ToJson(reportEvent.reportEvent);
            UnityPlayerUtils.invokeWithParams("setFirebaseCommonParam", reportEventInfo);
        }

        public override void FirebaseEventReport(ReportEventBuilder.ReportEvent reportEvent)
        {
            string reportEventInfo = JsonMapper.ToJson(reportEvent.reportEvent);
            UnityPlayerUtils.invokeWithTwoParams("firebaseEventReport", reportEvent.eventName, reportEventInfo);
        }

        public override void Check(BindEventBuilder.BindEvent bindEvent, Action<string> callback)
        {
            NativeCallBack.Put("Check", callback);
            if (bindEvent.loginType.Equals(SDKType.EMAIL_CODE))
            {
                string bindEventInfo = JsonMapper.ToJson(bindEvent);
                UnityPlayerUtils.invokeWithTwoParamOneCallback("checkWithExtra", bindEvent.loginType, bindEventInfo, "Check");
            }
            else
            {
                UnityPlayerUtils.invokeWithTwoCallback("check", bindEvent.loginType, "Check");
            }
        }

        public override void Bind(BindEventBuilder.BindEvent bindEvent, Action<string> callback)
        {
            NativeCallBack.Put("Bind", callback);
            if (bindEvent.loginType.Equals(SDKType.EMAIL_CODE))
            {
                string bindEventInfo = JsonMapper.ToJson(bindEvent);
                UnityPlayerUtils.invokeWithTwoParamOneCallback("bindWithExtra", bindEvent.loginType, bindEventInfo, "Bind");
            }
            else
            {
                UnityPlayerUtils.invokeWithTwoCallback("bind", bindEvent.loginType, "Bind");
            }
        }

        public override void CanBindList(Action<string> callback)
        {
            NativeCallBack.canBindListResultCallback = callback;
            UnityPlayerUtils.invokeWithCallback("canBindList", "CanBindListResult");
        }

        public override void AlreadyBindList(Action<string> callback)
        {
            NativeCallBack.alreadyBindListResultCallback = callback;
            UnityPlayerUtils.invokeWithCallback("alreadyBindList", "AlreadyBindListResult");
        }

        public override void GetBindUserList(BindEventBuilder.BindEvent bindEvent, Action<string> callback)
        {
            NativeCallBack.userBindListResultCallback = callback;
            UnityPlayerUtils.invokeWithAll("userBindList", bindEvent.phoneNumber, "UserBindListResult");
        }

        public override void GAProfileTrack(ReportEventBuilder.ReportEvent reportEvent)
        {
            string reportEventInfo = JsonMapper.ToJson(reportEvent);
            UnityPlayerUtils.invokeWithParams("gaProfileTrack", reportEventInfo);
        }

        public override void GAEventTrack(ReportEventBuilder.ReportEvent reportEvent)
        {

            string reportEventInfo = JsonMapper.ToJson(reportEvent.reportEvent);
            UnityPlayerUtils.invokeWithThreeParams("gaEventTrack", reportEvent.typeName, reportEvent.eventName, reportEventInfo);
        }

        public override void SetGACommonParam(ReportEventBuilder.ReportEvent reportEvent)
        {
            string reportEventInfo = JsonMapper.ToJson(reportEvent.reportEvent);
            UnityPlayerUtils.invokeWithParams("setGACommonParam", reportEventInfo);
        }

        public override void SetLocalDeliverListener(Action<string, Action, Action<string, string>> callback)
        {
            NativeCallBack.setDeliverResultCallback = callback;
            UnityCallback unityCallback = new UnityCallback();
            UnityPlayerUtils.invokeWithJavaObject("setLocalDeliverListener", unityCallback);
        }

        public override void RequestNotificationPermission()
        {
            UnityPlayerUtils.invokeWithNone("requestNotificationPermission");
        }

        public override void SetCertificationListener(Action<string> callback)
        {
            CertificationInfoChangedCallbackType certificationInfoChangedCallbackType = new CertificationInfoChangedCallbackType();
            certificationInfoChangedCallbackType.callback = callback;
            NativeCallBack.callbacks["setCertificationListener"] = certificationInfoChangedCallbackType;
            UnityPlayerUtils.invokeWithJavaObject("setCertificationListener", certificationInfoChangedCallbackType);
        }

        public override void Certificate(CertificationEventBuilder.CertificationEvent certificationEvent, Action<string> callback)
        {
            CertificationSetCallbackType certificationSetCallbackType = new CertificationSetCallbackType();
            certificationSetCallbackType.callback = callback;
            NativeCallBack.callbacks["certificate"] = certificationSetCallbackType;
            string certificationEventInfo = JsonMapper.ToJson(certificationEvent);
            UnityPlayerUtils.invokeWithJavaObject("certificate", certificationEventInfo, certificationSetCallbackType);
        }

        public override string GetCertificationInfo()
        {
            return UnityPlayerUtils.invokeWithNoneReturn("getCertificationInfo");
        }

        public override void ReCertificate(CertificationEventBuilder.CertificationEvent certificationEvent, Action<string> callback)
        {
            ReCertificationSetCallbackType reCertificationSetCallbackType = new ReCertificationSetCallbackType();
            reCertificationSetCallbackType.callback = callback;
            NativeCallBack.callbacks["reCertificate"] = reCertificationSetCallbackType;
            string certificationEventInfo = JsonMapper.ToJson(certificationEvent);
            UnityPlayerUtils.invokeWithJavaObject("reCertificate", certificationEventInfo, reCertificationSetCallbackType);
        }

        public override void RefreshCertification()
        {
            UnityPlayerUtils.invokeWithNone("refreshCertificate");
        }

        public override bool IsCertificationEnable()
        {
            return "true".Equals(UnityPlayerUtils.invokeWithNoneReturn("isCertificationEnable"));
        }

        public override void SetServerLanguage(string serverLanguage, Action<string> callback)
        {
            string action = "SetServerLanguageResult";
            NativeCallBack.callbacks[action] = callback;
            UnityPlayerUtils.invokeWithAll("setServerLanguage", serverLanguage, action);
        }

        public override void GetDeviceId(Action<string> callback)
        {
            NativeCallBack.getDeviceIdResultCallback = callback;
            UnityPlayerUtils.invokeWithCallback("getDeviceInfo", "GetDeviceIdResult");
        }

        public override void LiveDetect(YiDunEventBuilder.YiDunEvent yiDunEvent, Action<string> callback)
        {
            NativeCallBack.liveDetectResultCallback = callback;
            string yiDunEventInfo = JsonMapper.ToJson(yiDunEvent);
            UnityPlayerUtils.invokeWithAll("liveDetect", yiDunEventInfo, "LiveDetectResult");
        }

        public override void RequestWXAuthorize(Action<string> callback)
        {
            NativeCallBack.requestWXAuthorizeResultCallback = callback;
            UnityPlayerUtils.invokeWithCallback("requestWXAuthorize", "RequestWXAuthorizeResult");
        }

        public override void GetWXAuthInfo(Action<string> callback)
        {
            NativeCallBack.getWXAuthInfoResultCallback = callback;
            UnityPlayerUtils.invokeWithCallback("getWXAuthInfo", "GetWXAuthInfoResult");
        }

        public override void GetYiDunCaptcha(YiDunEventBuilder.YiDunEvent yiDunEvent, Action<string> callback)
        {
            NativeCallBack.getYiDunCaptchaResultCallback = callback;
            string yiDunEventInfo = JsonMapper.ToJson(yiDunEvent);
            UnityPlayerUtils.invokeWithAll("getYiDunCaptcha", yiDunEventInfo, "GetYiDunCaptchaResult");
        }

        public override void GetAPIVersion(Action<string> callback)
        {
            NativeCallBack.getAPIVersionResultCallback = callback;
            UnityPlayerUtils.invokeWithCallback("getAPIVersion", "GetAPIVersionResult");
        }

        public override void HasGeneratedGuest(Action<string> callback)
        {
            NativeCallBack.hasGeneratedGuestResultCallback = callback;
            UnityPlayerUtils.invokeWithCallback("hasGeneratedGuest", "HasGeneratedGuestResult");
        }

        public override void SetPrivacy(YiDunEventBuilder.YiDunEvent yiDunEvent, Action<string> callback)
        {
            NativeCallBack.setPrivacyResultCallback = callback;
            string yiDunEventInfo = JsonMapper.ToJson(yiDunEvent);
            UnityPlayerUtils.invokeWithAll("setPrivacy", yiDunEventInfo, "SetPrivacyResult");
        }

        public override void Share(ShareEventBuilder.ShareEvent shareEvent, Action<string> callback)
        {
            NativeCallBack.shareResultCallback = callback;
            string shareEventInfo = JsonMapper.ToJson(shareEvent);
            UnityPlayerUtils.invokeWithAll("share", shareEventInfo, "ShareResult");
        }

        public override void ResetUserInfo(DYTrackEventBuilder.DYTrackEvent dYTrackEvent, Action<string> callback)
        {
            NativeCallBack.resetUserInfoResultCallback = callback;
            string dYTrackEventInfo = JsonMapper.ToJson(dYTrackEvent);
            UnityPlayerUtils.invokeWithAll("resetUserInfo", dYTrackEventInfo, "ResetUserInfoResult");
        }

        public override void GetUserInfo(DYTrackEventBuilder.DYTrackEvent dYTrackEvent, Action<string> callback)
        {
            NativeCallBack.getUserInfoResultCallback = callback;
            string dYTrackEventInfo = JsonMapper.ToJson(dYTrackEvent);
            UnityPlayerUtils.invokeWithAll("getUserInfo", dYTrackEventInfo, "GetUserInfoResult");
        }

        public override void GetLiveInfo(Action<string> callback)
        {
            NativeCallBack.getLiveInfoResultCallback = callback;
            UnityPlayerUtils.invokeWithCallback("getLiveInfo", "GetLiveInfoResult");
        }

        public override void SetDefaultShareInfo(ShareEventBuilder.ShareEvent shareEvent, Action<string> callback)
        {
            throw new NotImplementedException();
        }

        public override void SetConfig(ConfigEventBuilder.ConfigEvent configEvent, Action<string> callback)
        {
            NativeCallBack.Put("SetConfig", callback);
            string configEventJson = JsonMapper.ToJson(configEvent);
            UnityPlayerUtils.invokeWithTwoCallback("setConfig", configEventJson, "SetConfig");
        }

        public override void IsWxInstalled(Action<string> callback)
        {
            NativeCallBack.Put("IsWxInstalled", callback);
            UnityPlayerUtils.invokeWithCallback("iswInstalled", "IsWxInstalled");
        }

        public override void GetShareInfoFromMarketService(Action<string> callback)
        {
            throw new NotImplementedException();
        }

        public override void GetAdInfoFromMarketService(Action<string> callback, Action<string> newCallback)
        {
            throw new NotImplementedException();
        }

        public override void TxAdSDKReport(TxAdSDKReportEventBuilder.TxAdSDKReportEvent txAdSDKReportEvent)
        {
            throw new NotImplementedException();
        }

        public override void SetWxUserInfo(SetWxUserInfoEventBuilder.SetWxUserInfoEvent setWxUserInfoEvent, Action<string> callback)
        {
            throw new NotImplementedException();
        }

        public override void ShowAIHelp(AIHelpShowTypeBuilder.AIHelpShowType aihelpShowType)
        {
            string aihelpShowTypeInfo = JsonMapper.ToJson(aihelpShowType);
            UnityPlayerUtils.invokeWithParams("showAIHelp", aihelpShowTypeInfo);
        }

        public override void SetLoginUserInfo(AIHelpSetLoginUserInfoTypeBuilder.AIHelpSetLoginUserInfoType aihelpSetLoginUserInfoType)
        {
            string aihelpSetLoginUserInfoTypeInfo = JsonMapper.ToJson(aihelpSetLoginUserInfoType);
            UnityPlayerUtils.invokeWithParams("setLoginUserInfo", aihelpSetLoginUserInfoTypeInfo);
        }

        public override void LogoutAIHelp()
        {
            UnityPlayerUtils.invokeWithNone("logoutAIHelp");
        }

        public override void FetchAIHelpUnreadMessageCount()
        {
            UnityPlayerUtils.invokeWithNone("fetchAIHelpUnreadMessageCount");
        }

        public override void RegisterAIHelpEventListener(AiHelpEventType aiHelpEventType, Action<string, object> callback)
        {
            AIHelpCallback aiHelpCallback = new AIHelpCallback();
            aiHelpCallback.onAsyncEventReceivedCallback = callback;
            NativeCallBack.callbacks["registerAiHelpAsyncEventListener"] = aiHelpCallback;
            UnityPlayerUtils.invokeWithJavaObject("registerAiHelpAsyncEventListener", aiHelpEventType.ToString(), aiHelpCallback);
        }

        public override void SetFirebaseCrashCustomKey(FirebaseCrashCustomKeyBuilder.FirebaseCrashCustomKeyType firebaseCrashCustomKey)
        {
            string firebaseCrashCustomKeyInfo = JsonMapper.ToJson(firebaseCrashCustomKey);
            UnityPlayerUtils.invokeWithParams("setFirebaseCrashCustomKey", firebaseCrashCustomKeyInfo);
        }

        public override void ReportFirebaseCrashLog(FirebaseCrashLogBuilder.FirebaseCrashLogType firebaseCrashLog)
        {
            string firebaseCrashLogInfo = JsonMapper.ToJson(firebaseCrashLog);
            UnityPlayerUtils.invokeWithParams("reportFirebaseCrashLog", firebaseCrashLogInfo);
        }

        public override void SetFirebaseCrashUserIdentifier(FirebaseCrashUserIdentifierBuilder.FirebaseCrashUserIdentifierType firebaseCrashUserIdentifier)
        {
            string firebaseCrashUserIdentifierInfo = JsonMapper.ToJson(firebaseCrashUserIdentifier);
            UnityPlayerUtils.invokeWithParams("setFirebaseCrashUserIdentifier", firebaseCrashUserIdentifierInfo);
        }

        public override void ReportFirebaseCrashException(FirebaseCrashExceptionTypeBuilder.FirebaseCrashExceptionType firebaseCrashException)
        {
            string firebaseCrashExceptionInfo = JsonMapper.ToJson(firebaseCrashException);
            UnityPlayerUtils.invokeWithParams("reportFirebaseCrashException", firebaseCrashExceptionInfo);
        }

        public override void ShowCollectUserInfo()
        {
            UnityPlayerUtils.invokeWithNone("showCollectUserInfo");
        }

        public override void ShowCollectThirdInfo()
        {
            UnityPlayerUtils.invokeWithNone("showCollectThirdInfo");
        }

        public override string GetCustomKeyValue(string key, string defaultValue)
        {
            return UnityPlayerUtils.invokeWithTwoReturn("getCustomKeyValue", key, defaultValue);
        }

        public override void UpdatePassword(LoginEventBuilder.LoginEvent loginEvent, Action<string> callback)
        {
            string action = "updatePassword";
            NativeCallBack.Put(action, callback);
            string loginEventInfo = JsonMapper.ToJson(loginEvent);
            UnityPlayerUtils.invokeWithAll(action, loginEventInfo, action);
        }

        public override void UnBind(BindEventBuilder.BindEvent bindEvent, Action<string> callback)
        {
            string action = "unBind";
            NativeCallBack.callbacks[action] = callback;
            string bindEventInfo = JsonMapper.ToJson(bindEvent);
            UnityPlayerUtils.invokeWithAll(action, bindEventInfo, action);
        }


        public override void GetStoreRegion(Action<string> callback)
        {
            string action = "getStoreRegion";
            NativeCallBack.callbacks[action] = callback;
            UnityPlayerUtils.invokeWithCallback(action, action);
        }
    }
}

#endif