﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Platform101XP.Serialization;
using UnityEngine;
using UnityEngine.SceneManagement;

using Platform101XP.Entities;

public class P101XPBehaviour : MonoBehaviour
{
    private Dictionary<string, string> eventProperties;
    private Dictionary<string, string> purchaseProperty;


    private string consumeProductId;
    private string nonconsumeProductId;

    void Awake()
    {
        // Events
        P101XP.GetInstance().InitializeEvent += SdkInitializeHandler;
        P101XP.GetInstance().AuthorizeResultEvent += AuthorizeResultHandler;
        P101XP.GetInstance().GetAccountEvent += GetAccountEventHandler;
        P101XP.GetInstance().BillingInitializeEvent += SdkBillingInitializeHandler;
        P101XP.GetInstance().GetProductsEvent += GetProductsHandler;
        P101XP.GetInstance().PurchaseResultEvent += PurchaseProductHandler;
        P101XP.GetInstance().FinishPurchaseEvent += FinishPurchaseHandler;
        P101XP.GetInstance().SocialFriendsEvent += GetSocialFriendsHandler;
        P101XP.GetInstance().InviteEvent += InviteHandler;
        P101XP.GetInstance().MessageReceivedEvent += MessageReceivedHandler;
        P101XP.GetInstance().LogoutEvent += LogoutHandler;
        P101XP.GetInstance().RewardedInviteEvent += RewardedInviteHandler;
        P101XP.GetInstance().RewardedInviteLinkSenderEvent += RewardedLinkSenderHandler;
        P101XP.GetInstance().RewardedInviteLinkRecipientEvent += RewardedLinkRecipientHandler;
        P101XP.GetInstance().AnalyticsConversionDataEvent += AnalyticsConversionDataHandler;
        P101XP.GetInstance().ShowWebStoreEvent += ShowWebStoreEventHandler;

        // Advertising
        P101XP.GetInstance().OnRewardedInterstitialAdShowedEvent += HandleRewardedInterstitialAdShowed;
        P101XP.GetInstance().OnRewardedInterstitialAdLoadedEvent += HandleRewardedInterstitialAdLoaded;
        P101XP.GetInstance().OnInterstitialAdShowedEvent += HandleInterstitialAdShowed;
        P101XP.GetInstance().OnInterstitialAdLoadedEvent += HandleInterstitialAdLoaded;
        P101XP.GetInstance().OnBannerAdShowedEvent += HandleBannerAdShowed;
        P101XP.GetInstance().OnAppOpenAdShowedEvent += HandleAppOpenAdShowed;
        P101XP.GetInstance().OnAppOpenAdLoadedEvent += HandleAppOpenAdLoaded;
        P101XP.GetInstance().OnInitializationCompleteEvent += HandleInitializationComplete;
        P101XP.GetInstance().OnRewardedAdLoadedEvent += HandleRewardedAdLoaded;
        P101XP.GetInstance().OnRewardedAdShowedEvent += HandleRewardedAdShowed;

        // Initialize
        P101XP.GetInstance().Initialize();
    }

    void Start()
    {
        eventProperties = new Dictionary<string, string>
        {
            { "first_event_property", "first_property" },
            { "second_event_property", "second_property" }
        };

        purchaseProperty = new Dictionary<string, string>
        {
            { "first_purchase_property", "first_property" },
            { "second_purchase_property", "second_property" }
        };

#if UNITY_ANDROID
        consumeProductId = "com.platform101xp.sample_android.consume";
        nonconsumeProductId = "com.platform101xp.sample_android.nonconsume";
#elif UNITY_IOS 
        consumeProductId = "com.xp101.sample.consume_product2";
        nonconsumeProductId = "com.xp101.sample.product2";
#endif
    }


    void OnDestroy()
    {
        // Events
        P101XP.GetInstance().InitializeEvent -= SdkInitializeHandler;
        P101XP.GetInstance().AuthorizeResultEvent -= AuthorizeResultHandler;
        P101XP.GetInstance().GetAccountEvent -= GetAccountEventHandler;
        P101XP.GetInstance().BillingInitializeEvent -= SdkBillingInitializeHandler;
        P101XP.GetInstance().GetProductsEvent -= GetProductsHandler;
        P101XP.GetInstance().PurchaseResultEvent -= PurchaseProductHandler;
        P101XP.GetInstance().FinishPurchaseEvent -= FinishPurchaseHandler;
        P101XP.GetInstance().SocialFriendsEvent -= GetSocialFriendsHandler;
        P101XP.GetInstance().InviteEvent -= InviteHandler;
        P101XP.GetInstance().MessageReceivedEvent -= MessageReceivedHandler;
        P101XP.GetInstance().LogoutEvent -= LogoutHandler;
        P101XP.GetInstance().RewardedInviteEvent -= RewardedInviteHandler;
        P101XP.GetInstance().RewardedInviteLinkSenderEvent -= RewardedLinkSenderHandler;
        P101XP.GetInstance().RewardedInviteLinkRecipientEvent -= RewardedLinkRecipientHandler;
        P101XP.GetInstance().AnalyticsConversionDataEvent -= AnalyticsConversionDataHandler;
        P101XP.GetInstance().ShowWebStoreEvent -= ShowWebStoreEventHandler;

        // Advertising
        P101XP.GetInstance().OnRewardedInterstitialAdShowedEvent -= HandleRewardedInterstitialAdShowed;
        P101XP.GetInstance().OnRewardedInterstitialAdLoadedEvent -= HandleRewardedInterstitialAdLoaded;
        P101XP.GetInstance().OnInterstitialAdShowedEvent -= HandleInterstitialAdShowed;
        P101XP.GetInstance().OnInterstitialAdLoadedEvent -= HandleInterstitialAdLoaded;
        P101XP.GetInstance().OnBannerAdShowedEvent -= HandleBannerAdShowed;
        P101XP.GetInstance().OnAppOpenAdShowedEvent -= HandleAppOpenAdShowed;
        P101XP.GetInstance().OnAppOpenAdLoadedEvent -= HandleAppOpenAdLoaded;
        P101XP.GetInstance().OnInitializationCompleteEvent -= HandleInitializationComplete;
        P101XP.GetInstance().OnRewardedAdLoadedEvent -= HandleRewardedAdLoaded;
        P101XP.GetInstance().OnRewardedAdShowedEvent -= HandleRewardedAdShowed;
    }

    public void GetToken()
    {
        Token token = P101XP.GetInstance().GetToken();
        if (token == null)
        {
            DebugOverlay.Instance.Log("Token is null!");
        }
        else
        {
            DebugOverlay.Instance.Log("Token is received!");
            DebugOverlay.Instance.Log($"accessToken={token.accessToken}");
            DebugOverlay.Instance.Log($"expires={token.expires}");
            DebugOverlay.Instance.Log($"type={token.type}");
            DebugOverlay.Instance.Log($"provider={token.provider}");
        }
    }

    public void GetAccount()
    {
        Account account = P101XP.GetInstance().GetAccount();
        if (account == null)
        {
            DebugOverlay.Instance.Log("Account is null!");
        }
        else
        {
            DebugOverlay.Instance.Log("Account is received!");
            DebugOverlay.Instance.Log($"accountId={account.accountId}");
            DebugOverlay.Instance.Log($"portalId={account.portalId}");
            DebugOverlay.Instance.Log($"userGameId={account.userGameId}");
            DebugOverlay.Instance.Log($"mobileId={account.mobileId}");
            DebugOverlay.Instance.Log($"userName={account.userName}");
            DebugOverlay.Instance.Log($"userPhotoUrl={account.userPhotoUrl}");
            DebugOverlay.Instance.Log($"isGuest={account.isGuest}");
        }
    }

    public void ShowTroublesDialog()
    {
        P101XP.GetInstance().ShowTroublesDialog();
    }

    public void AuthorizeAction()
    {
        P101XP.GetInstance().Authorize();
        P101XP.GetInstance().SendAnalyticsEvent("authorize_event", eventProperties);
    }

    public void RestoreProducts()
    {
        P101XP.GetInstance().RestoreProducts();
    }

    public void ShowProfile()
    {
        P101XP.GetInstance().ShowProfile();
    }

    public void PurchaseConsume()
    {
        P101XP.GetInstance().PurchaseProduct(consumeProductId, "90001", purchaseProperty);
    }

    public void Purchase()
    {
        P101XP.GetInstance().PurchaseProduct(nonconsumeProductId, "90001", purchaseProperty);
    }

    public void GetAllProducts()
    {
        P101XP.GetInstance().GetProducts(null);
    }

    public void ApplicationReview()
    {
        P101XP.GetInstance().AppReview();
    }

    public void AppInvite()
    {
        P101XP.GetInstance().ApplicationInvite();
    }

    public void SendInviteLink(string eventName)
    {
        P101XP.GetInstance().SendInviteLink(eventName);
    }

    public void GetSocialFriends()
    {
        P101XP.GetInstance().GetSocialFriends();
    }

    public void ShowWebStore()
    {
        P101XP.GetInstance().ShowWebStore(null, null);
    }

    public void TrackSentryEvent()
    {
        P101XP.GetInstance().TrackSentryEvent("testEvent", new Dictionary<string, object>
        {
            { "testBool", true },
            { "testInt", 1 },
            { "testFloat", 3.333 },
            { "testString", "qweasdzxc" },
        });
    }

    public void TrackSentryException()
    {
        P101XP.GetInstance().TrackSentryException(new ArgumentOutOfRangeException("Some Out Of Range Parameter!!!"));
    }

    // MARK: - Advertising

    public void ShowRewardedAd()
    {
        P101XP.GetInstance().ShowRewardedAd();
    }

    public void IsRewardedVideoLoaded()
    {
        bool result = P101XP.GetInstance().IsRewardedVideoLoaded();
        P101XP.GetInstance().MessageShow("The IsRewardedVideoLoaded method call result: " + result);
    }

    public void ShowInterstitialAd()
    {
        P101XP.GetInstance().ShowInterstitialAd();
    }

    public void IsInterstitialAdLoaded()
    {
        bool result = P101XP.GetInstance().IsInterstitialAdLoaded();
        P101XP.GetInstance().MessageShow("The IsInterstitialAdLoaded method call result: " + result);
    }

    public void ShowBannerAd()
    {
        P101XP.GetInstance().ShowBannerAd();
    }

    public void HideBannerAd()
    {
        P101XP.GetInstance().HideBannerAd();
    }

    public void IsBannerAdLoaded()
    {
        bool result = P101XP.GetInstance().IsBannerAdLoaded();
        P101XP.GetInstance().MessageShow("The IsBannerAdLoaded method call result: " + result);
    }

    public void ShowRewardedInterstitialAd()
    {
        P101XP.GetInstance().ShowRewardedInterstitialAd();
    }

    public void ResetConsentInformation()
    {
        P101XP.GetInstance().ResetConsentInformation();
    }

    public void LoadRewardedAd()
    {
        string id = null;
        P101XP.GetInstance().LoadRewardedAd(id);
    }

    public void LoadInterstitialAd()
    {
        string id = null;
        P101XP.GetInstance().LoadInterstitialAd(id);
    }

    public void LoadRewardedInterstitialAd()
    {
        string id = null;
        P101XP.GetInstance().LoadRewardedInterstitialAd(id);
    }

    // MARK: - Advertising Event Handlers

    private void HandleRewardedInterstitialAdShowed(RewardedInterstitialAdShowedResult result)
    {
        if (!string.IsNullOrEmpty(result.error))
        {
            HandleError($"OnRewardedInterstitialAdShowed error: {result.error}");
            return;
        }
        string message = $"Rewarded Interstitial Ad Showed: Amount = {result.amount}, Name = {result.name}";
        P101XP.GetInstance().MessageShow(message);
    }

    private void HandleRewardedInterstitialAdLoaded(RewardedInterstitialAdLoadedResult result)
    {
        if (!string.IsNullOrEmpty(result.error))
        {
            HandleError($"OnRewardedInterstitialAdLoaded error: {result.error}");
            return;
        }
        P101XP.GetInstance().MessageShow("Rewarded Interstitial Ad Loaded");
    }

    private void HandleInterstitialAdShowed(InterstitialAdShowedResult result)
    {
        if (!string.IsNullOrEmpty(result.error))
        {
            HandleError($"OnInterstitialAdShowed error: {result.error}");
            return;
        }
        P101XP.GetInstance().MessageShow("Interstitial Ad Showed");
    }

    private void HandleInterstitialAdLoaded(InterstitialAdLoadedResult result)
    {
        if (!string.IsNullOrEmpty(result.error))
        {
            HandleError($"OnInterstitialAdLoaded error: {result.error}");
            return;
        }
        P101XP.GetInstance().MessageShow("Interstitial Ad Loaded");
    }

    private void HandleBannerAdShowed(BannerAdShowedResult result)
    {
        if (!string.IsNullOrEmpty(result.error))
        {
            HandleError($"OnBannerAdShowed error: {result.error}");
            return;
        }
        P101XP.GetInstance().MessageShow("Banner Ad Showed");
    }

    private void HandleAppOpenAdShowed(AppOpenAdShowedResult result)
    {
        if (!string.IsNullOrEmpty(result.error))
        {
            HandleError($"OnAppOpenAdShowed error: {result.error}");
            return;
        }
        P101XP.GetInstance().MessageShow("App Open Ad Showed");
    }

    private void HandleAppOpenAdLoaded(AppOpenAdLoadedResult result)
    {
        if (!string.IsNullOrEmpty(result.error))
        {
            HandleError($"OnAppOpenAdLoaded error: {result.error}");
            return;
        }
        P101XP.GetInstance().MessageShow("App Open Ad Loaded");
    }

    private void HandleInitializationComplete()
    {
        P101XP.GetInstance().MessageShow("Advertising Initialization Complete");
    }

    private void HandleRewardedAdLoaded(RewardedAdLoadedResult result)
    {
        if (!string.IsNullOrEmpty(result.error))
        {
            HandleError($"OnRewardedAdLoaded error: {result.error}");
            return;
        }
        P101XP.GetInstance().MessageShow("Rewarded Ad Loaded");
    }

    private void HandleRewardedAdShowed(RewardedAdShowedResult result)
    {
        if (!string.IsNullOrEmpty(result.error))
        {
            HandleError($"OnRewardedAdShowed error: {result.error}");
            return;
        }
        string message = $"Rewarded Ad Showed: Amount = {result.amount}, Name = {result.name}";
        P101XP.GetInstance().MessageShow(message);
    }

    // MARK: - Private

    private void LoadScene(string sceneName)
    {
        SceneManager.LoadScene(sceneName);
    }

    private void HandleError(string errorText)
    {
        P101XP.GetInstance().ErrorHandle(errorText);
    }

    //Callback implements:
    private void SdkInitializeHandler(InitResult initResult)
    {
        if (initResult == null)
        {
            return;
        }

        if (!string.IsNullOrEmpty(initResult.error))
        {
            HandleError("initialize: " + initResult.error);
        }

        if (initResult.initialized)
        {
            P101XP.GetInstance().WriteLog("Sdk initialize success.");
        }
    }

    private void SdkBillingInitializeHandler(BillingResult billingResult)
    {
        if (billingResult == null) return;
        if (!string.IsNullOrEmpty(billingResult.error))
        {
            HandleError("billing initialize: " + billingResult.error);
        }

        if (billingResult.available)
        {
            P101XP.GetInstance().MessageShow("Billing is available!");
        }
    }

    private void AuthorizeResultHandler(AuthorizeResult authorizeResult)
    {
        if (authorizeResult == null)
        {
            return;
        }

        if (!string.IsNullOrEmpty(authorizeResult.error))
        {
            HandleError("authorize: " + authorizeResult.error);
            return;
        }

        var json = Json.Serialize(authorizeResult);
        P101XP.GetInstance().MessageShow($"AuthorizeResult as JSON:\n{json}");
    }

    private void GetProductsHandler(ProductsContainer productsContainer)
    {
        if (productsContainer == null)
        {
            HandleError("GetProductsHandler_Error: Products container is null!");
            return;
        }

        if (!string.IsNullOrEmpty(productsContainer.error))
        {
            HandleError("GetProductsHandler_Error: " + productsContainer.error);
        }

        if (productsContainer.products != null)
        {
            string productsString = $"GetProductsHandler_Products(count={productsContainer.products.Count}):";
            foreach (Product product in productsContainer.products)
            {
                productsString += " " + product.productId;
            }

            P101XP.GetInstance().WriteLog(productsString);
            P101XP.GetInstance().MessageShow(productsString);
        } else
        {
            HandleError("GetProductsHandler_Error: Products list is null!");
        }
    }

    private void PurchaseProductHandler(PurchaseResult purchaseResult)
    {
        if (purchaseResult == null)
        {
            return;
        }

        if (!string.IsNullOrEmpty(purchaseResult.error))
        {
            HandleError("purchase product: " + purchaseResult.error);
        }
        else if (purchaseResult.productId != null)
        {
            if (purchaseResult.productId.Contains("consume"))
                P101XP.GetInstance().FinishPurchase(purchaseResult);
            else
                P101XP.GetInstance().MessageShow("Now you are owner product with id: " + purchaseResult.productId);
        }
    }

    private void FinishPurchaseHandler(PurchaseResult purchaseResult)
    {
        if (purchaseResult == null)
        {
            return;
        }

        if (!string.IsNullOrEmpty(purchaseResult.error))
        {
            HandleError("finish purchase: " + purchaseResult.error);
        }
        else if (purchaseResult.productId != null)
        {
            P101XP.GetInstance().MessageShow("Product with id:\n" + purchaseResult.productId + "\nconsumed");
        }
    }

    private void GetSocialFriendsHandler(FriendsContainer friendsContainer)
    {
        if (friendsContainer == null)
        {
            return;
        }

        if (!string.IsNullOrEmpty(friendsContainer.error))
        {
            HandleError("get social friends: " + friendsContainer.error);
        }
        else if (friendsContainer.friends != null)
        {
            string friendsNames = "";
            foreach (SocialFriend friend in friendsContainer.friends)
            {
                friendsNames += " " + friend.name;
            }

            if (friendsNames != "")
            {
                P101XP.GetInstance().MessageShow("Friends" + friendsNames);
            }
        }
    }

    private void InviteHandler(InviteResult inviteResult)
    {
        if (inviteResult == null)
        {
            return;
        }

        if (!string.IsNullOrEmpty(inviteResult.error))
        {
            HandleError("invite: " + inviteResult.error);
        }

        if (inviteResult.invited)
        {
            P101XP.GetInstance().MessageShow("Invite sucess!");
        }
    }

    private void MessageReceivedHandler(string messageText)
    {
        P101XP.GetInstance().MessageShow(messageText);
    }

    private void LogoutHandler()
    {
        P101XP.GetInstance().MessageShow("Logout");
    }

    private void RewardedInviteHandler(RewardRefererResult refererResult)
    {
        if (refererResult == null) return;
        if (refererResult.referrer != null)
        {
            P101XP.GetInstance().MessageShow("Invite Rewarded \n for Referrer:" + refererResult.referrer);
        }
    }

    private void RewardedLinkSenderHandler(RewardedInviteLinkResult linkResult)
    {
        if (linkResult == null) return;
        if (linkResult.eventName != null)
        {
            P101XP.GetInstance().MessageShow("Referrer got reward, got event: " + linkResult.eventName);
        }
    }

    private void RewardedLinkRecipientHandler(RewardedInviteLinkRecipientResult linkRecipientResult)
    {
        if (linkRecipientResult == null) return;
        if (linkRecipientResult.eventName != null && linkRecipientResult.referrer != null)
        {
            P101XP.GetInstance().MessageShow("User done condition. User got reward");
        }
    }

    private void AnalyticsConversionDataHandler(IReadOnlyDictionary<string, string> data)
    {
        if (data == null)
        {
            P101XP.GetInstance().MessageShow("The AnalyticsConversionData is null");
            return;
        }
        else if (!data.Any())
        {
            P101XP.GetInstance().MessageShow("The AnalyticsConversionData is empty");
            return;
        }
        else
        {
            var json = Json.Serialize(data);
            P101XP.GetInstance().MessageShow($"The AnalyticsConversionData as JSON:\n{json}");
            return;
        }
    }

    private void ShowWebStoreEventHandler(ShowWebStoreResult result)
    {
        if (result == null)
        {
            return;
        }

        if (!string.IsNullOrEmpty(result.error))
        {
            HandleError("An error occurred while trying to show the WebStore: " + result.error);
        }

        if (result.success)
        {
            P101XP.GetInstance().WriteLog("The WebStore was shown successfully");
        }
    }

    private void GetAccountEventHandler(AccountResult result)
    {
        if (result == null)
        {
            return;
        }

        if (!string.IsNullOrEmpty(result.error))
        {
            HandleError("An error occurred while trying to get account: " + result.error);
            return;
        }

        var json = Json.Serialize(result);
        P101XP.GetInstance().MessageShow($"AccountResult as JSON:\n{json}");
    }
}