package com.suno.android.billing import com.revenuecat.purchases.CustomerInfo import com.revenuecat.purchases.Offerings import com.revenuecat.purchases.Purchases import com.revenuecat.purchases.PurchasesError import com.revenuecat.purchases.interfaces.LogInCallback import com.revenuecat.purchases.interfaces.ReceiveCustomerInfoCallback import com.revenuecat.purchases.interfaces.ReceiveOfferingsCallback import com.suno.android.common_core_utils.ApplicationCoroutineScope import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import javax.inject.Inject interface RevenueCatManager { fun getOfferingsFlow(): Flow fun refreshOfferings() fun getCustomerInfoFlow(): Flow fun refreshCustomerInfo() fun triggerFullRefresh() fun setRevenueCatCustomerId( sunoUserId: String, ) fun setRevenueCatEmail( email: String?, ) fun customerSuccessfullySetFlow(): Flow } class RevenueCatManagerImpl @Inject constructor( @ApplicationCoroutineScope private val applicationScope: CoroutineScope, ) : RevenueCatManager { private val _offeringsEventFlow = MutableSharedFlow() override fun getOfferingsFlow(): Flow = _offeringsEventFlow.asSharedFlow() private val _customerStateFlow = MutableStateFlow(null) override fun getCustomerInfoFlow(): Flow = _customerStateFlow.asStateFlow() private val _customerSuccessfullySetFlow = MutableSharedFlow() init { applicationScope.launch { triggerFullRefresh() } } override fun customerSuccessfullySetFlow(): Flow = _customerSuccessfullySetFlow.asSharedFlow() override fun triggerFullRefresh() { refreshOfferings() refreshCustomerInfo() } override fun setRevenueCatCustomerId( sunoUserId: String, ) { Purchases.sharedInstance.logIn( newAppUserID = sunoUserId, callback = object : LogInCallback { override fun onError( error: PurchasesError, ) { // todo: handle customer error!!! } override fun onReceived( customerInfo: CustomerInfo, created: Boolean, ) { applicationScope.launch { refreshCustomerInfo() _customerSuccessfullySetFlow.emit(customerInfo.originalAppUserId.isNotEmpty()) } } }, ) } override fun setRevenueCatEmail( email: String?, ) { Purchases.sharedInstance.setEmail(email) } override fun refreshCustomerInfo() { Purchases.sharedInstance.getCustomerInfo( object : ReceiveCustomerInfoCallback { override fun onError( error: PurchasesError, ) { // todo: broadcast error } override fun onReceived( customerInfo: CustomerInfo, ) { _customerStateFlow.update { customerInfo } } }, ) } override fun refreshOfferings() { Purchases.sharedInstance.getOfferings( object : ReceiveOfferingsCallback { override fun onError( error: PurchasesError, ) { // todo: broadcast error } override fun onReceived( offerings: Offerings, ) { applicationScope.launch { _offeringsEventFlow.emit(offerings) } } }, ) } }