Объясни подробно и доступно, что происходит когда приходит CRMNotificationType.COUPON? package ru.maxi.mobile.ui.splash

import android.content.Intent
import android.os.Bundle
import androidx.core.os.BundleCompat
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.work.WorkManager
import com.axmor.maxi.AgreementActivity
import com.axmor.maxi.Constants
import com.axmor.maxi.UserPolicyActivity
import com.axmor.maxi.model.user.UserInfoProvider
import com.axmor.maxi.view.main.MainNavigationActivity
import com.axmor.maxi.view.main.TabType
import ru.maxi.mobile.MyTrackerInitializer
import ru.maxi.mobile.base.ui.BaseActivity
import ru.maxi.mobile.common.card.repository.local.LocalCardRepository
import ru.maxi.mobile.common.client.repository.local.LocalClientRepository
import ru.maxi.mobile.entity.app.AppIntentData
import ru.maxi.mobile.feature.achievements.AchievementsScreens
import ru.maxi.mobile.feature.analytics.model.events.AnalyticsPushEvent
import ru.maxi.mobile.feature.analytics.model.eventsource.PushCouponDetailsEventSource
import ru.maxi.mobile.feature.analytics.model.eventsource.PushPostEventSource
import ru.maxi.mobile.feature.analytics.model.eventsource.PushProductEventSource
import ru.maxi.mobile.feature.analytics.usecase.AnalyticsUseCase
import ru.maxi.mobile.feature.appLink.AppLinkParser
import ru.maxi.mobile.feature.city.repository.local.LocalCityRepository
import ru.maxi.mobile.presentation.auth.AuthScreens
import ru.maxi.mobile.repositories.client.local.LocalUserPolicyRepository
import ru.maxi.mobile.repositories.deeplink.DeepLinkType
import ru.maxi.mobile.service.notification.CRMNotificationType
import ru.maxi.mobile.service.notification.PushTypeAction
import ru.maxi.mobile.service.notification.ReadNotificationWorker
import ru.maxi.mobile.service.notification.RemoteMessageHandler
import javax.inject.Inject

/**
 * Splash-экран при запуске приложения
 */
class SplashActivity : BaseActivity() {

    private var appIntentData: AppIntentData? = null

    private var pushId: Long? = null
    private var analyticsLabel: String? = null

    @Inject
    lateinit var workManager: WorkManager

    @Inject
    lateinit var localClientRepository: LocalClientRepository

    @Inject
    lateinit var localCardRepository: LocalCardRepository

    @Inject
    lateinit var localUserPolicyRepository: LocalUserPolicyRepository

    @Inject
    lateinit var userInfoProvider: UserInfoProvider

    @Inject
    lateinit var localCityRepository: LocalCityRepository

    @Inject
    lateinit var analyticsUseCase: AnalyticsUseCase

    override fun onCreate(savedInstanceState: Bundle?) {
        activityComponent.inject(this)
        installSplashScreen()
        super.onCreate(savedInstanceState)
    }

    override fun onStart() {
        super.onStart()
        PushTypeAction.getByActionName(intent.action)
            ?.let { pushTypeAction -> parsePushIntentData(intent.extras, pushTypeAction) }
            ?: (MyTrackerInitializer.handleDeeplink(intent) ?: intent.data)
                ?.let(AppLinkParser::parseUri)
                ?.let { appIntentData = AppIntentData.OpenDeepLink(it) }
    }

    override fun onResume() {
        super.onResume()
        checkRules()
    }

    private fun parsePushIntentData(bundle: Bundle?, action: PushTypeAction) {
        val pushId = bundle?.getLong(RemoteMessageHandler.Companion.NotificationDataKeys.PUSH_ID)
        this.pushId = pushId
        this.analyticsLabel = bundle?.getString(RemoteMessageHandler.Companion.NotificationDataKeys.ANALYTICS_LABEL)
        appIntentData = when (action) {
            PushTypeAction.POST -> {
                val postId = bundle?.getLong(RemoteMessageHandler.Companion.NotificationDataKeys.POST_ID)
                if (pushId != null && postId != null) {
                    ReadNotificationWorker.enqueueWorkWith(workManager, pushId)
                    AppIntentData.OpenDeepLink(DeepLinkType.OpenPost(postId, PushPostEventSource))
                } else {
                    null
                }
            }

            PushTypeAction.MESSAGE -> AppIntentData.OpenDeepLink(DeepLinkType.SwitchTab(TabType.MESSAGES_TAB))
            PushTypeAction.DELIVERY -> AppIntentData.UpdateDeliveryOrderStatus

            PushTypeAction.COUPON_STATUS_CHANGE -> null
            PushTypeAction.CRM_ACTIONS -> parseCrmActionIntentData(bundle)
            PushTypeAction.DELIVERY_PROMO_CODES -> {
                bundle?.getString(RemoteMessageHandler.Companion.NotificationDataKeys.PROMO_CODE)
                    ?.let { promoCode ->
                        AppIntentData.OpenDeepLink(DeepLinkType.ShowDeliveryPromoCode(promoCode))
                    }
            }

            PushTypeAction.MAXI_PAY_CONFIRMATION -> {
                val paymentUuid =
                    bundle?.getString(RemoteMessageHandler.Companion.NotificationDataKeys.MAXI_PAY_UUID)
                val notificationId = bundle?.getInt(RemoteMessageHandler.Companion.NotificationDataKeys.NOTIFICATION_ID)
                if (paymentUuid != null && notificationId != null) {
                    AppIntentData.OpenDeepLink(
                        DeepLinkType.OpenMaxiPayPaymentConfirmation(
                            paymentUuid,
                            notificationId,
                        ),
                    )
                } else {
                    null
                }
            }

            PushTypeAction.MAXI_PAY_STATUS -> {
                val paymentUuid = bundle?.getString(RemoteMessageHandler.Companion.NotificationDataKeys.MAXI_PAY_UUID)
                paymentUuid?.let { AppIntentData.OpenDeepLink(DeepLinkType.OpenMaxiPayPaymentNotification(it)) }
            }
        }
    }

    private fun parseCrmActionIntentData(bundle: Bundle?): AppIntentData? {
        if (bundle == null) return null

        val notificationType = BundleCompat.getSerializable(
            bundle,
            RemoteMessageHandler.Companion.NotificationDataKeys.CRM_TRANSITION_TYPE,
            CRMNotificationType::class.java,
        ) ?: return null

        return when (notificationType) {
            CRMNotificationType.CATEGORY -> {
                bundle.getString(RemoteMessageHandler.Companion.NotificationDataKeys.CRM_VALUE)
                    ?.toLongOrNull()
                    ?.let { categoryId ->
                        AppIntentData.OpenDeepLink(DeepLinkType.OpenProductsCategory(categoryId))
                    }
            }

            CRMNotificationType.COUPON -> {
                val couponId = bundle.getString(RemoteMessageHandler.Companion.NotificationDataKeys.CRM_VALUE)
                    ?.toLongOrNull()
                AppIntentData.OpenDeepLink(DeepLinkType.OpenCoupons(couponId, PushCouponDetailsEventSource))
            }

            CRMNotificationType.CASHBACK -> AppIntentData.OpenDeepLink(DeepLinkType.OpenCashback)
            CRMNotificationType.MOMENT_DISCOUNT -> AppIntentData.OpenDeepLink(DeepLinkType.OpenMomentDiscount)
            CRMNotificationType.LOTTERY -> {
                val lotteryId = bundle.getString(RemoteMessageHandler.Companion.NotificationDataKeys.CRM_VALUE)
                AppIntentData.OpenDeepLink(DeepLinkType.OpenLottery(lotteryId))
            }

            CRMNotificationType.BIRTHDAY -> AppIntentData.OpenDeepLink(DeepLinkType.OpenBirthdayPromo)
            CRMNotificationType.GIFT_CARD -> AppIntentData.OpenDeepLink(DeepLinkType.OpenGiftCardPromo)
            CRMNotificationType.CATALOG -> AppIntentData.OpenDeepLink(DeepLinkType.SwitchTab(TabType.CATALOG_TAB))
            CRMNotificationType.CATEGORY_COLLECTION -> {
                bundle.getString(RemoteMessageHandler.Companion.NotificationDataKeys.CRM_VALUE)
                    ?.toLongOrNull()
                    ?.let { collectionId ->
                        AppIntentData.OpenDeepLink(
                            DeepLinkType.OpenCategoryCollection(collectionId),
                        )
                    }
            }

            CRMNotificationType.PRODUCT_COLLECTION -> {
                bundle.getString(RemoteMessageHandler.Companion.NotificationDataKeys.CRM_VALUE)
                    ?.toLongOrNull()
                    ?.let { productCollectionId ->
                        AppIntentData.OpenDeepLink(
                            DeepLinkType.OpenProductCollection(productCollectionId),
                        )
                    }
            }

            CRMNotificationType.USER_PROFILE -> AppIntentData.OpenDeepLink(DeepLinkType.OpenClientData)
            CRMNotificationType.USER_CARD -> AppIntentData.OpenDeepLink(DeepLinkType.SwitchTab(TabType.CARD_TAB))
            CRMNotificationType.ADVENT_CALENDAR -> AppIntentData.OpenDeepLink(DeepLinkType.OpenAdventCalendar)
            CRMNotificationType.CLUBS -> {
                bundle.getString(RemoteMessageHandler.Companion.NotificationDataKeys.CRM_VALUE)
                    ?.toLongOrNull()
                    ?.let { clubId ->
                        AppIntentData.OpenDeepLink(
                            DeepLinkType.OpenClub(clubId),
                        )
                    }
            }

            CRMNotificationType.CLUB_COUPONS -> {
                bundle.getString(RemoteMessageHandler.Companion.NotificationDataKeys.CRM_VALUE)
                    ?.toLongOrNull()
                    ?.let { clubId ->
                        AppIntentData.OpenDeepLink(
                            DeepLinkType.OpenClubCoupons(clubId),
                        )
                    }
            }

            CRMNotificationType.CLUBS_LIST -> AppIntentData.OpenDeepLink(DeepLinkType.OpenClubsList)

            CRMNotificationType.POPULAR_DISCOUNT -> AppIntentData.OpenDeepLink(DeepLinkType.OpenPopularProductsDiscount)
            CRMNotificationType.WELCOME_PACKAGE -> AppIntentData.OpenDeepLink(DeepLinkType.OpenWelcomePackagePromo)
            CRMNotificationType.PARTNERS_DISCOUNTS -> {
                val discountId = bundle.getString(RemoteMessageHandler.Companion.NotificationDataKeys.CRM_VALUE)
                    ?.toLongOrNull()
                AppIntentData.OpenDeepLink(DeepLinkType.OpenPartnersDiscounts(discountId))
            }

            CRMNotificationType.WEB_URL -> {
                bundle.getString(RemoteMessageHandler.Companion.NotificationDataKeys.CRM_VALUE)
                    ?.let { url ->
                        AppIntentData.OpenDeepLink(DeepLinkType.OpenExternalLink(url))
                    }
            }

            CRMNotificationType.PROFILE_EXTRA_DATA -> AppIntentData.OpenDeepLink(DeepLinkType.OpenClientExtraData)

            CRMNotificationType.PROMO_CODE -> {
                val promoCode = bundle.getString(RemoteMessageHandler.Companion.NotificationDataKeys.CRM_VALUE)
                AppIntentData.OpenDeepLink(DeepLinkType.ShowOfflinePromoCode(promoCode))
            }

            CRMNotificationType.COUPON_FOR_CHIPS -> AppIntentData.OpenDeepLink(DeepLinkType.OpenCouponsForChips)
            CRMNotificationType.COUPON_FOR_CHIPS_PROMO ->
                AppIntentData.OpenDeepLink(DeepLinkType.OpenCouponsForChipsPromo)

            CRMNotificationType.SCRATCH_CARDS ->
                AppIntentData.OpenDeepLink(DeepLinkType.OpenScratchCards)

            CRMNotificationType.MARATHON -> AppIntentData.OpenDeepLink(DeepLinkType.OpenMarathon)
            CRMNotificationType.MAXI_PAY -> AppIntentData.OpenDeepLink(DeepLinkType.OpenMaxiPay)
            CRMNotificationType.SHOPPING_LIST -> AppIntentData.OpenDeepLink(DeepLinkType.OpenShoppingList)
            CRMNotificationType.CHIPS -> AppIntentData.OpenDeepLink(DeepLinkType.OpenChips)
            CRMNotificationType.SHARE_CHIPS -> AppIntentData.OpenDeepLink(DeepLinkType.OpenShareChips)

            CRMNotificationType.PRODUCT -> {
                bundle.getString(RemoteMessageHandler.Companion.NotificationDataKeys.CRM_VALUE)
                    ?.toLongOrNull()
                    ?.let { productId ->
                        AppIntentData.OpenDeepLink(
                            DeepLinkType.OpenProductDetails(
                                productId = productId,
                                eventSource = PushProductEventSource,
                            ),
                        )
                    }
            }

            CRMNotificationType.ACHIEVEMENTS -> {
                val achievementId = bundle.getString(RemoteMessageHandler.Companion.NotificationDataKeys.CRM_VALUE)
                AppIntentData.OpenDeepLink(
                    DeepLinkType.OpenAchievements(
                        AchievementsScreens.AchievementsTab.IN_PROGRESS_TAB,
                        achievementId?.toLongOrNull(),
                    ),
                )
            }

            CRMNotificationType.ACHIEVEMENTS_RECEIVED -> {
                val achievementId = bundle.getString(RemoteMessageHandler.Companion.NotificationDataKeys.CRM_VALUE)
                AppIntentData.OpenDeepLink(
                    DeepLinkType.OpenAchievements(
                        AchievementsScreens.AchievementsTab.RECEIVED_TAB,
                        achievementId?.toLongOrNull(),
                    ),
                )
            }

            CRMNotificationType.STORIES -> {
                val storiesId = bundle.getString(RemoteMessageHandler.Companion.NotificationDataKeys.CRM_VALUE)
                AppIntentData.OpenDeepLink(
                    DeepLinkType.OpenStories(
                        storiesId?.toLongOrNull(),
                    )
                )
            }
        }
    }

    private fun checkRules() {
        if (localClientRepository.isUserAnonymous() || localUserPolicyRepository.getUserPolicy()?.isAccepted != false) {
            openNextScreen()
        } else {
            val intent = Intent(this, UserPolicyActivity::class.java)
            startActivity(intent)
        }
    }

    private fun openNextScreen() {
        if (userInfoProvider.needAcceptAgreement()) {
            return openAgreementScreen()
        }

        val isUserAuthenticated = localClientRepository.isUserAuthenticated() &&
            localCardRepository.hasCardNumber() &&
            localCityRepository.getCurrentCityCode().isNotBlank()
        if (localClientRepository.isAuthSkipped() || isUserAuthenticated) {
            return openMainScreen()
        }

        return openAuthScreen()
    }

    private fun openAgreementScreen() {
        val intent = Intent(this, AgreementActivity::class.java)
        startActivity(intent)
        finish()
    }

    private fun openAuthScreen() {
        val intent = AuthScreens.AuthContainerScreen().createIntent(this)
        startActivity(intent)
        finish()
    }

    private fun openMainScreen() {
        val intent = Intent(this, MainNavigationActivity::class.java)
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
        appIntentData?.let {
            intent.putExtra(Constants.EXTRA_INTENT_DATA, it)
            sendPushOpenAnalytic(it)
        } ?: intent.putExtras(getIntent())
        startActivity(intent)
        finish()
    }

    private fun sendPushOpenAnalytic(intentData: AppIntentData) {
        val eventAdditionalValue = when (intentData) {
            is AppIntentData.OpenDeepLink -> when (val deepLink = intentData.deepLink) {
                is DeepLinkType.OpenPost -> deepLink.postId.toString()
                is DeepLinkType.ShowDeliveryPromoCode -> deepLink.promoCode
                is DeepLinkType.OpenCategoryCollection -> deepLink.collectionId.toString()
                is DeepLinkType.OpenProductsCategory -> deepLink.categoryId.toString()
                else -> null
            }

            else -> null
        }
        analyticsUseCase log AnalyticsPushEvent.AppOpenFromPush(
            intentData,
            pushId,
            eventAdditionalValue,
            analyticsLabel,
        )
    }
}