package com.stove.unity

import androidx.annotation.Keep
import com.stove.base.json.putIgnoreException
import com.stove.base.log.Logger
import com.stove.log.Log
import com.stove.log.LogEvent
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
import com.stove.log.game.GameLog
import com.stove.log.game.domain.GameLogEvent
import com.stove.base.result.Result
import com.stove.base.result.Result.Companion.CanceledResult

@Keep
object LogWrapper {
    private const val TAG = "LogWrapper"
    private const val objectName = "StoveSDK"
    private const val functionName = "CallMessage"
    private const val IdentifierKey = "identifier"
    private const val ValueKey = "value"
    private const val ResultKey = "result"

    @JvmStatic
    fun add(logEventString: String, identifier: String) {
        val context = UnityPlayer.currentActivity.applicationContext
        val logEvent = LogEvent.from(logEventString)
        if (logEvent == null) {
            Logger.trace(
                LogLevel.ERROR,
                "$TAG.add",
                logTagList("logEvent is null")
            )
            return
        }
        Log.add(context, logEvent) { 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 flush() {
        val context = UnityPlayer.currentActivity.applicationContext
        Log.flush(context)
    }

    @JvmStatic
    fun getVersion(): String? {

        val version : String? = com.stove.log.BuildConfig.VERSION_NAME
        return version
    }

    @JvmStatic
    fun getSDKVersions(): String? {
        val context = UnityPlayer.currentActivity.applicationContext
        val jsonObject = Log.getSDKVersions(context)
        val version = jsonObject.toString()

        return version
    }

    @JvmStatic
    fun setExternalId(externalId: String) {
        Log.setExternalId(externalId)
    }

    @JvmStatic
    fun addGameLog(logEventString: String, identifier: String) {
        val context = UnityPlayer.currentActivity.applicationContext
        val logEvent = GameLogEvent.from(logEventString)
        if (logEvent == null) {
            Logger.trace(LogLevel.ERROR, TAG, logTagList("GameLog"), mapOf("error" to "Failed to parse GameLogEvent from JSON"))
            sendResult(identifier, CanceledResult)
            return
        }
        GameLog.add(context, logEvent) { result ->
            sendResult(identifier, result)
        }
    }

    private fun sendResult(identifier: String, result: Result) {
        val valueJSONObject = JSONObject().apply {
            putIgnoreException(ResultKey, result.toJSONObject())
        }
        val jsonObject = JSONObject().apply {
            putIgnoreException(IdentifierKey, identifier)
            putIgnoreException(ValueKey, valueJSONObject)
        }
        UnityPlayer.UnitySendMessage(objectName, functionName, jsonObject.toString())
    }
    
    @JvmStatic
    fun flushGameLog() {
        val context = UnityPlayer.currentActivity.applicationContext
        GameLog.flush(context)
    }
}