#if UNITY_OPENHARMONY
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Sentry;
using ThinkingData.Analytics;
using UnityEngine;

namespace Combo.Platform
{
    public class NativeOpenHarmony : MonoBehaviour
    {
        private static readonly OpenHarmonyJSObject openHarmonyJSObject = new OpenHarmonyJSObject("ComboSDKOpenHarmonyWrapper");
        private static Action<Result<SetupResult>> setupFinishedAction;
        private static Action<Result<LoginResult>> loginFinishedAction;
        private static Action<Result<LogoutResult>> logoutFinishedAction;
        private static Action<Result<QuitResult>> quitFinishedAction;
        private static Action<Result<KickOutResult>> kickOutFinishedAction;
        private static Action<Result<PurchaseResult>> purchaseFinishedAction;
        private static Action<Result<UpdateGameResult>> updateGameFinishedAction;
        private static Action<Result<DownloadUrlResult>> downloadUrlFinishedAction;
        private static Action<Result<OpenShortLinkResult>> openShortLinkFinishedAction;
        private static Action<Result<CheckAnnouncementsResult>> checkAnnouncementsFinishedAction;
        private static Action<Result<OpenAnnouncementsResult>> openAnnouncementsFinishedAction;
        private static Action<Result<ComplainResult>> complainFinishedAction;
        private static Action<Result<RedeemGiftCodeResult>> redeemGiftCodeFinishedAction;
        private static Action<Result<PreloadAdResult>> preloadAdFinishedAction;
        private static Action<Result<ShowAdResult>> showAdFinishedAction;
        private static Action<Result<ShareResult>> shareFinishedAction;
        private static Action<string> deepLinkingReceivedAction;

        [RuntimeInitializeOnLoadMethod]
        private static void GameOnLoad()
        {
            GameObject obj = GameObject.Find("ComboSDKOpenHarmony");
            if (obj == null)
            {
                obj = new GameObject("ComboSDKOpenHarmony", typeof(NativeOpenHarmony));
                DontDestroyOnLoad(obj);
            }
        }
        public static void Setup(SetupOptions options, Action<Result<SetupResult>> callback)
        {
            setupFinishedAction = callback;
            openHarmonyJSObject.Call("setup", options.ToJson());
        }

        public static Dictionary<string, string> GetParameters()
        {
            return JsonConvert.DeserializeObject<Dictionary<string, string>>(openHarmonyJSObject.Call<string>("getParameters"));
        }

        public static void Login(Action<Result<LoginResult>> callback)
        {
            loginFinishedAction = callback;
            openHarmonyJSObject.Call("login");
        }

        public static void Logout(Action<Result<LogoutResult>> callback)
        {
            logoutFinishedAction = callback;
            openHarmonyJSObject.Call("logout");
        }

        public static void Quit(Action<Result<QuitResult>> callback)
        {
            quitFinishedAction = callback;
            openHarmonyJSObject.Call("quit");
        }

        public static LoginInfo GetLoginInfo()
        {
            var result = openHarmonyJSObject.Call<string>("getLoginInfo");
            if (result == null)
                return null;
            return Result<LoginInfo>.CreateSuccessFromJson(result).Data;
        }

        public static void OnKickOut(Action<Result<KickOutResult>> callback)
        {
            kickOutFinishedAction = callback;
            openHarmonyJSObject.Call("onKickOut");
        }

        public static void Purchase(PurchaseOptions options, Action<Result<PurchaseResult>> callback)
        {
            purchaseFinishedAction = callback;
            openHarmonyJSObject.Call("purchase", options.ToJson());
        }

        public static void ReportCreateRole(RoleInfo options)
        {
            openHarmonyJSObject.Call("reportCreateRole", options.ToJson());
        }

        public static void ReportEnterGame(RoleInfo options)
        {
            openHarmonyJSObject.Call("reportEnterGame", options.ToJson());
        }

        public static void OpenGameUrl(GameUrl gameUrl)
        {
            openHarmonyJSObject.Call("openGameUrl", (int)gameUrl);
        }

        public static void OpenShortLink(string shortLink, Dictionary<string, string> gameData, Action<Result<OpenShortLinkResult>> callback)
        {
            openShortLinkFinishedAction = callback;
            openHarmonyJSObject.Call("openShortLink", shortLink, JsonConvert.SerializeObject(gameData));
        }

        public static void CheckAnnouncements(CheckAnnouncementsOptions options, Action<Result<CheckAnnouncementsResult>> callback)
        {
            checkAnnouncementsFinishedAction = callback;
            openHarmonyJSObject.Call("checkAnnouncements", options.ToJson());
        }

        public static void OpenAnnouncements(OpenAnnouncementsOptions options, Action<Result<OpenAnnouncementsResult>> callback)
        {
            openAnnouncementsFinishedAction = callback;
            openHarmonyJSObject.Call("openAnnouncements", options.ToJson());
        }

        public static void Complain(ComplainOptions options, Action<Result<ComplainResult>> callback)
        {
            complainFinishedAction = callback;
            openHarmonyJSObject.Call("complain", options.ToJson());
        }

        public static void RedeemGiftCode(RedeemGiftCodeOptions options, Action<Result<RedeemGiftCodeResult>> callback)
        {
            redeemGiftCodeFinishedAction = callback;
            openHarmonyJSObject.Call("redeemGiftCode", options.ToJson());
        }

        public static string GetUserId()
        {
            return openHarmonyJSObject.Call<string>("getUserId");
        }

        public static string GetDistro()
        {
            return openHarmonyJSObject.Call<string>("getDistro");
        }

        public static string GetDeviceId()
        {
            return openHarmonyJSObject.Call<string>("getDeviceId");
        }

        public static string GetVersion()
        {
            return openHarmonyJSObject.Call<string>("getVersion");
        }

        public static bool IsFeatureAvailable(Feature feature)
        {
            return openHarmonyJSObject.Call<bool>("isFeatureAvailable", (int)feature);
        }

        public static void UpdateGame(UpdateGameOptions opts, Action<Result<UpdateGameResult>> callback)
        {
            updateGameFinishedAction = callback;
            openHarmonyJSObject.Call("updateGame", opts.ToJson());
        }

        public static void GetDownloadUrl(Action<Result<DownloadUrlResult>> callback)
        {
            downloadUrlFinishedAction = callback;
            openHarmonyJSObject.Call("getDownloadUrl");
        }

        public static void ContactSupport()
        {
            openHarmonyJSObject.Call("contactSupport");
        }

        public static void PreloadAd(PreloadAdOptions opts, Action<Result<PreloadAdResult>> callback)
        {
            preloadAdFinishedAction = callback;
            openHarmonyJSObject.Call("preloadAd", opts.ToJson());
        }

        public static void ShowAd(ShowAdOptions opts, Action<Result<ShowAdResult>> callback)
        {
            showAdFinishedAction = callback;
            openHarmonyJSObject.Call("showAd", opts.ToJson());
        }

        public static ShareTarget[] GetAvailableShareTargets()
        {
            return JsonConvert.DeserializeObject<ShareTarget[]>(openHarmonyJSObject.Call<string>("getAvailableShareTargets"));
        }

        public static void Share(ShareOptions opts, Action<Result<ShareResult>> callback)
        {
            shareFinishedAction = callback;
            openHarmonyJSObject.Call("share", opts.GetType().Name, opts.ToJson());
        }

        public static void PromoPseudoPurchase(PromoPseudoPurchaseOptions opts)
        {
            openHarmonyJSObject.Call("promoPseudoPurchase", opts.ToJson());
        }

        public static LanguagePreference GetLanguagePreference()
        {
            return JsonConvert.DeserializeObject<LanguagePreference>(openHarmonyJSObject.Call<string>("getLanguagePreference"));
        }

        public static void SetLanguagePreference(LanguagePreference languagePreference)
        {
            openHarmonyJSObject.Call("setLanguagePreference", (int)languagePreference);
        }

        public static string GetLanguageCode()
        {
            return openHarmonyJSObject.Call<string>("getLanguageCode");
        }

        public static void OpenAppSettings()
        {
            openHarmonyJSObject.Call("openAppSettings");
        }

        public static void RegisterDeepLinkCallback(Action<string> callback)
        {
            deepLinkingReceivedAction = callback;
        }

        public static void ManageAccount()
        {
            openHarmonyJSObject.Call("manageAccount");
        }

        public static void ChangePassword()
        {
            openHarmonyJSObject.Call("changePassword");
        }

        public static void DeleteAccount()
        {
            openHarmonyJSObject.Call("deleteAccount");
        }

#region NativeMessageReceivers

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

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

        public void _LoginSucceed(string msg)
        {
            DebugLog("_LoginSucceed", msg);
            var result = Result<LoginResult>.CreateSuccessFromJson(msg);

            if (result != null)
            {
                var comboId = result.Data.loginInfo.comboId;
                TDAnalytics.Login(comboId);
                SentrySdk.ConfigureScope(scope =>
                {
                    scope.User.Id = comboId;
                });
            }

            loginFinishedAction?.Invoke(result);
        }

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

        public void _LogoutSucceed(string msg)
        {
            DebugLog("_LogoutSucceed", msg);
            TDAnalytics.Logout();
            var result = Result<LogoutResult>.CreateSuccessFromJson(msg);
            logoutFinishedAction?.Invoke(result);
        }

        public void _LogoutFailed(string msg)
        {
            DebugLog("_LogoutFailed", msg);
            var result = Result<LogoutResult>.CreateFailFromJson(msg);
            logoutFinishedAction?.Invoke(result);
        }

        public void _QuitSucceed(string msg)
        {
            DebugLog("_QuitSucceed", msg);
            var result = Result<QuitResult>.CreateSuccessFromJson(msg);
            quitFinishedAction?.Invoke(result);
        }

        public void _QuitFailed(string msg)
        {
            DebugLog("_QuitFailed", msg);
            var result = Result<QuitResult>.CreateFailFromJson(msg);
            quitFinishedAction?.Invoke(result);
        }

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

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

        public void _KickOutSucceed(string msg)
        {
            DebugLog("_KickOutSucceed", msg);
            var result = Result<KickOutResult>.CreateSuccessFromJson(msg);
            kickOutFinishedAction?.Invoke(result);
        }

        public void _UpdateGameSucceed(string msg)
        {
            DebugLog("_UpdateGameSucceed", msg);
            var result = Result<UpdateGameResult>.CreateSuccessFromJson(msg);
            updateGameFinishedAction?.Invoke(result);
        }

        public void _UpdateGameFailed(string msg)
        {
            DebugLog("_UpdateGameFailed", msg);
            var result = Result<UpdateGameResult>.CreateFailFromJson(msg);
            updateGameFinishedAction?.Invoke(result);
        }

        public void _GetDownloadUrlSucceed(string msg)
        {
            DebugLog("_GetDownloadUrlSucceed", msg);
            var result = Result<DownloadUrlResult>.CreateSuccessFromJson(msg);
            downloadUrlFinishedAction?.Invoke(result);
        }

        public void _GetDownloadUrlFailed(string msg)
        {
            DebugLog("_GetDownloadUrlFailed", msg);
            var result = Result<DownloadUrlResult>.CreateFailFromJson(msg);
            downloadUrlFinishedAction?.Invoke(result);
        }

        public void _OpenShortLinkSucceed(string msg)
        {
            DebugLog("_OpenShortLinkSucceed", msg);
            var result = Result<OpenShortLinkResult>.CreateSuccessFromJson(msg);
            openShortLinkFinishedAction?.Invoke(result);
        }

        public void _OpenShortLinkFailed(string msg)
        {
            DebugLog("_OpenShortLinkFailed", msg);
            var result = Result<OpenShortLinkResult>.CreateFailFromJson(msg);
            openShortLinkFinishedAction?.Invoke(result);
        }
        public void _CheckAnnouncementsSucceed(string msg)
        {
            DebugLog("_CheckAnnouncementsSucceed", msg);
            var result = Result<CheckAnnouncementsResult>.CreateSuccessFromJson(msg);
            checkAnnouncementsFinishedAction?.Invoke(result);
        }

        public void _CheckAnnouncementsFailed(string msg)
        {
            DebugLog("_CheckAnnouncementsFailed", msg);
            var result = Result<CheckAnnouncementsResult>.CreateFailFromJson(msg);
            checkAnnouncementsFinishedAction?.Invoke(result);
        }
        public void _OpenAnnouncementsSucceed(string msg)
        {
            DebugLog("_OpenAnnouncementsSucceed", msg);
            var result = Result<OpenAnnouncementsResult>.CreateSuccessFromJson(msg);
            openAnnouncementsFinishedAction?.Invoke(result);
        }

        public void _OpenAnnouncementsFailed(string msg)
        {
            DebugLog("_OpenAnnouncementsFailed", msg);
            var result = Result<OpenAnnouncementsResult>.CreateFailFromJson(msg);
            openAnnouncementsFinishedAction?.Invoke(result);
        }

        public void _ComplainSucceed(string msg)
        {
            DebugLog("_ComplainSucceed", msg);
            var result = Result<ComplainResult>.CreateSuccessFromJson(msg);
            complainFinishedAction?.Invoke(result);
        }

        public void _ComplainFailed(string msg)
        {
            DebugLog("_ComplainFailed", msg);
            var result = Result<ComplainResult>.CreateFailFromJson(msg);
            complainFinishedAction?.Invoke(result);
        }

        public void _RedeemGiftCodeSucceed(string msg)
        {
            DebugLog("_RedeemGiftCodeSucceed", msg);
            var result = Result<RedeemGiftCodeResult>.CreateSuccessFromJson(msg);
            redeemGiftCodeFinishedAction?.Invoke(result);
        }

        public void _RedeemGiftCodeFailed(string msg)
        {
            DebugLog("_RedeemGiftCodeFailed", msg);
            var result = Result<RedeemGiftCodeResult>.CreateFailFromJson(msg);
            redeemGiftCodeFinishedAction?.Invoke(result);
        }

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

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

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

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

        public void _ShareSucceed(string msg)
        {
            DebugLog("_ShareSucceed", msg);
            var result = Result<ShareResult>.CreateSuccessFromJson(msg);
            shareFinishedAction?.Invoke(result);
        }

        public void _ShareFailed(string msg)
        {
            DebugLog("_ShareFailed", msg);
            var result = Result<ShareResult>.CreateFailFromJson(msg);
            shareFinishedAction?.Invoke(result);
        }

        public void _OnDeepLink(string url)
        {
            DebugLog("_OnDeepLink", url);
            deepLinkingReceivedAction?.Invoke(url);
        }

        public void DebugLog(string methodName, string msg)
        {
            Debug.Log($"ComboSDKOpenHarmony {methodName}: {msg}");
        }
#endregion
    }
}
#endif