package com.platform101xp.plugin

// SDK 3.0.+
import android.util.Log
import com.platform101xp.authorize.account.Account
import com.platform101xp.authorize.social_networks.entities.Platform101XPSocialFriend
import com.platform101xp.authorize.token.Platform101XPToken
import com.platform101xp.base.error.Platform101XPError
import com.platform101xp.billing.dto.Platform101XPProduct
import com.platform101xp.billing.dto.Platform101XPPurchase
import com.platform101xp.billing.internal.InternalOrderStatus
import com.platform101xp.sdk.*
import org.json.JSONArray
import org.json.JSONObject

class Platform101XPEventListener(private val actionListener: Platform101XPUnityActionListener) :
        Platform101XPListener {

    companion object {
        const val LOG_TAG = "UnitySampleHelper"

        @JvmStatic
        fun tokenToJson(token: Platform101XPToken): JSONObject {
            val json = JSONObject()
            json.put("accessToken", token.accessToken)
            json.put("expires", token.expires)
            json.put("type", token.type)
            json.put("provider", token.provider)
            return json
        }

        @JvmStatic
        fun accountToJson(account: Account): JSONObject {
            val json = JSONObject()
            json.put("accountId", account.accountId)
            json.put("portalId", account.portalId)
            json.put("userGameId", account.userGameId)
            json.put("mobileId", account.mobileId)
            json.put("userName", account.userName)
            json.put("userPhotoUrl", account.userPhotoUrl)
            json.put("isGuest", account.isGuest)
            return json
        }        

        @JvmStatic
        fun productToJson(product: Platform101XPProduct): JSONObject {
            val json = JSONObject()
            json.put("productId", product.productId)
            json.put("productType", product.productType)
            json.put("price", product.getPrice())
            json.put("priceValue", product.priceValue)
            json.put("currencyCode", product.currencyCode)
            json.put("title", product.title)
            json.put("description", product.description)
            return json
        }
    }
    
    override fun onAuthorizeResult(token: Platform101XPToken?, error: Platform101XPError?) {
        try {
            val resultJson = JSONObject()
            if (error != null) {
                resultJson.put("error", error.toString())
            }

            if (token != null) {
                val tokenJson = tokenToJson(token)
                resultJson.put("token", tokenJson)
            }
            actionListener.onSendAction("OnAuthorizeResult", resultJson.toString())
        } catch (e: Exception) {
            Log.d(LOG_TAG, e.toString())
        }
    }

    override fun onInviteResult(error: Platform101XPError?) {
        try {
            val jsonResult = JSONObject()
            if (error != null) {
                jsonResult.put("error", error.toString())
            } else {
                jsonResult.put("invited", true)
            }
            actionListener.onSendAction("OnInviteResult", jsonResult.toString())
        } catch (e: Exception) {
            Log.d(LOG_TAG, e.toString())
        }
    }

    override fun onBillingInitializeResult(error: Platform101XPError?) {
        try {
            val jsonResult = JSONObject()
            if (error != null) {
                jsonResult.put("error", error.toString())
            } else {
                jsonResult.put("available", true)
            }
            actionListener.onSendAction("OnBillingInitializeResult", jsonResult.toString())
        } catch (e: Exception) {
            Log.d(LOG_TAG, e.toString())
        }
    }

    override fun onGetProductsResult(
        products: List<Platform101XPProduct>?,
        error: Platform101XPError?
    ) {
        try {
            val resultJson = JSONObject()

            if (error != null) {
                // Error case
                resultJson.put("error", error.toString())
            } else if (products != null) {
                // Success case
                val productsJson = JSONArray()
                for (product in products) {
                    // Use companion object helper
                    val productJson = productToJson(product)
                    productsJson.put(productJson)
                }

                resultJson.put("products", productsJson)

                // Restore purchased products
                Platform101XP.restoreProducts()
                Log.d(LOG_TAG, "ProductsJson: $resultJson")
            } else {
                // No error, no products – define some reasonable payload
                resultJson.put("products", JSONArray())
            }

            actionListener.onSendAction("OnGetProductsResult", resultJson.toString())
        } catch (e: Exception) {
            Log.d(LOG_TAG, e.toString())
        }
    }

    override fun onPurchaseProductResult(
            purchase: Platform101XPPurchase?,
            error: Platform101XPError?
    ) {
        try {
            val jsonResult = JSONObject()
            if (error != null) {
                jsonResult.put("error", error.toString())
            } else if (purchase != null) {
                jsonResult.put("orderId", purchase.orderId)
                jsonResult.put("packageName", purchase.packageName)
                jsonResult.put("productId", purchase.productId)
                jsonResult.put("token", purchase.token)
                jsonResult.put("transactionId", purchase.transactionId)
                jsonResult.put("signature", purchase.signature)
                jsonResult.put("originalJson", purchase.originalJson)
            }
            actionListener.onSendAction("OnPurchaseProductResult", jsonResult.toString())
        } catch (e: Exception) {
            Log.d(LOG_TAG, e.toString())
        }
    }

    override fun onFinishPurchaseResult(
            purchase: Platform101XPPurchase?,
            error: Platform101XPError?
    ) {
        try {
            val jsonResult = JSONObject()
            if (error != null) {
                jsonResult.put("error", error.toString())
            } else if (purchase != null) {
                jsonResult.put("orderId", purchase.orderId)
                jsonResult.put("packageName", purchase.packageName)
                jsonResult.put("productId", purchase.productId)
                jsonResult.put("token", purchase.token)
                jsonResult.put("transactionId", purchase.transactionId)
                jsonResult.put("signature", purchase.signature)
            }
            actionListener.onSendAction("OnFinishPurchaseResult", jsonResult.toString())
        } catch (e: Exception) {
            Log.d(LOG_TAG, e.toString())
        }
    }

    override fun onMessageReceived(message: Platform101XPMessage?) {
        try {
            val messageJson = JSONObject()
            if (message == null) {
                Log.d(LOG_TAG, "[101XP] Error: In the (fun onMessageReceived(message: Platform101XPMessage?)) fun, the message is null!")
            } else {
                messageJson.put("messageId", message.messageId)
                messageJson.put("messageBody", message.messageBody)
                messageJson.put("messageSentTime", message.messageSentTime)
                actionListener.onSendAction("OnMessageReceived", messageJson.toString())
            }
        } catch (e: Exception) {
            Log.d(LOG_TAG, e.toString())
        }
    }

    override fun onLogout() {
        actionListener.onSendAction("OnLogout", "")
    }

    override fun onRewardedInvite(referrer: String?) {
        referrer?.let {
            val jsonResult = JSONObject()
            jsonResult.put("referrer", it)
            actionListener.onSendAction("OnRewardedInvite", jsonResult.toString())
        }
    }

    override fun onRewardedInviteLinkSender(eventName: String?) {
        eventName?.let {
            val jsonResult = JSONObject()
            jsonResult.put("eventName", it)
            actionListener.onSendAction("OnRewardedInviteLinkSender", jsonResult.toString())
        }
    }

    override fun onRewardedInviteLinkRecipient(referrer: String?, eventName: String?): Boolean {
        val jsonResult = JSONObject()
        jsonResult.put("referrer", referrer)
        jsonResult.put("eventName", eventName)
        actionListener.onSendAction("OnRewardedInviteLinkRecipient", jsonResult.toString())
        return (referrer != null && eventName != null)
    }

    override fun onInitializeResult(error: Platform101XPError?) {
        try {
            val jsonResult = JSONObject()
            if (error != null) {
                jsonResult.put("error", error.toString())
            } else {
                jsonResult.put("initialized", true)
            }
            actionListener.onSendAction("OnInitializeResult", jsonResult.toString())
        } catch (e: Exception) {
            Log.d(LOG_TAG, e.toString())
        }
    }

    override fun onGetSocialFriendsResult(
            friendsList: List<Platform101XPSocialFriend>?,
            error: Platform101XPError?
    ) {
        var result = ""
        try {
            val jsonResult = JSONObject()
            if (error != null) {
                jsonResult.put("error", error.toString()).toString()
            } else if (friendsList != null) {
                val friendsListJson = JSONArray()
                for (friend in friendsList) {
                    val currentFriend = JSONObject()
                    currentFriend.put("level", friend.level)
                    currentFriend.put("mobileId", friend.mobileId)
                    currentFriend.put("name", friend.name)
                    currentFriend.put("pictureUrl", friend.pictureUrl)
                    currentFriend.put("socialNetId", friend.socialNetId)
                    friendsListJson.put(currentFriend)
                }
                jsonResult.put("friends", friendsListJson)
            } else {
                jsonResult.put("error", "The account argument is null!")
            }
            actionListener.onSendAction("OnGetSocialFriendsResult", jsonResult.toString())
        } catch (e: Exception) {
            Log.d(LOG_TAG, e.toString())
        }
    }

    override fun onGetAnalyticsConversionData(dataMap: Map<Any, Any>?) {
        try {
            val jsonData = JSONObject()
            if (dataMap != null) {
                for (entry in dataMap.entries) {
                    jsonData.put(entry.key.toString(), entry.value)
                }
            }
            actionListener.onSendAction("OnAnalyticsConversionData", jsonData.toString())
        } catch (e: Exception) {
            Log.d(LOG_TAG, e.toString())
        }
    }

    override fun onShowWebStoreResult(error: Platform101XPError?) {
        try {
            val jsonResult = JSONObject()
            if (error != null) {
                jsonResult.put("error", error.toString())
            } else {
                jsonResult.put("success", true)
            }
            actionListener.onSendAction("OnShowWebStoreResult", jsonResult.toString())
        } catch (e: Exception) {
            Log.d(LOG_TAG, e.toString())
        }
    }

    override fun onPurchaseProductInternalOrderResult(
            productId: String,
            status: InternalOrderStatus,
            error: Platform101XPError?
    ) {
        try {
            val jsonResult = JSONObject()
            if (error != null) {
                jsonResult.put("error", error.toString())
            } else {
                jsonResult.put("productId", productId)
                jsonResult.put("status", status?.ordinal)
            }
            actionListener.onSendAction(
                    "OnPurchaseProductInternalOrderResult",
                    jsonResult.toString()
            )
        } catch (e: Exception) {
            Log.d(LOG_TAG, e.toString())
        }
    }

    override fun onCheckMobilePurchase(
            itemName: String,
            bought: Boolean,
            error: Platform101XPError?
    ) {
        try {
            val jsonResult = JSONObject()
            if (error != null) {
                jsonResult.put("error", error.toString())
            } else {
                jsonResult.put("itemName", itemName)
                jsonResult.put("bought", bought)
            }
            actionListener.onSendAction("OnCheckMobilePurchase", jsonResult.toString())
        } catch (e: Exception) {
            Log.d(LOG_TAG, e.toString())
        }
    }

    override fun onGetAccountResult(account: Account?, error: Platform101XPError?) {
        try {
            val jsonResult = JSONObject()
            if (error != null) {
                jsonResult.put("error", error.toString())
            } else if (account != null) {
                val accountJson = accountToJson(account)
                jsonResult.put("account", accountJson)
            } else {
                jsonResult.put("error", "The account is null!")
            }
            actionListener.onSendAction("OnGetAccountResult", jsonResult.toString())
        } catch (e: Exception) {
            Log.d(LOG_TAG, e.toString())
        }
    }
}
