package com.tapjoy.easyapp

import android.app.Activity
import android.content.Context
import android.util.Log
import androidx.lifecycle.ViewModel
import com.unity3d.ads.IUnityAdsInitializationListener
import com.unity3d.ads.IUnityAdsLoadListener
import com.unity3d.ads.IUnityAdsShowListener
import com.unity3d.ads.UnityAds
import com.unity3d.ads.UnityAds.UnityAdsLoadError
import com.unity3d.ads.UnityAds.UnityAdsShowCompletionState
import com.unity3d.ads.UnityAds.UnityAdsShowError
import com.unity3d.ads.UnityAdsLoadOptions
import com.unity3d.ads.UnityAdsShowOptions
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import java.util.UUID

const val PREF_AD_UNIT_ID_KEY = "adUnitIdKey"
const val PREF_GAME_ID_KEY = "gameIdKey"
const val PREF_TEST_MODE_KEY = "testModeKey"
const val PREF_DEBUG_MODE_KEY = "debugModeKey"
const val DEFAULT_GAME_ID = "14851"
const val DEFAULT_AD_UNIT_ID = "video"
const val DEFAULT_TEST_MODE = false

class UnityAdsViewModel : ViewModel() {

    private val _statusMessage = MutableStateFlow(if (UnityAds.isInitialized) "Unity SDK connected" else "Unity SDK not connected")
    private val _isConnected = MutableStateFlow(UnityAds.isInitialized)
    private val _isLoaded = MutableStateFlow(false)
    val statusMessage = _statusMessage.asStateFlow()
    val isConnected = _isConnected.asStateFlow()
    val isLoaded = _isLoaded.asStateFlow()

    private val objectIdMap = hashMapOf<String, String>()

    fun connect(context: Context, gameId: String, isTestMode: Boolean) {
        UnityAds.initialize(
            context,
            gameId,
            isTestMode,
            object : IUnityAdsInitializationListener {
                override fun onInitializationComplete() {
                    setStatusMessage("Unity SDK connected")
                    _isConnected.value = true
                }

                override fun onInitializationFailed(error: UnityAds.UnityAdsInitializationError, message: String) {
                    setStatusMessage("Unity init failed with error: [$error] $message")
                    _isConnected.value = false
                }
            },
        )
    }

    fun load(adUnitId: String) {
        val objectId = UUID.randomUUID().toString()
        objectIdMap[adUnitId] = objectId
        val loadOptions = UnityAdsLoadOptions()
        loadOptions.objectId = objectId

        UnityAds.load(
            adUnitId,
            loadOptions,
            object : IUnityAdsLoadListener {
                override fun onUnityAdsAdLoaded(placementId: String) {
                    setStatusMessage("Unity Ad Loaded")
                    _isLoaded.value = true
                }

                override fun onUnityAdsFailedToLoad(placementId: String, error: UnityAdsLoadError, message: String) {
                    setStatusMessage("Unity Ads failed to load ad for $placementId with error: [$error] $message")
                    _isLoaded.value = false
                }
            },
        )
    }

    fun show(activity: Activity, adUnitId: String) {
        val unityAdsShowOptions = UnityAdsShowOptions()
        unityAdsShowOptions.objectId = objectIdMap[adUnitId]

        UnityAds.show(
            activity,
            adUnitId,
            unityAdsShowOptions,
            object : IUnityAdsShowListener {
                override fun onUnityAdsShowFailure(placementId: String, error: UnityAdsShowError, message: String) {
                    setStatusMessage("Unity Ads failed to show ad for $placementId with error: [$error] $message")
                }

                override fun onUnityAdsShowStart(placementId: String) {
                    setStatusMessage("onUnityAdsShowStart: $placementId")
                }

                override fun onUnityAdsShowClick(placementId: String) {
                    setStatusMessage("onUnityAdsShowClick: $placementId")
                }

                override fun onUnityAdsShowComplete(placementId: String, state: UnityAdsShowCompletionState) {
                    setStatusMessage("onUnityAdsShowComplete: $placementId")
                }
            },
        )
    }

    fun getSDKVersion() = "SDK Version: " + UnityAds.version

    private fun setStatusMessage(errorMessage: String) {
        _statusMessage.value = errorMessage
        Log.d("UnityAds", errorMessage)
    }
}
