﻿using System;
using System.Collections;
using System.Collections.Generic;
using Platform101XP.Serialization;
using UnityEngine;
using UnityEngine.Android;

using Platform101XP.Entities;
using Platform101XP.Platforms;

public class P101XP : MonoBehaviour
{
    public const string PLUGIN_OBJECT_NAME = "PluginService";

    /// <summary>
    ///  Deligates (Callback)
    /// </summary>
    public delegate void ResultOfInitialize(InitResult initResult);
    public event ResultOfInitialize InitializeEvent;

    public delegate void ResultOfAuthorize(AuthorizeResult authorizeResult);
    public event ResultOfAuthorize AuthorizeResultEvent;

    public delegate void ResultOfBillingInitialize(BillingResult billingResult);
    public event ResultOfBillingInitialize BillingInitializeEvent;

    public delegate void ResultOfGetProducts(ProductsContainer products);
    public event ResultOfGetProducts GetProductsEvent;

    public delegate void ResultOfPurchaseProduct(PurchaseResult purchaseResult);
    public event ResultOfPurchaseProduct PurchaseResultEvent;

    public delegate void ResultOfFinishPurchase(PurchaseResult purchaseResult);
    public event ResultOfFinishPurchase FinishPurchaseEvent;

    public delegate void ResultOfSocialFriends(FriendsContainer friendsContainer);
    public event ResultOfSocialFriends SocialFriendsEvent;

    public delegate void ResultOfInvite(InviteResult inviteResult);
    public event ResultOfInvite InviteEvent;

    public delegate void MessageReceived(string messageText);
    public event MessageReceived MessageReceivedEvent;

    public delegate void LogoutHandler();
    public event LogoutHandler LogoutEvent;

    public delegate void RewardedInviteHandler(RewardRefererResult refererResult);
    public event RewardedInviteHandler RewardedInviteEvent;

    public delegate void RewardedInviteLinkSenderHandler(RewardedInviteLinkResult inviteLinkResult);
    public event RewardedInviteLinkSenderHandler RewardedInviteLinkSenderEvent;

    public delegate void RewardedInviteLinkRecipientHandler(RewardedInviteLinkRecipientResult inviteLinkRecipientResult);
    public event RewardedInviteLinkRecipientHandler RewardedInviteLinkRecipientEvent;

    public delegate void AnalyticsConversionDataHandler(IReadOnlyDictionary<string, string> data);
    public event AnalyticsConversionDataHandler AnalyticsConversionDataEvent;

    public delegate void ResultOfShowWebStore(ShowWebStoreResult result);
    public event ResultOfShowWebStore ShowWebStoreEvent;

    public delegate void PurchaseProductInternalOrderDelegate(PurchaseProductInternalOrderResult result);
    public event PurchaseProductInternalOrderDelegate OnPurchaseProductInternalOrder;

    public delegate void ResultOfCheckMobilePurchase(CheckMobilePurchaseResult result);
    public event ResultOfCheckMobilePurchase CheckMobilePurchaseEvent;

    public delegate void ResultOfGettingAccount(AccountResult result);
    public event ResultOfGettingAccount GetAccountEvent;

    // MARK: - Advertising Events

    public delegate void OnRewardedInterstitialAdShowedDelegate(RewardedInterstitialAdShowedResult result);
    public event OnRewardedInterstitialAdShowedDelegate OnRewardedInterstitialAdShowedEvent;

    public delegate void OnRewardedInterstitialAdLoadedDelegate(RewardedInterstitialAdLoadedResult result);
    public event OnRewardedInterstitialAdLoadedDelegate OnRewardedInterstitialAdLoadedEvent;

    public delegate void OnInterstitialAdShowedDelegate(InterstitialAdShowedResult result);
    public event OnInterstitialAdShowedDelegate OnInterstitialAdShowedEvent;

    public delegate void OnInterstitialAdLoadedDelegate(InterstitialAdLoadedResult result);
    public event OnInterstitialAdLoadedDelegate OnInterstitialAdLoadedEvent;

    public delegate void OnBannerAdLoadedDelegate(BannerAdLoadedResult result);
    public event OnBannerAdLoadedDelegate OnBannerAdLoadedEvent;

    public delegate void OnBannerAdShowedDelegate(BannerAdShowedResult result);
    public event OnBannerAdShowedDelegate OnBannerAdShowedEvent;

    public delegate void OnAppOpenAdShowedDelegate(AppOpenAdShowedResult result);
    public event OnAppOpenAdShowedDelegate OnAppOpenAdShowedEvent;

    public delegate void OnAppOpenAdLoadedDelegate(AppOpenAdLoadedResult result);
    public event OnAppOpenAdLoadedDelegate OnAppOpenAdLoadedEvent;

    public delegate void OnInitializationCompleteDelegate();
    public event OnInitializationCompleteDelegate OnInitializationCompleteEvent;

    public delegate void OnRewardedAdLoadedDelegate(RewardedAdLoadedResult result);
    public event OnRewardedAdLoadedDelegate OnRewardedAdLoadedEvent;

    public delegate void OnRewardedAdShowedDelegate(RewardedAdShowedResult result);
    public event OnRewardedAdShowedDelegate OnRewardedAdShowedEvent;

    // MARK: - Private

    private static P101XP _instance;
    private IPlatform platform;
    private List<Product> allProducts;

    private static void NewInstance()
    {
        if (_instance != null)
        {
            Debug.Log("PluginWrapper instance was found. Already initialized");
            return;
        }

        GameObject pluginOwner = new GameObject(PLUGIN_OBJECT_NAME);
        _instance = pluginOwner.AddComponent<P101XP>();
#if UNITY_ANDROID && !UNITY_EDITOR
        _instance.platform = new AndroidPlatform();
#elif UNITY_IOS && !UNITY_EDITOR
       _instance.platform = new IOSPlatform();
#else
        _instance.platform = new StubPlatform();
#endif
        DontDestroyOnLoad(_instance);
    }

    private T GetFromJson<T>(string json)
    {
        return JsonUtility.FromJson<T>(json);
    }

    private bool IsPluginAvaliable()
    {
        if (platform == null)
        {
            Debug.LogError("Target platform is not available!");
        }
        
        return platform != null;
    }

    // MARK: - SDK Interface

    public static P101XP GetInstance()
    {
        if (_instance == null)
        {
            NewInstance();
        }
        return _instance;
    }

    public Token GetToken()
    {
        if (!IsPluginAvaliable())
            return null;
        return platform.GetToken();
    }

    public Account GetAccount()
    {
        if (!IsPluginAvaliable())
            return null;
        return platform.GetAccount();
    }

    public Product GetProduct(string productId)
    {
        if (string.IsNullOrEmpty(productId))
        {
            Debug.LogError("Error at GetProduct(string) method: The product ID is null or empty.");
            return null;
        }

        return platform.GetProduct(productId);
    }

    public void Initialize()
    {
        if (!IsPluginAvaliable())
            return;
        platform.Initialize();
    }

    public void ShowTroublesDialog()
    {
        if (!IsPluginAvaliable())
            return;
        platform.ShowTroublesDialog();
    }

    public void Authorize()
    {
        if (!IsPluginAvaliable())
            return;
        platform.Authorize();
    }

    public void ShowProfile()
    {
        if (!IsPluginAvaliable())
            return;
        platform.ShowProfile();
    }

    public void PurchaseProduct(string productId, string serverId, Dictionary<string, string> properties)
    {
        if (!IsPluginAvaliable())
            return;
        platform.PurchaseProduct(productId, serverId, properties);
    }

    public void FinishPurchase(PurchaseResult purchaseResult)
    {
        platform.FinishPurchase(purchaseResult);
    }

    public void RestoreProducts()
    {
        platform.RestoreProducts();
    }

    public void PrefetchProduct(string productId)
    {
        platform.PrefetchProduct(productId);
    }

    public void GetProducts(List<string> productIds)
    {
        platform.GetProducts(productIds);
    }

    public void AppReview()
    {
        if (!IsPluginAvaliable())
            return;
        platform.ApplicationReview();
    }

    public void ForcedAppReview()
    {
        if (!IsPluginAvaliable())
            return;
        platform.ForcedApplicationReview();
    }

    public void ApplicationInvite()
    {
        if (!IsPluginAvaliable())
            return;
        platform.ApplicationInvite();
    }

    public void SendInviteLink(string eventName)
    {
        if (!IsPluginAvaliable())
            return;
        platform.SendInviteLink(eventName);
    }

    public void GetSocialFriends()
    {
        if (!IsPluginAvaliable())
            return;
        platform.GetSocialFriends();
    }

    public void SendAnalyticsEvent(string eventName, Dictionary<string, string> eventProperties)
    {
        if (!IsPluginAvaliable())
            return;
        platform.SendEventToAnalytic(eventName, eventProperties);
    }

    public void ShowWebStore(Dictionary<string, string> purchaseProperties, List<string> allowedLocale)
    {
        if (!IsPluginAvaliable())
            return;
        platform.ShowWebStore(purchaseProperties, allowedLocale);
    }

    public void CheckMobilePurchase(string itemName)
    {
        if (!IsPluginAvaliable())
            return;
        platform.CheckMobilePurchase(itemName);
    }

    public void TrackSentryEvent(string eventName, Dictionary<string, object> values)
    {
        if (!IsPluginAvaliable())
            return;
        platform.TrackSentryEvent(eventName, values);
    }

    public void TrackSentryException(Exception exception)
    {
        if (!IsPluginAvaliable())
            return;
        platform.TrackSentryException(exception);
    }

    //
    // MARK: - Reward Ads
    //

    /// <summary>
    /// Loads a rewarded ad using the specified ad unit ID.
    /// </summary>
    /// <param name="id">The ad unit ID for the rewarded ad.</param>
    public void LoadRewardedAd(string id)
    {
        if (!IsPluginAvaliable())
            return;
        platform.LoadRewardedAd(id);
    }

    /// <summary>
    /// Displays the reward ad.
    /// </summary>
    public void ShowRewardedAd()
    {
        if (!IsPluginAvaliable())
            return;
        platform.ShowRewardedAd();
    }

    /// <summary>
    /// Checks the availability of a reward ad. This method only applies to IronSource;
    /// it always returns false for AdMob.
    /// </summary>
    /// <returns>
    /// A boolean indicating whether the rewarded video ad is loaded.
    /// </returns>
    public bool IsRewardedVideoLoaded()
    {
        if (!IsPluginAvaliable())
            return false;
        return platform.IsRewardedVideoLoaded();
    }

    //
    // MARK: - Interstitial Ads
    //

    /// <summary>
    /// Loads an interstitial ad using the specified ad unit ID.
    /// </summary>
    /// <param name="id">The ad unit ID for the interstitial ad.</param>
    public void LoadInterstitialAd(string id)
    {
        if (!IsPluginAvaliable())
            return;
        platform.LoadInterstitialAd(id);
    }

    /// <summary>
    /// Displays the interstitial ad.
    /// </summary>
    public void ShowInterstitialAd()
    {
        if (!IsPluginAvaliable())
            return;
        platform.ShowInterstitialAd();
    }

    /// <summary>
    /// Checks the availability of an interstitial ad. This method only applies to IronSource;
    /// it always returns false for AdMob.
    /// </summary>
    /// <returns>
    /// A boolean indicating whether the interstitial ad is loaded.
    /// </returns>
    public bool IsInterstitialAdLoaded()
    {
        if (!IsPluginAvaliable())
            return false;
        return platform.IsInterstitialAdLoaded();
    }

    //
    // MARK: - Banner Ads
    //

    /// <summary>
    /// Loads a banner ad using the specified ad unit ID.
    /// </summary>
    /// <param name="id">The ad unit ID for the banner ad.</param>
    public void LoadBannerAd(string id)
    {
        if (!IsPluginAvaliable())
            return;
        platform.LoadBannerAd(id);
    }

    /// <summary>
    /// Displays the banner ad.
    /// </summary>
    public void ShowBannerAd()
    {
        if (!IsPluginAvaliable())
            return;
        platform.ShowBannerAd();
    }

    /// <summary>
    /// Hides the banner ad.
    /// </summary>
    public void HideBannerAd()
    {
        if (!IsPluginAvaliable())
            return;
        platform.HideBannerAd();
    }

    /// <summary>
    /// Checks the availability of a banner ad. This method only applies to IronSource;
    /// it always returns false for AdMob.
    /// </summary>
    /// <returns>
    /// A boolean indicating whether the banner ad is loaded.
    /// </returns>
    public bool IsBannerAdLoaded()
    {
        if (!IsPluginAvaliable())
            return false;
        return platform.IsBannerAdLoaded();
    }

    //
    // MARK: - Reward Interstitial Ads - (only AdMob)
    //

    /// <summary>
    /// Loads a rewarded interstitial ad using the specified ad unit ID.
    /// </summary>
    /// <param name="id">The ad unit ID for the rewarded interstitial ad.</param>
    public void LoadRewardedInterstitialAd(string id)
    {
        if (!IsPluginAvaliable())
            return;
        platform.LoadRewardedInterstitialAd(id);
    }

    /// <summary>
    /// Displays the rewarded interstitial ad.
    /// </summary>
    /// <param name="id">
    /// The ad unit ID. Pass 'null' to load the ad specified in your manifest for AdMob.
    /// </param>
    public void ShowRewardedInterstitialAd()
    {
        if (!IsPluginAvaliable())
            return;
        platform.ShowRewardedInterstitialAd();
    }

    //
    // MARK: - UMP SDK
    //

    /// <summary>
    /// Resets the consent information.
    /// </summary>
    /// <remarks>
    /// When testing your app with the UMP SDK, you might find it helpful to reset the state of the SDK
    /// so that you can simulate a user's first install experience.
    /// </remarks>
    public void ResetConsentInformation()
    {
        if (!IsPluginAvaliable())
            return;
        platform.ResetConsentInformation();
    }

    // MARK: - Advertising Listeners

    private void OnRewardedInterstitialAdShowed(string json)
    {
        var result = GetFromJson<RewardedInterstitialAdShowedResult>(json);
        OnRewardedInterstitialAdShowedEvent?.Invoke(result);
    }

    private void OnRewardedInterstitialAdLoaded(string json)
    {
        var result = GetFromJson<RewardedInterstitialAdLoadedResult>(json);
        OnRewardedInterstitialAdLoadedEvent?.Invoke(result);
    }

    private void OnInterstitialAdShowed(string json)
    {
        var result = GetFromJson<InterstitialAdShowedResult>(json);
        OnInterstitialAdShowedEvent?.Invoke(result);
    }

    private void OnInterstitialAdLoaded(string json)
    {
        var result = GetFromJson<InterstitialAdLoadedResult>(json);
        OnInterstitialAdLoadedEvent?.Invoke(result);
    }

    private void OnBannerAdLoaded(string json)
    {
        var result = GetFromJson<BannerAdLoadedResult>(json);
        OnBannerAdLoadedEvent?.Invoke(result);
    }

    private void OnBannerAdShowed(string json)
    {
        var result = GetFromJson<BannerAdShowedResult>(json);
        OnBannerAdShowedEvent?.Invoke(result);
    }

    private void OnAppOpenAdShowed(string json)
    {
        var result = GetFromJson<AppOpenAdShowedResult>(json);
        OnAppOpenAdShowedEvent?.Invoke(result);
    }

    private void OnAppOpenAdLoaded(string json)
    {
        var result = GetFromJson<AppOpenAdLoadedResult>(json);
        OnAppOpenAdLoadedEvent?.Invoke(result);
    }

    private void OnInitializationComplete(string json)
    {
        OnInitializationCompleteEvent?.Invoke();
    }

    private void OnRewardedAdLoaded(string json)
    {
        var result = GetFromJson<RewardedAdLoadedResult>(json);
        OnRewardedAdLoadedEvent?.Invoke(result);
    }

    private void OnRewardedAdShowed(string json)
    {
        var result = GetFromJson<RewardedAdShowedResult>(json);
        OnRewardedAdShowedEvent?.Invoke(result);
    }

    // MARK: - Event Listener

    /// <summary>
    /// Called from current OS.
    /// </summary>
    private void OnAuthorizeResult(string jsonResult)
    {
        ResultOfAuthorize resultAuthorize = AuthorizeResultEvent;
        if (resultAuthorize == null)
        {
            Debug.Log("Callback error. ResultAuthorize is null");
            return;
        }

        AuthorizeResult authorizeResult = GetFromJson<AuthorizeResult>(jsonResult);
        if (authorizeResult == null)
        {
            authorizeResult = new AuthorizeResult();
            authorizeResult.error = "AuthorizeResult is null";
        }
        resultAuthorize(authorizeResult);
    }

    private void OnBillingInitializeResult(string jsonResult)
    {
        ResultOfBillingInitialize resultBillingInitialize = BillingInitializeEvent;
        if (resultBillingInitialize == null)
        {
            Debug.Log("Callback error. ResultBillingInitialize is null");
            return;
        }

        BillingResult billingResult = GetFromJson<BillingResult>(jsonResult);
        if (billingResult == null)
        {
            billingResult = new BillingResult();
            billingResult.error = "BillingResult is null";
        }
        resultBillingInitialize(billingResult);
    }

    private void OnInitializeResult(string jsonResult)
    {
        ResultOfInitialize resultInitialize = InitializeEvent;
        if (resultInitialize == null)
        {
            Debug.Log("Callback error. ResultOfInitialize is null");
            return;
        }
        InitResult initResult = GetFromJson<InitResult>(jsonResult);
        if (initResult == null)
        {
            initResult = new InitResult();
            initResult.error = "InitResult is null";
        }
        resultInitialize(initResult);
    }

    private void OnGetProductsResult(string jsonResult)
    {
        ProductsContainer productsContainer = GetFromJson<ProductsContainer>(jsonResult);
        if (productsContainer == null)
        {
            productsContainer = new ProductsContainer();
            productsContainer.error = "ProductsContainer is null";
        }
        else
        {
            allProducts = productsContainer.products;
        }
        
        GetProductsEvent(productsContainer);
    }

    private void OnPurchaseProductResult(string jsonResult)
    {
        ResultOfPurchaseProduct resultPurchaseProduct = PurchaseResultEvent;
        if (resultPurchaseProduct == null)
        {
            Debug.Log("Callback error. ResultOfPurchaseProduct is null");
            return;
        }
        PurchaseResult purchaseResult = GetFromJson<PurchaseResult>(jsonResult);
        if (purchaseResult == null)
        {
            purchaseResult = new PurchaseResult();
            purchaseResult.error = "PurchaseResult is null";
        }
        resultPurchaseProduct(purchaseResult);
    }

    private void OnFinishPurchaseResult(string jsonResult)
    {
        ResultOfFinishPurchase resultFinishPurchase = FinishPurchaseEvent;
        if (resultFinishPurchase == null)
        {
            Debug.Log("Callback error. ResultOfFinishPurchase is null");
            return;
        }
        PurchaseResult purchaseResult = GetFromJson<PurchaseResult>(jsonResult);
        if (purchaseResult == null)
        {
            purchaseResult = new PurchaseResult();
            purchaseResult.error = "PurchaseResult is null";
        }
        resultFinishPurchase(purchaseResult);
    }

    private void OnGetSocialFriendsResult(string jsonResult)
    {
        ResultOfSocialFriends resultSocialFriends = SocialFriendsEvent;
        if (resultSocialFriends == null)
        {
            Debug.Log("Callback error. ResultOfSocialFriends is null");
            return;
        }
        FriendsContainer friendsContainer = GetFromJson<FriendsContainer>(jsonResult);
        if (friendsContainer == null)
        {
            friendsContainer = new FriendsContainer();
            friendsContainer.error = "FriendsContainer is null";
        }
        resultSocialFriends(friendsContainer);
    }

    private void OnInviteResult(string jsonResult)
    {
        ResultOfInvite resultOfInvite = InviteEvent;
        if (resultOfInvite == null)
        {
            Debug.Log("Callback error. ResultOfInvite is null");
            return;
        }
        InviteResult inviteResult = GetFromJson<InviteResult>(jsonResult);
        if (inviteResult == null)
        {
            inviteResult = new InviteResult();
            inviteResult.error = "InviteResult is null";
        }
        resultOfInvite(inviteResult);
    }

    private void OnMessageReceived(string jsonMessage)
    {
        MessageReceived messageReceived = MessageReceivedEvent;
        if (messageReceived == null)
        {
            Debug.Log("Callback error. MessageReceived is null");
            return;
        }
        SDKMessage message = GetFromJson<SDKMessage>(jsonMessage);
        if (message != null)
        {
            messageReceived(message.messageBody);
        }
    }

    private void OnLogout()
    {
        LogoutHandler logoutHandler = LogoutEvent;
        if (logoutHandler == null)
        {
            Debug.Log("Callback error. LogoutHandler is null");
            return;
        }
        logoutHandler();
    }

    private void OnRewardedInvite(string jsonResult)
    {
        RewardedInviteHandler rewardedInviteHandler = RewardedInviteEvent;
        if (rewardedInviteHandler == null)
        {
            Debug.Log("Callback error. RewardedInviteHandler is null");
            return;
        }
        RewardRefererResult refererResult = GetFromJson<RewardRefererResult>(jsonResult);
        WriteLog("OnRewardedInvite Referrer: " + refererResult.referrer);
        rewardedInviteHandler(refererResult);
    }

    private void OnRewardedInviteLinkSender(string jsonResult)
    {
        RewardedInviteLinkSenderHandler linkSenderHandler = RewardedInviteLinkSenderEvent;
        if (linkSenderHandler == null)
        {
            Debug.Log("Callback error. RewardedInviteLinkSenderHandler is null");
            return;
        }
        RewardedInviteLinkResult inviteLinkResult = GetFromJson<RewardedInviteLinkResult>(jsonResult);
        WriteLog("OnRewardedInviteLinkSender Event: " + inviteLinkResult.eventName);
        linkSenderHandler(inviteLinkResult);
    }

    private void OnRewardedInviteLinkRecipient(string jsonResult)
    {
        RewardedInviteLinkRecipientHandler linkRecipientHandler = RewardedInviteLinkRecipientEvent;
        if (linkRecipientHandler == null)
        {
            Debug.Log("Callback error. RewardedInviteLinkRecipientHandler is null");
            return;
        }
        RewardedInviteLinkRecipientResult linkRecipientResult = GetFromJson<RewardedInviteLinkRecipientResult>(jsonResult);
        WriteLog("OnRewardedInviteLinkRecipient Referrer: " + linkRecipientResult.referrer + " Event: " + linkRecipientResult.eventName);
        linkRecipientHandler(linkRecipientResult);
    }

    private void OnAnalyticsConversionData(string jsonResult)
    {
        AnalyticsConversionDataHandler analyticsConversionDataHandler = AnalyticsConversionDataEvent;
        if (analyticsConversionDataHandler == null)
        {
            Debug.Log("Callback error. AnalyticsConversionDataHandler is null");
            return;
        }
        var data = Json.Deserialize<Dictionary<string, string>>(jsonResult);
        analyticsConversionDataHandler(data);
    }

    private void OnShowWebStoreResult(string jsonResult)
    {
        ResultOfShowWebStore showWebStoreEvent = ShowWebStoreEvent;
        if (showWebStoreEvent == null)
        {
            Debug.Log("Callback error. ShowWebStoreEvent is null");
            return;
        }
        ShowWebStoreResult showWebStoreResult = GetFromJson<ShowWebStoreResult>(jsonResult);
        if (showWebStoreResult == null)
        {
            showWebStoreResult = new ShowWebStoreResult();
            showWebStoreResult.error = "ShowWebStoreResult is null";
        }
        showWebStoreEvent(showWebStoreResult);
    }

    private void OnPurchaseProductInternalOrderResult(string jsonResult)
    {
        PurchaseProductInternalOrderDelegate handler = OnPurchaseProductInternalOrder;
        if (handler == null)
        {
            Debug.Log("[101XP] Error: The OnPurchaseProductInternalOrder event is null");
            return;
        }
        PurchaseProductInternalOrderResult result = GetFromJson<PurchaseProductInternalOrderResult>(jsonResult);
        if (result == null)
        {
            result = new PurchaseProductInternalOrderResult();
            result.error = "PurchaseProductInternalOrderResult is null";
        }
        handler(result);
    }

    private void OnCheckMobilePurchase(string jsonResult)
    {
        ResultOfCheckMobilePurchase checkMobilePurchaseEvent = CheckMobilePurchaseEvent;
        if (checkMobilePurchaseEvent == null)
        {
            Debug.Log("Callback error. CheckMobilePurchaseEvent is null");
            return;
        }
        CheckMobilePurchaseResult checkMobilePurchaseResult = GetFromJson<CheckMobilePurchaseResult>(jsonResult);
        if (checkMobilePurchaseResult == null)
        {
            checkMobilePurchaseResult = new CheckMobilePurchaseResult();
            checkMobilePurchaseResult.error = "CheckMobilePurchaseResult is null";
        }
        checkMobilePurchaseEvent(checkMobilePurchaseResult);
    }

    private void OnGetAccountResult(string jsonResult)
    {
        ResultOfGettingAccount getAccountEvent = GetAccountEvent;
        if (getAccountEvent == null)
        {
            Debug.Log("Callback error. GetAccountEvent is null");
            return;
        }
        AccountResult accountResult = GetFromJson<AccountResult>(jsonResult);
        if (accountResult == null)
        {
            accountResult = new AccountResult();
            accountResult.error = "AccountResult is null";
        }
        getAccountEvent(accountResult);
    }

    ///<summary>
    /// Unity internal.
    ///</summary>
    public List<Product> GetAllProducts()
    {
        return allProducts;
    }

    public void ErrorHandle(string errorMessage)
    {
        var prefix = "P101XP Unity error: ";
        WriteLog(prefix + errorMessage);
        MessageShow(prefix + errorMessage);
    }

    public void MessageShow(string text)
    {
        if (!IsPluginAvaliable()) return;
        platform.ShowMessage(text);
    }

    public void WriteLog(string logMessage)
    {
        if (!IsPluginAvaliable()) return;
        platform.LogEvent(logMessage);
    }
}