package com.suno.android.common_data.promos import arrow.core.getOrElse import com.suno.android.common_core_utils.SunoLogger import com.suno.android.common_data.mappers.promos.DomainModalsGraphic import com.suno.android.common_data.mappers.promos.toDomainModalsGraphic import com.suno.android.common_networking.extensions.toThrowable import com.suno.android.common_networking.remote.modals.ModalsService import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList import javax.inject.Inject interface PromoBannersRepository { suspend fun getPromoBanners(): Result> suspend fun markBannerAsSeen( modalId: String, ): Result } class DefaultPromoBannersRepository @Inject constructor( loggerFactory: SunoLogger.Factory, private val modalsService: ModalsService, ) : PromoBannersRepository { private val logger = loggerFactory.create(this@DefaultPromoBannersRepository) override suspend fun getPromoBanners(): Result> { val modals = modalsService.getModals() .getOrElse { error -> val throwable = error.toThrowable() logger.e(throwable) { "Failed to fetch modals" } return Result.failure(throwable) } val promoBanners = modals .map { it.toDomainModalsGraphic() } .toImmutableList() return Result.success(promoBanners) } // Tries to ping backend to mark banner as seen 3 times. override suspend fun markBannerAsSeen( modalId: String, ): Result { repeat(MAX_RETRIES) { attempt -> val result = modalsService.markModalAsSeen(modalId) .getOrElse { error -> logger.e(error.toThrowable()) { "Failed to mark modal as seen: $modalId" } return@repeat } // Check if backend reports success if (result.success) { return Result.success(Unit) } } // All retries exhausted logger.w { "Failed to mark modal as seen after $MAX_RETRIES attempts: $modalId" } return Result.failure(Throwable("Unknown error marking modal as seen")) } companion object { private const val MAX_RETRIES = 3 } }