package com.blaze.rtnblazeima.module import android.util.Log import androidx.annotation.Keep import com.blaze.blazesdk.ads.ima.BlazeIMAHandlerEventType import com.blaze.blazesdk.ads.ima.models.BlazeImaAdInfo import com.blaze.ima.BlazeIMA import com.blaze.ima.BlazeIMAAdRequestInformation import com.blaze.ima.BlazeIMADelegate import com.blaze.rtnblazesdk.ads.BlazeRTNContentExtraInfo import com.blaze.rtnblazesdk.ads.toReactNativeModel import com.blaze.rtnblazesdk.shared.blazeAsyncBridge import com.blaze.rtnblazesdk.shared.callJSMethod import com.facebook.common.internal.DoNotStrip import com.facebook.react.bridge.ReactApplicationContext import com.facebook.react.bridge.ReactContextBaseJavaModule import com.facebook.react.bridge.ReactMethod import com.google.ads.interactivemedia.v3.api.ImaSdkFactory import com.google.ads.interactivemedia.v3.api.ImaSdkSettings import javax.annotation.Nonnull class BlazeIMASdkModule(private val context: ReactApplicationContext): ReactContextBaseJavaModule(context) { @Nonnull override fun getName(): String { return NAME } private val delegate: BlazeIMADelegate by lazy { object : BlazeIMADelegate { override fun onIMAAdEvent(eventType: BlazeIMAHandlerEventType, adInfo: BlazeImaAdInfo?) { this@BlazeIMASdkModule.onAdEvent( eventType = eventType, adInfo = adInfo ) } override fun onIMAAdError(errMsg: String) { this@BlazeIMASdkModule.onAdError( errorMessage = errMsg ) } override suspend fun additionalIMATagQueryParams(requestData: BlazeIMAAdRequestInformation): Map { return this@BlazeIMASdkModule.additionalIMATagQueryParams( requestData = requestData ) ?: super.additionalIMATagQueryParams( requestData = requestData ) } override suspend fun customIMASettings(requestData: BlazeIMAAdRequestInformation): ImaSdkSettings? { return this@BlazeIMASdkModule.customIMASettings( requestData = requestData ) ?: super.customIMASettings( requestData = requestData ) } override suspend fun overrideAdTagUrl(requestData: BlazeIMAAdRequestInformation): String? { return this@BlazeIMASdkModule.overrideAdTagUrl( requestData = requestData ) ?: super.overrideAdTagUrl( requestData = requestData ) } } } @ReactMethod @DoNotStrip fun enableAds() { BlazeIMA.enableAds(delegate = delegate) } @ReactMethod @DoNotStrip fun disableAds() { BlazeIMA.disableAds() } // MARK: - Delegate Implementation Functions private fun onAdError(errorMessage: String) { val event = SdkModuleJsEvent.OnAdErrorEvent( errorMessage = errorMessage ) sendJsEvent(event) } private fun onAdEvent( eventType: BlazeIMAHandlerEventType, adInfo: BlazeImaAdInfo? ) { val event = SdkModuleJsEvent.OnAdEvent( eventType = eventType, ad = adInfo ) sendJsEvent(event) } private suspend fun additionalIMATagQueryParams( requestData: BlazeIMAAdRequestInformation ): Map? { val asyncBridge = context.blazeAsyncBridge ?: return null return try { val result: Map = asyncBridge.callJSMethod( name = "BlazeIMA.additionalIMATagQueryParams", params = requestData.toReactNativeModel() ) result } catch (e: Exception) { // Log specific error and continue with fallback Log.d(TAG, "Error additionalIMATagQueryParams: ${e.message}") null } } private suspend fun customIMASettings( requestData: BlazeIMAAdRequestInformation ): ImaSdkSettings? { val asyncBridge = context.blazeAsyncBridge ?: return null return try { val result: BlazeRTNIMASettings? = asyncBridge.callJSMethod( name = "BlazeIMA.customIMASettings", params = requestData.toReactNativeModel() ) result ?: run { return null } // imaSdkSettings is optional. Clients can use this to customize ImaSdkSettings. val settings = ImaSdkFactory.getInstance().createImaSdkSettings().apply { result.language?.let { language = it } result.ppid?.let { ppid = it } result.sessionId?.let { sessionId = it } } settings } catch (e: Exception) { // Log specific error and continue with fallback Log.d(TAG, "Error customIMASettings: ${e.message}") null } } private suspend fun overrideAdTagUrl( requestData: BlazeIMAAdRequestInformation ): String? { val asyncBridge = context.blazeAsyncBridge ?: return null return try { val result: String? = asyncBridge.callJSMethod( name = "BlazeIMA.overrideAdTagUrl", params = requestData.toReactNativeModel() ) result } catch (e: Exception) { // Log specific error and continue with fallback Log.d(TAG, "Error overrideAdTagUrl: ${e.message}") null } } private fun sendJsEvent(event: SdkModuleJsEvent) { context.emitDeviceEvent(event.eventName, event.params) } companion object { const val NAME = "RTNBlazeIMA" val TAG: String = BlazeIMASdkModule::class.java.simpleName } } @Keep private data class RTNBlazeIMAAdRequestParams( val requestDataInfo: RequestDataInfo ) { @Keep data class RequestDataInfo( val extraInfo: BlazeRTNContentExtraInfo ) } private fun BlazeIMAAdRequestInformation.toReactNativeModel(): RTNBlazeIMAAdRequestParams { return RTNBlazeIMAAdRequestParams( requestDataInfo = RTNBlazeIMAAdRequestParams.RequestDataInfo( extraInfo = this.extraInfo.toReactNativeModel() ) ) }