using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using hive;
using GameNetwork;
using Game;
using GameUtility;

public class Shop : MonoBehaviour {

	public HomeManager homeManager;

	public Toast toast;
	public Loading loading;
	public Popup popup;
	public Popup2 popupSubscriptionInfo;

	public Text textBalance;

	public Sprite subscribe;
	public Sprite subscribeBg;
	public Sprite subscribed;
	public Sprite subscribedBg;
	public Sprite reserved;
	public Sprite reservedBg;

	public Text textSubGold1Price;
	public Text textSubGold2Price;
	public Text textSubSpeed1Price;
	public Text textSubSpeed2Price;
	public Text textSubSuperSuitPrice;
	public Text textSubDevilSuitPrice;

	public Button buttonSubGold1;
	public Image buttonSubGold1Text;
	public Button buttonSubGold2;
	public Image buttonSubGold2Text;
	public Button buttonSubSpeed1;
	public Image buttonSubSpeed1Text;
	public Button buttonSubSpeed2;
	public Image buttonSubSpeed2Text;
	public Button buttonSubSuperSuit;
	public Image buttonSubSuperSuitText;
	public Button buttonSubDevilSuit;
	public Image buttonSubDevilSuitText;

	public Sprite level1;
	public Sprite level2;
	public Sprite level3;
	public Sprite levelMax;

	public Button buttonHealthUp;
	public Image imageHealthUpValue;
	public Text textHealthUpPrice;

	public Button buttonSpeedUp;
	public Image imageSpeedUpValue;
	public Text textSpeedUpPrice;

	public Button buttonItem1;
	public Text textItem1Message;
	public Text textItem1Price;

	public Button buttonItem2;
	public Text textItem2Message;
	public Text textItem2Price;

	public Button buttonItem3;
	public Text textItem3Message;
	public Text textItem3Price;


	public Button buttonItem4;
	public Text textItem4Message;
	public Text textItem4Price;

	bool isSetup = false;

	private enum SubscriptionState {
		SUBSCRIBE, SUBSCRIBED, RESERVED
	}

	SubscriptionState isActiveSubGold1Button = SubscriptionState.SUBSCRIBE;
	SubscriptionState isActiveSubGold2Button = SubscriptionState.SUBSCRIBE;
	SubscriptionState isActiveSubSpeed1Button = SubscriptionState.SUBSCRIBE;
	SubscriptionState isActiveSubSpeed2Button = SubscriptionState.SUBSCRIBE;
	SubscriptionState isActiveSubSuperSuitButton = SubscriptionState.SUBSCRIBE;
	SubscriptionState isActiveSubDevilSuitButton = SubscriptionState.SUBSCRIBE;
	

	// 구매 버튼 중복 클릭 방지
	private bool _progressState;
	private bool inProgressing 
	{
		get {
			return _progressState;
		}
		set {
			if (value) {
				// 다른 것이 처리중이다
				_progressState = value;
				loading.show();
				
			} else {
				// 처리 중인 것이 없는 상태이다.
				_progressState = value;
				loading.hide();
			}
		}
	}


	private Dictionary<string, long> localSubscribedPidList = new Dictionary<string, long>();


	void Update () {
		if(Input.GetKeyDown(KeyCode.Escape))
		{
			inProgressing = false;
			
			if (popup.gameObject.activeSelf) {
				popup.dismiss();
			} else if (popupSubscriptionInfo.gameObject.activeSelf) {
				popupSubscriptionInfo.dismiss();
			} else {
				homeManager.onShopClick(false);
			}
		}
	}

	public void open()
	{
		Debug.Log ("Shop open");

		inProgressing = true;
		HIVEManager.shared.shopSetup(onHIVEManagerShopSetup);	
	}

	public void close() 
	{
		Debug.Log ("Shop close");

		inProgressing = false;
		popup.dismiss();
		popupSubscriptionInfo.dismiss();
		homeManager.onShopClick(false);
	}


	public void updatePlayerUiInfo(string balance)
	{
		textBalance.text = balance == null ? PlayerSettings.Instance().Gold.ToString() : balance;
		UpdatePlayerHealthUpButton();
		UpdatePlayerSpeedUpButton();
		UpdatePlayerSubscribeButton();
	}


	void setAccountItems(List<Item> accountItems)
	{
		PlayerSettings.Instance ().Items = accountItems;
	}

	void setAccountSubscriptionItems(List<GameNetwork.Subscription> subscriptions)
	{
		PlayerSettings.Instance ().Subscriptions = subscriptions;

		if (subscriptions == null || subscriptions.Count <= 0) {
			isActiveSubGold1Button = SubscriptionState.SUBSCRIBE;
			isActiveSubGold2Button = SubscriptionState.SUBSCRIBE;
			isActiveSubSpeed1Button = SubscriptionState.SUBSCRIBE;
			isActiveSubSpeed2Button = SubscriptionState.SUBSCRIBE;
			isActiveSubSuperSuitButton = SubscriptionState.SUBSCRIBE;
			isActiveSubDevilSuitButton = SubscriptionState.SUBSCRIBE;

		} else {
			foreach(GameNetwork.Subscription sub in subscriptions) {
				if (string.Equals(sub.productId, HIVEManager.marketPid_subGold1)) {
					isActiveSubGold1Button = SubscriptionState.SUBSCRIBED;
					if (string.Equals(sub.nextProductId, HIVEManager.marketPid_subGold2)) {
						isActiveSubGold2Button = SubscriptionState.RESERVED;
					} else {
						isActiveSubGold2Button = SubscriptionState.SUBSCRIBE;
					}
									
				} else if (string.Equals(sub.productId, HIVEManager.marketPid_subGold2)) {
					isActiveSubGold2Button = SubscriptionState.SUBSCRIBED;
					if (string.Equals(sub.nextProductId, HIVEManager.marketPid_subGold1)) {
						isActiveSubGold1Button = SubscriptionState.RESERVED;
					} else {
						isActiveSubGold1Button = SubscriptionState.SUBSCRIBE;
					}

				} else if (string.Equals(sub.productId, HIVEManager.marketPid_subSpeed1)) {
					isActiveSubSpeed1Button = SubscriptionState.SUBSCRIBED;
					if (string.Equals(sub.nextProductId, HIVEManager.marketPid_subSpeed2)) {
						isActiveSubSpeed2Button = SubscriptionState.RESERVED;
					} else {
						isActiveSubSpeed2Button = SubscriptionState.SUBSCRIBE;
					}
					
				} else if (string.Equals(sub.productId, HIVEManager.marketPid_subSpeed2)) {
					isActiveSubSpeed2Button = SubscriptionState.SUBSCRIBED;
					if (string.Equals(sub.nextProductId, HIVEManager.marketPid_subSpeed1)) {
						isActiveSubSpeed1Button = SubscriptionState.RESERVED;
					} else {
						isActiveSubSpeed1Button = SubscriptionState.SUBSCRIBE;
					}
					
				} else if (string.Equals(sub.productId, HIVEManager.marketPid_subSuperSuit)) {
					isActiveSubSuperSuitButton = SubscriptionState.SUBSCRIBED;
					if (string.Equals(sub.nextProductId, HIVEManager.marketPid_subDevilSuit)) {
						isActiveSubDevilSuitButton = SubscriptionState.RESERVED;
					} else {
						isActiveSubDevilSuitButton = SubscriptionState.SUBSCRIBE;
					}
					
				} else if (string.Equals(sub.productId, HIVEManager.marketPid_subDevilSuit)) {
					isActiveSubDevilSuitButton = SubscriptionState.SUBSCRIBED;
					if (string.Equals(sub.nextProductId, HIVEManager.marketPid_subSuperSuit)) {
						isActiveSubSuperSuitButton = SubscriptionState.RESERVED;
					} else {
						isActiveSubSuperSuitButton = SubscriptionState.SUBSCRIBE;
					}
				}
			}
		}
	}

	/* 서버 컨트롤을 위해서는 서버에서 준 값으로만 UI 를 구성해야 하지만 여기서는 고정값으로 구현 */
	void setItemList(List<IAPV4.IAPV4Product> productList)
	{
		Debug.Log("setItemList");
		// product list
		textItem1Message.text = removeAppName(productList [HIVEManager.item1Index].title);
		textItem1Price.text = productList [HIVEManager.item1Index].displayPrice;

		textItem2Message.text = removeAppName(productList [HIVEManager.item2Index].title);
		textItem2Price.text = productList [HIVEManager.item2Index].displayPrice;

		textItem3Message.text = removeAppName(productList [HIVEManager.item3Index].title);
		textItem3Price.text = productList [HIVEManager.item3Index].displayPrice;

		textItem4Message.text = removeAppName(productList [HIVEManager.item4Index].title);
		textItem4Price.text = productList [HIVEManager.item4Index].displayPrice;

		
	}

	void setSubscriptionItemList(List<IAPV4.IAPV4Product> subscriptionList)
	{
		Debug.Log("setSubscriptionItemList");
		// subscription list
		// textSubGold1Title.text = removeAppName(subscriptionList [HIVEManager.subGold1Index].title);
		textSubGold1Price.text = subscriptionList [HIVEManager.subGold1Index].displayPrice + " / 7 days";
		textSubGold2Price.text = subscriptionList [HIVEManager.subGold2Index].displayPrice + " / 7 days";
		textSubSpeed1Price.text = subscriptionList [HIVEManager.subSpeed1Index].displayPrice + " / 30 days";
		textSubSpeed2Price.text = subscriptionList [HIVEManager.subSpeed2Index].displayPrice + " / 30 days";
		textSubSuperSuitPrice.text = subscriptionList [HIVEManager.subSuperSuitIndex].displayPrice + " / 7 days";
		textSubDevilSuitPrice.text = subscriptionList [HIVEManager.subDevilSuitIndex].displayPrice + " / 7 days";
	}

	string removeAppName(string str) {
		string restr = "";
		if (!string.IsNullOrEmpty(str)) {
			int strIndex = str.IndexOf(" (Planet explore)");

			if (strIndex > 0) {
				restr = str.Substring(0, strIndex);
			} else {
				restr = str;
			}
		}
		return restr;
	}

	void UpdatePlayerHealthUpButton()
	{
		if (PlayerSettings.Instance().IsMaxHealth) {
			imageHealthUpValue.sprite = levelMax;
			buttonHealthUp.gameObject.SetActive (false);

		} else {
			buttonHealthUp.gameObject.SetActive (true);
			switch (PlayerSettings.Instance ().HealthLevel) {
			case 0:
				imageHealthUpValue.sprite = level1;
				textHealthUpPrice.text = "1000";
				break;
			case 1:
				imageHealthUpValue.sprite = level2;
				textHealthUpPrice.text = "2000";
				break;
			case 2:
				imageHealthUpValue.sprite = level3;
				textHealthUpPrice.text = "4000";
				break;
			case 3:
			default:
				imageHealthUpValue.sprite = levelMax;
				buttonHealthUp.gameObject.SetActive (false);
				break;
			}
		}
	}

	void UpdatePlayerSpeedUpButton()
	{
		if (PlayerSettings.Instance().IsMaxSpeed) {
			imageSpeedUpValue.sprite = levelMax;
			buttonSpeedUp.gameObject.SetActive (false);

		} else {
			buttonSpeedUp.gameObject.SetActive (true);
			switch (PlayerSettings.Instance ().OriginalSpeed) {
			case 0:
				imageSpeedUpValue.sprite = level1;
				textSpeedUpPrice.text = "2000";
				break;
			case 1:
				imageSpeedUpValue.sprite = level2;
				textSpeedUpPrice.text = "3000";
				break;
			case 2:
				imageSpeedUpValue.sprite = level3;
				textSpeedUpPrice.text = "6000";
				break;
			case 3:
			default:
				imageSpeedUpValue.sprite = levelMax;
				buttonSpeedUp.gameObject.SetActive (false);
				break;
			}
		}
	}

	void UpdatePlayerSubscribeButton() {

		updateSubscribeButton(
			isActiveSubGold1Button, 
			buttonSubGold1, 
			buttonSubGold1Text);

		updateSubscribeButton(
			isActiveSubGold2Button, 
			buttonSubGold2, 
			buttonSubGold2Text);

		updateSubscribeButton(
			isActiveSubSpeed1Button, 
			buttonSubSpeed1, 
			buttonSubSpeed1Text);

		updateSubscribeButton(
			isActiveSubSpeed2Button, 
			buttonSubSpeed2, 
			buttonSubSpeed2Text);

		updateSubscribeButton(
			isActiveSubSuperSuitButton, 
			buttonSubSuperSuit, 
			buttonSubSuperSuitText);

		updateSubscribeButton(
			isActiveSubDevilSuitButton, 
			buttonSubDevilSuit,
			buttonSubDevilSuitText);
	}

	private void updateSubscribeButton(SubscriptionState state, Button bg, Image text)
	{
		switch(state) {
			case SubscriptionState.SUBSCRIBE:
				bg.GetComponent<Image>().sprite = subscribeBg;
				text.sprite = subscribe;
				break;

			case SubscriptionState.SUBSCRIBED:
				bg.GetComponent<Image>().sprite = subscribedBg;
				text.sprite = subscribed;
				break;

			case SubscriptionState.RESERVED:
				bg.GetComponent<Image>().sprite = reservedBg;
				text.sprite = reserved;
				break;
		}
	}


	/* 소프트 커런시 아이템 구매 */
	public void onPlayerHealthUpButton()
	{
		Debug.Log("onPlayerHealthUpButton");

		UpdatePlayerHealthUpButton();

		if (PlayerSettings.Instance().IsMaxHealth) {
			popup.show(SBSLocalization.PopupKey.PURCHASE_FAIL_MAX_HP, null, null, new string[] {"OK"}, null);
		} else {
			inProgressing = true;
			GameConnect.shared.AccountPurchaseItem("health", 1, onGameConnectAccountPurchaseItem);
		}
	}


	/* 소프트 커런시 아이템 구매 */
	public void onPlayerSpeedUpButton()
	{
		Debug.Log("onPlayerSpeedUpButton");

		UpdatePlayerSpeedUpButton();

		if (PlayerSettings.Instance().IsMaxSpeed) {
			popup.show(SBSLocalization.PopupKey.PURCHASE_FAIL_MAX_SPEED, null, null, new string[] {"OK"}, null);

		} else {
			inProgressing = true;
			GameConnect.shared.AccountPurchaseItem("speed", 1, onGameConnectAccountPurchaseItem);
		}
	}


	/* 하드 커런시 아이템 구매 */
	public void onItem01Button()
	{
		onItemButton(HIVEManager.item1Index);
	}

	/* 하드 커런시 아이템 구매 */
	public void onItem02Button()
	{
		onItemButton(HIVEManager.item2Index);
	}

	/* 하드 커런시 아이템 구매 */
	public void onItem03Button()
	{
		onItemButton(HIVEManager.item3Index);
	}

	/* 하드 커런시 아이템 구매 */
	public void onItem04Button()
	{
		onItemButton(HIVEManager.item4Index);
	}

	public void onSubGold1Button()
	{
		onSubscriptionItemButton(textSubGold1Price.text, HIVEManager.subGold1Index, HIVEManager.subGold2Index);
	}

	public void onSubGold2Button()
	{
		onSubscriptionItemButton(textSubGold2Price.text, HIVEManager.subGold2Index, HIVEManager.subGold1Index);
	}

	public void onSubSpeed1Button()
	{
		onSubscriptionItemButton(textSubSpeed1Price.text, HIVEManager.subSpeed1Index, HIVEManager.subSpeed2Index);
	}

	public void onSubSpeed2Button()
	{
		onSubscriptionItemButton(textSubSpeed2Price.text, HIVEManager.subSpeed2Index, HIVEManager.subSpeed1Index);
	}

	public void onSubSuperSuitButton()
	{
		onSubscriptionItemButton(textSubSuperSuitPrice.text, HIVEManager.subSuperSuitIndex, HIVEManager.subDevilSuitIndex);
	}

	public void onSubDevilSuitButton()
	{
		onSubscriptionItemButton(textSubDevilSuitPrice.text, HIVEManager.subDevilSuitIndex, HIVEManager.subSuperSuitIndex);
	}

	void onItemButton(int index)
	{
		if (!inProgressing) {
			inProgressing = true;

			GameConnect.shared.AccountGetItems((int errorCode, string message, List<Item> items, List<GameNetwork.Subscription> subscriptions) => {

				if (errorCode == 102) {
					inProgressing = false;

					popup.show(SBSLocalization.PopupKey.ACCOUNT_SESSION_INVALID, message, null, new string[] {"OK"}, (i) => {
						inProgressing = false;
						PlayerSettings.Instance ().reset ();
						homeManager.IsGameSignIn = false;
						homeManager.onShopClick(false);
					});
				
				} else {
					string marketPid = HIVEManager.shared.productList[index].marketPid;
					HIVEManager.shared.shopPurchase(marketPid, onHIVEManagerPurchase);
				}
			});
		} else {
			toast.show ("In Progressing...");
		}
	}

	void onSubscriptionItemButton(string priceText, int index, int oldIndex)
	{
		if (!inProgressing) {
			inProgressing = true;

			GameConnect.shared.AccountGetItems((int errCode, string message, List<Item> items, List<GameNetwork.Subscription> subscriptions) => {

				if (errCode == 0) {
					setAccountItems (items);
					setAccountSubscriptionItems (subscriptions);
					updatePlayerUiInfo(null);
					
					string marketPid = HIVEManager.shared.subscriptionProductList[index].marketPid;
					string oldMarketPid = HIVEManager.shared.subscriptionProductList[oldIndex].marketPid;

					bool isExistOld = false;
					
					bool showPopup = false;
					SBSLocalization.PopupKey popupKey = SBSLocalization.PopupKey.UNKNOWN_ERROR;
					string errorCode = null;
					string[] buttons = {"OK"};

					if (PlayerSettings.Instance().Subscriptions != null) {
						foreach (GameNetwork.Subscription sub in PlayerSettings.Instance().Subscriptions) {
							if (string.Equals(oldMarketPid, sub.productId)) {
								isExistOld = true;
								
								#if UNITY_ANDROID
								if (sub.marketId == 1) {
									showPopup = true;
									popupKey = SBSLocalization.PopupKey.SUBSCRIPED_OTHER_MARKET;
									break;
								}
								#elif UNITY_IOS
								if (sub.marketId == 2) {
									showPopup = true;
									popupKey = SBSLocalization.PopupKey.SUBSCRIPED_OTHER_MARKET;
									break;
								}
								#endif
							}

							if (string.Equals(marketPid, sub.productId)) {
								showPopup = true;
								popupKey = SBSLocalization.PopupKey.SUBSCRIPED;
								break;
							}

							if (string.Equals(marketPid, sub.nextProductId)) {
								showPopup = true;
								popupKey = SBSLocalization.PopupKey.SUBSCRIPED;
								break;
							}
						}
					}

					foreach(string subscribedPid in localSubscribedPidList.Keys) {
						if (string.Equals(marketPid, subscribedPid) || string.Equals(oldMarketPid, subscribedPid)) {
							if (localSubscribedPidList[subscribedPid] != AuthV4.getPlayerInfo().playerId) {
								showPopup = true;
								popupKey = SBSLocalization.PopupKey.SUBSCRIPTION_NOT_OWNED;
								errorCode = localSubscribedPidList[subscribedPid].ToString();
								break;
							}
						}
					}

					if (!isExistOld) oldMarketPid = "";

					if (showPopup) {
						inProgressing = false;
						popup.show(popupKey, errorCode, null, buttons, null);
						
					} else {
						inProgressing = false;
						popupSubscriptionInfo.show(priceText, (bool isPastive) => {
							if (isPastive) {
								if (isExistOld) {
									popup.show(SBSLocalization.PopupKey.SUBSCRIPTION_CHANGE, null, null, new string[] {"Cancel", "OK"},
										(int idx) => {
											if (idx == 1) {
												inProgressing = true;
												HIVEManager.shared.shopSubscriptionPurchase(marketPid, oldMarketPid, onHIVEManagerSubscriptionPurchase);
											} else {
											}
										}
									);

								} else {
									inProgressing = true;
									HIVEManager.shared.shopSubscriptionPurchase(marketPid, oldMarketPid, onHIVEManagerSubscriptionPurchase);
								}
							}
						});
					}

				} else {
					inProgressing = false;
					
					popup.show(SBSLocalization.PopupKey.ACCOUNT_SESSION_INVALID, message, null, new string[] {"OK"}, (i) => {
						inProgressing = false;
						PlayerSettings.Instance ().reset ();
						homeManager.IsGameSignIn = false;
						homeManager.onShopClick(false);
					});
				}
			});

		} else {
			toast.show ("In Progressing...");
		}
	}

	public void onRestore()
	{
		if (!inProgressing) {
			inProgressing = true;
			HIVEManager.shared.shopRestore(onHIVEManagerRestore);

		} else {
			toast.show ("In Progressing...");
		}
	}


	//====================================
	//	HIVEManager 콜백 핸들러
	//====================================
	void onHIVEManagerShopSetup(bool success, string message)
	{
		if (success == true) {
			List<IAPV4.IAPV4Product> productList = HIVEManager.shared.productList;
			List<IAPV4.IAPV4Product> subscriptionList = HIVEManager.shared.subscriptionProductList;

			if (productList != null) {
				setItemList(productList);
			}

			if (subscriptionList != null) {
				setSubscriptionItemList(subscriptionList);
			}

			if (isSetup == false) {
				HIVEManager.shared.shopRestoreSubscription((bool shopRestoreIsSuccess, string shopRestoreMessage, List<IAPV4.IAPV4Receipt> iapV4ReceiptList) => {
					isSetup = shopRestoreIsSuccess;
					if (shopRestoreIsSuccess && iapV4ReceiptList != null && iapV4ReceiptList.Count > 0) {
						int requestCnt = iapV4ReceiptList.Count;
						foreach (IAPV4.IAPV4Receipt receipt in iapV4ReceiptList) {
							GameConnect.shared.VerifyReceiptSubscription(receipt, (bool verifyReceiptSuccess, string verifyReceiptMessage, string pid, long ownedPlayerId) => {
								if (verifyReceiptSuccess && pid != null && ownedPlayerId != -1) {
									if (localSubscribedPidList.ContainsKey(pid)) {
										localSubscribedPidList.Remove(pid);
									}
									localSubscribedPidList.Add(pid, ownedPlayerId);
								}
								
								if (--requestCnt <= 0) {
									GameConnect.shared.AccountGetItems(onGameConnectAccountGetItems);
								}
							});

							HIVEManager.shared.shopTransactionFinish(receipt.product.marketPid, onHIVEManagerTransactionFinish);
						}

					} else {
						inProgressing = false;
						GameConnect.shared.AccountGetItems(onGameConnectAccountGetItems);
					}
				});
				
			} else {
				inProgressing = false;
				GameConnect.shared.AccountGetItems(onGameConnectAccountGetItems);
			}

		} else {
			inProgressing = false;

			if (message != "INPROGRESS") {
				#if UNITY_ANDROID
				popup.show(SBSLocalization.PopupKey.UNKNOWN_ERROR, "Check Google Account", null, new string[] {"OK"} , null);
				#elif UNITY_IOS
				popup.show(SBSLocalization.PopupKey.UNKNOWN_ERROR, "Check iTunes Account", null, new string[] {"OK"} , null);
				#endif
			}
		}
	}

	void onHIVEManagerPurchase(bool isSuccess, string msg, IAPV4.IAPV4Receipt iapV4Receipt)
	{
		if (isSuccess) {
			GameConnect.shared.VerifyReceipt(iapV4Receipt, (bool success, string message, string pid) => {
				if (success) {
					HIVEManager.shared.shopTransactionFinish(pid, onHIVEManagerTransactionFinish);
				}
				verifyReceiptResult(SBSLocalization.PopupKey.PURCHASE_IAP_SUCCESS, success, message, pid);
			});
		} else {
			inProgressing = false;
			popup.show(SBSLocalization.PopupKey.PURCHASE_FAIL, msg, null, new string[] {"OK"}, null);
		}
	}


	void onHIVEManagerSubscriptionPurchase(bool isSuccess, string msg, IAPV4.IAPV4Receipt iapV4Receipt)
	{
		if (isSuccess) {
			GameConnect.shared.VerifyReceiptSubscription(iapV4Receipt, (bool success, string message, string pid, long ownedPlayerId) => {
				if (success) {
					if (pid != null && ownedPlayerId != -1) {
						if (localSubscribedPidList.ContainsKey(pid)) {
							localSubscribedPidList.Remove(pid);
						}
						localSubscribedPidList.Add(pid, ownedPlayerId);
					}
				}
				verifyReceiptResult(SBSLocalization.PopupKey.PURCHASE_SUCCESS, success, message, pid);
			});

			HIVEManager.shared.shopTransactionFinish(iapV4Receipt.product.marketPid, onHIVEManagerTransactionFinish);

		} else {
			inProgressing = false;
			popup.show(SBSLocalization.PopupKey.PURCHASE_FAIL, msg, null, new string[] {"OK"}, null);
		}
	}


	// 적절한 시점에 자동으로 해주어도 상관은 없으나 마켓 연결 여부와, 아이템 지급이 가능한 시점,
	// 결제 도중에 중복으로 호출되지 않도록 주의 한다.
	// NOT_OWNED 는 요청에는 성공했으나 복구할 아이템은 없다는 뜻이다. 일반적으로 대부분 이 경우에 해당.
	void onHIVEManagerRestore(bool isRestoreSuccess, string restoreMsg, List<IAPV4.IAPV4Receipt> iapV4RestoreReceiptList)
	{
		if (isRestoreSuccess == true && iapV4RestoreReceiptList != null) {
			foreach (IAPV4.IAPV4Receipt restoreReceipt in iapV4RestoreReceiptList) {
				GameConnect.shared.VerifyReceipt(restoreReceipt, (bool consumerbleSuccess, string consumerbleMessage, string consumerblePid) => {
					if (consumerbleSuccess) {
						HIVEManager.shared.shopTransactionFinish(consumerblePid, onHIVEManagerTransactionFinish);
					}
				});
			}
		}

		// 결과 처리는 RestoreSubscription 에서
		HIVEManager.shared.shopRestoreSubscription((bool isRestoreSubsSuccess, string restoreSubsMsg, List<IAPV4.IAPV4Receipt> iapV4RestoreSubsReceiptList) => {

			if (isRestoreSubsSuccess == true && iapV4RestoreSubsReceiptList != null && iapV4RestoreSubsReceiptList.Count > 0) {

				bool successResult = false;
				bool isOwned = false;
				int requestCnt = iapV4RestoreSubsReceiptList.Count;
				localSubscribedPidList.Clear();

				foreach (IAPV4.IAPV4Receipt restoreSubsReceipt in iapV4RestoreSubsReceiptList) {
					GameConnect.shared.VerifyReceiptSubscription(restoreSubsReceipt, (bool subsSuccess, string subsMessage, string subsPid, long ownedPlayerId) => {

						if (subsSuccess) {
							successResult = true;
							if (subsPid != null && ownedPlayerId != -1) {
								if (localSubscribedPidList.ContainsKey(subsPid)) {
									localSubscribedPidList.Remove(subsPid);
								}
								localSubscribedPidList.Add(subsPid, ownedPlayerId);

								if (ownedPlayerId == AuthV4.getPlayerInfo().playerId) {
									isOwned = true;
								}
							}
						}

						if (--requestCnt <= 0) {
							verifyReceiptResult(isOwned ? SBSLocalization.PopupKey.RESTORE_IAP_SUCCESS : SBSLocalization.PopupKey.RESTORE_IAP_SUCCESS_NOT_OWNED, successResult, subsMessage, subsPid);
						}
					});

					HIVEManager.shared.shopTransactionFinish(restoreSubsReceipt.product.marketPid, onHIVEManagerTransactionFinish);
				}

			} else if (isRestoreSuccess && iapV4RestoreReceiptList != null && iapV4RestoreReceiptList.Count > 0) {
				inProgressing = false;
				popup.show(SBSLocalization.PopupKey.RESTORE_IAP_SUCCESS, restoreMsg, null, new string[] {"OK"}, null);

			} else {
				inProgressing = false;

				if (isRestoreSuccess && isRestoreSubsSuccess) {
					localSubscribedPidList.Clear();
					popup.show(SBSLocalization.PopupKey.RESTORE_IAP_SUCCESS_NOT_OWNED, restoreSubsMsg, null, new string[] {"OK"}, null);

				} else {
					string popupMsg = isRestoreSuccess ? restoreSubsMsg : restoreMsg;
					popup.show(SBSLocalization.PopupKey.RESTORE_FAIL, popupMsg, null, new string[] {"OK"}, null);
				} 
			}

		});
	}


	void onHIVEManagerTransactionFinish(bool success, string message)
	{
		// no operation.
	}

	//====================================
	//	GameConnect 콜백 핸들러
	//====================================
	void onGameConnectAccountGetItems(int errorCode, string message, List<Item> items, List<GameNetwork.Subscription> subscriptions)
	{
		inProgressing = false;
		
		if (errorCode == 0) {
			setAccountItems (items);
			setAccountSubscriptionItems (subscriptions);
			updatePlayerUiInfo(null);

		} else if (errorCode == 102) {
			popup.show(SBSLocalization.PopupKey.ACCOUNT_SESSION_INVALID, message, null, new string[] {"OK"}, (index) => {
				inProgressing = false;
				PlayerSettings.Instance ().reset ();
				homeManager.IsGameSignIn = false;
				homeManager.onShopClick(false);
			});
		
		} else {
			updatePlayerUiInfo("Server Error. Please try again later.");	
		}
	}

	void onGameConnectAccountPurchaseItem(int errorCode, string message, List<Item> items, List<GameNetwork.Subscription> subscriptions)
	{
		inProgressing = false;

		if (errorCode == 0) {
			if (items != null) {
				setAccountItems (items);
				updatePlayerUiInfo(null);
			}

			popup.show(SBSLocalization.PopupKey.PURCHASE_SUCCESS, message, null, new string[] {"OK"}, null);

		} else if (errorCode == 102) {
			popup.show(SBSLocalization.PopupKey.ACCOUNT_SESSION_INVALID, message, null, new string[] {"OK"}, (index) => {
				inProgressing = false;
				PlayerSettings.Instance ().reset ();
				homeManager.IsGameSignIn = false;
				homeManager.onShopClick(false);
			});

		} else {
			if (string.IsNullOrEmpty(message)) {
				popup.show(SBSLocalization.PopupKey.SERVER_CONNECT_FAIL, message, null, new string[] {"OK"}, null);
			} else {
				popup.show(SBSLocalization.PopupKey.PURCHASE_FAIL, message, null, new string[] {"OK"}, null);
			}
		}
	}

	private void verifyReceiptResult(SBSLocalization.PopupKey key, bool success, string message, string pid) {
		Debug.Log("VerifyReceiptSubscription");

		inProgressing = false;
		GameConnect.shared.AccountGetItems(onGameConnectAccountGetItems);
		if (success == true) {
			popup.show(key, null, null, new string[] {"OK"}, null);
		} else {
			if (string.IsNullOrEmpty(message)) {
				popup.show(SBSLocalization.PopupKey.SERVER_CONNECT_FAIL, message, null, new string[] {"OK"}, null);
			} else {
				popup.show(SBSLocalization.PopupKey.INVALID_RECEIPT, message, null, new string[] {"OK"}, null);
			}
		}
	}

}
