package com.stove.unity

import androidx.annotation.Keep
import com.stove.base.json.putIgnoreException
import com.stove.base.log.Logger
import com.stove.base.result.Result
import com.stove.push.Push
import com.stove.push.PushSettings
import com.unity3d.player.UnityPlayer
import org.json.JSONObject
import com.stove.base.log.model.LogLevel
import com.stove.base.log.model.LogTag
import com.stove.base.log.model.logTagList

@Keep
object PushWrapper {
    private const val TAG = "PushWrapper"
    private const val objectName = "StoveSDK"
    private const val functionName = "CallMessage"
    private const val notifyFunctionName = "NotifyMessage"
    private const val IdentifierKey = "identifier"
    private const val ValueKey = "value"
    private const val ResultKey = "result"
    private const val MessageKey = "message"
    private const val PushSettingsKey = "pushSettings"
    private const val TokenKey = "token"

    @JvmStatic
    fun fetchToken(identifier: String) {
        val context = UnityPlayer.currentActivity.applicationContext
        Push.fetchToken(context) { result: Result, token: String? ->
            val jsonObject = JSONObject()
            jsonObject.putIgnoreException(IdentifierKey, identifier)
            val valueJSONObject = JSONObject()
            valueJSONObject.putIgnoreException(ResultKey, result.toJSONObject())
            valueJSONObject.putIgnoreException(TokenKey, token)
            jsonObject.putIgnoreException(ValueKey, valueJSONObject)
            val params = jsonObject.toString()
            UnityPlayer.UnitySendMessage(objectName, functionName, params)
        }
    }

    @JvmStatic
    fun registerPush(token: String, identifier: String) {
        val context = UnityPlayer.currentActivity.applicationContext
        Push.registerPush(context, token) { result ->
            val jsonObject = JSONObject()
            jsonObject.putIgnoreException(IdentifierKey, identifier)
            val valueJSONObject = JSONObject()
            valueJSONObject.putIgnoreException(ResultKey, result.toJSONObject())
            jsonObject.putIgnoreException(ValueKey, valueJSONObject)
            val params = jsonObject.toString()
            UnityPlayer.UnitySendMessage(objectName, functionName, params)
        }
    }

    @JvmStatic
    fun fetchPushSettings(identifier: String) {
        val context = UnityPlayer.currentActivity.applicationContext
        Push.fetchPushSettings(context) { result, pushSettings ->
            val jsonObject = JSONObject()
            jsonObject.putIgnoreException(IdentifierKey, identifier)
            val valueJSONObject = JSONObject()
            valueJSONObject.putIgnoreException(ResultKey, result.toJSONObject())
            valueJSONObject.putIgnoreException(PushSettingsKey, pushSettings?.toJSONObject())
            jsonObject.putIgnoreException(ValueKey, valueJSONObject)
            val params = jsonObject.toString()
            UnityPlayer.UnitySendMessage(objectName, functionName, params)
        }
    }

    @JvmStatic
    fun updatePushSettings(pushSettingsString: String, identifier: String) {
        val settings = PushSettings.from(pushSettingsString)
        if (settings == null) {
            Logger.trace(
                LogLevel.ERROR,
                "$TAG.updatePushSettings",
                logTagList("pushSettings is null")
            )
            return
        }
        val context = UnityPlayer.currentActivity.applicationContext
        Push.updatePushSettings(context, settings) { result, pushSettings ->
            val jsonObject = JSONObject()
            jsonObject.putIgnoreException(IdentifierKey, identifier)
            val valueJSONObject = JSONObject()
            valueJSONObject.putIgnoreException(ResultKey, result.toJSONObject())
            valueJSONObject.putIgnoreException(PushSettingsKey, pushSettings?.toJSONObject())
            jsonObject.putIgnoreException(ValueKey, valueJSONObject)
            val params = jsonObject.toString()
            UnityPlayer.UnitySendMessage(objectName, functionName, params)
        }
    }

    @JvmStatic
    fun setMessageDelegate(identifier: String) {
        val context = UnityPlayer.currentActivity.applicationContext
        Push.setMessageListener(context) { map ->
            val jsonObject = JSONObject()
            jsonObject.putIgnoreException(IdentifierKey, identifier)
            val valueJSONObject = JSONObject()
            valueJSONObject.putIgnoreException(MessageKey, convert(map))
            jsonObject.putIgnoreException(ValueKey, valueJSONObject)
            val params = jsonObject.toString()
            UnityPlayer.UnitySendMessage(objectName, notifyFunctionName, params)
        }
    }

    private fun convert(map: Map<String, String>): JSONObject {
        val jsonObject = JSONObject()
        map.forEach {
            jsonObject.putIgnoreException(it.key, it.value)
        }
        return jsonObject
    }

    @JvmStatic
    fun getVersion(): String? {
        val version : String? = com.stove.push.BuildConfig.VERSION_NAME
        return version
    }
}