﻿#if UNITY_ANDROID
namespace Stove.StoveSDK.IAP.Google
{
    using System;
    using System.Collections.Generic;
    using UnityEngine;

    public class IAP : IIAP
    {
        static AndroidJavaObject wrapper = new AndroidJavaObject("com.stove.unity.IAPGoogleWrapper");

        public static void SetCustomBillingGUID(string userId)
        {
            Debug.Log("IAP.SetCustomBillingGUID");
            wrapper.CallStatic("setCustomBillingGUID", userId);
        }

        public static void Initialize(Action<Result> action)
        {
            Debug.Log("IAP.Initialize");
            string identifier = StoveSDK.Instance.AddAction(payload =>
            {
                Result result = new Result(payload["result"] as Dictionary<string, object>);
                Debug.Log("IAP.Initialize Result : " + result);
                action.Invoke(result);
            });
            wrapper.CallStatic("initialize", identifier);
        }

        public static void Initialize(bool isCustomGuid, Action<Result> action)
        {
            Debug.Log("IAP.Initialize");
            string identifier = StoveSDK.Instance.AddAction(payload =>
            {
                Result result = new Result(payload["result"] as Dictionary<string, object>);
                Debug.Log("IAP.Initialize Result : " + result);
                action.Invoke(result);
            });
            wrapper.CallStatic("initialize", isCustomGuid, identifier);
        }

        public static void FetchProducts(Action<Result, List<IAPProduct>> action)
        {
            Debug.Log("IAP.FetchProducts");
            string identifier = StoveSDK.Instance.AddAction(payload =>
            {
                Result result = new Result(payload["result"] as Dictionary<string, object>);
                
                List<IAPProduct> products = new List<IAPProduct>();
                if (result.IsSuccessful)
                {
                    List<object> productsObject = payload["productList"] as List<object>;

                    foreach (object productObject in productsObject)
                    {
                        IAPProduct product = new IAPProduct(productObject as Dictionary<string, object>);
                        products.Add(product);
                    }
                }

                Debug.Log("IAP.FetchProducts Result : " + result);
                Debug.Log("IAP.FetchProducts Products : " + products);

                action.Invoke(result, products);
            });
            wrapper.CallStatic("fetchProducts", identifier);
        }

        public static void StartPurchase(IAPProduct product, Action<Result> action)
        {
            Debug.Log("IAP.StartPurchase");
            string identifier = StoveSDK.Instance.AddAction(payload =>
            {
                Result result = new Result(payload["result"] as Dictionary<string, object>);
                Debug.Log("IAP.StartPurchase Result : " + result);
                action.Invoke(result);
            });
            wrapper.CallStatic("startPurchase", product.ToJSONString(), identifier);
        }

        public static void StartPurchase(IAPProduct product, string serviceOrderId, IAPOptional optional, Action<Result> action)
        {
            Debug.Log("IAP.StartPurchase");
            string identifier = StoveSDK.Instance.AddAction(payload =>
            {
                Result result = new Result(payload["result"] as Dictionary<string, object>);
                Debug.Log("IAP.StartPurchase Result : " + result);
                action.Invoke(result);
            });
            string iapOptionalString = null;
            if(optional != null)
            {
                iapOptionalString = optional.ToJSONString();
            }
            wrapper.CallStatic("startPurchaseWithOption", product.ToJSONString(), serviceOrderId, iapOptionalString, identifier);
        }

        public static void SetListener(Action<Result, IAPProduct, IAPPurchaseDetail> action)
        {
            Debug.Log("IAP.SetListener");
            string identifier = StoveSDK.Instance.AddAction(payload =>
            {
                Result result = new Result(payload["result"] as Dictionary<string, object>);
                IAPProduct product = null;
                if (payload.ContainsKey("product"))
                {
                    product = new IAPProduct(payload["product"] as Dictionary<string, object>);
                }
                IAPPurchaseDetail purchaseDetail = null;
                if (payload.ContainsKey("purchaseDetail"))
                {
                    purchaseDetail = new IAPPurchaseDetail(payload["purchaseDetail"] as Dictionary<string, object>);

                }
                Debug.Log("IAP.SetListener Result : " + result);
                Debug.Log("IAP.SetListener product : " + product);
                Debug.Log("IAP.SetListener purchaseDetail : " + purchaseDetail);

                action.Invoke(result, product, purchaseDetail);
            });
            wrapper.CallStatic("setListener", identifier);
        }

        public static bool Flush()
        {
            Debug.Log("IAP.Flush");
            bool result = wrapper.CallStatic<bool>("flush");
            Debug.Log("IAP.Flush Result : " + result);
            return true;
        }

        public static void Consume(IAPProduct product, Action<Result> action)
        {
            Debug.Log("IAP.Consume");
            string identifier = StoveSDK.Instance.AddAction(payload =>
            {
                Result result = new Result(payload["result"] as Dictionary<string, object>);
                Debug.Log("IAP.Consume Result : " + result);
                action.Invoke(result);
            });
            wrapper.CallStatic("consume", product.ToJSONString(), identifier);
        }

        public static void FetchVoidedPurchases(Action<Result, List<Dictionary<string, object>>> action)
        {
            Debug.Log("IAP.FetchVoidedPurchases");
            string identifier = StoveSDK.Instance.AddAction(payload =>
            {
                Result result = new Result(payload["result"] as Dictionary<string, object>);
                
                List<Dictionary<string, object>> voidedPurchases = new List<Dictionary<string, object>>();
                if (result.IsSuccessful)
                {
                    List<object> voidedPurchasesObject = payload["voidedPurchases"] as List<object>;

                    foreach (object voidedPurchaseObject in voidedPurchasesObject)
                    {
                        voidedPurchases.Add(voidedPurchaseObject as Dictionary<string, object>);
                    }
                }

                Debug.Log("IAP.FetchVoidedPurchases Result : " + result);
                Debug.Log("IAP.FetchVoidedPurchases VoidedPurchases : " + voidedPurchases);

                action.Invoke(result, voidedPurchases);
            });
            wrapper.CallStatic("fetchVoidedPurchases", identifier);
        }
   
        public static void HandleVoidedPurchases(Action<Result> action)
        {
            Debug.Log("IAP.HandleVoidedPurchases");
            string identifier = StoveSDK.Instance.AddAction(payload =>
            {
                Result result = new Result(payload["result"] as Dictionary<string, object>);
                Debug.Log("IAP.HandleVoidedPurchases Result : " + result);
                action.Invoke(result);
            });
            wrapper.CallStatic("handleVoidedPurchases", identifier);
        }

        void IIAP.SetCustomBillingGUID(string guid)
        {
            SetCustomBillingGUID(guid);
        }

        void IIAP.Initialize(Action<Result> action)
        {
            Initialize(action);
        }

        void IIAP.FetchProducts(Action<Result, List<IAPProduct>> action)
        {
            FetchProducts(action);
        }

        void IIAP.StartPurchase(IAPProduct product, Action<Result> action)
        {
            StartPurchase(product, action);
        }

        void IIAP.StartPurchase(IAPProduct product, string serviceOrderId, IAPOptional optional, Action<Result> action)
        {
            StartPurchase(product, serviceOrderId, optional, action);
        }

        bool IIAP.Flush()
        {
            return Flush();
        }

        void IIAP.Consume(IAPProduct product, Action<Result> action)
        {
            Consume(product, action);
        }

        void IIAP.FetchVoidedPurchases(Action<Result, List<Dictionary<string, object>>> action)
        {
            FetchVoidedPurchases(action);
        }

        void IIAP.HandleVoidedPurchases(Action<Result> action)
        {
            HandleVoidedPurchases(action);
        }

        void IIAP.SetListener(Action<Result, IAPProduct, IAPPurchaseDetail> action)
        {
            SetListener(action);
        }

        public static string GetVersion()
        {

            Debug.Log("GetVersion");

            string version = wrapper.CallStatic<string>("getVersion");

            Debug.Log("GetVersion return : " + version);

            return version;
        }
    }
}
#endif

