Тимлид написал замечание к DeepLinkType.OpenMainPageStories -> : Почему в самом диплинке не передать список? Диплинк же "Открыть сторисы" и передать ему идентифиакторы этих сторисов. Как это сделать?  package ru.maxi.mobile.mainActivity.ui

import android.net.Uri
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.axmor.maxi.view.main.TabType
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Job
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.yield
import ru.maxi.mobile.BuildConfig
import ru.maxi.mobile.business.deeplinks.DeepLinkInteractor
import ru.maxi.mobile.common.features.business.FeatureProvider
import ru.maxi.mobile.entity.featurepromo.FeaturePromoType
import ru.maxi.mobile.feature.appLink.AppLinkParser
import ru.maxi.mobile.feature.birthdaygifts.usecase.ClientBirthdayInteractor
import ru.maxi.mobile.feature.mainpage.business.MainPageStoriesInteractor
import ru.maxi.mobile.feature.messages.business.MessageInteractor
import ru.maxi.mobile.feature.newCardTab.domain.GetNeedCardTabIndicationUseCase
import ru.maxi.mobile.feature.stories.model.StoriesPreviewFilter
import ru.maxi.mobile.feature.stories.model.StoryId
import ru.maxi.mobile.feature.webfeature.model.WebFeature
import ru.maxi.mobile.repositories.deeplink.DeepLink
import ru.maxi.mobile.repositories.deeplink.DeepLinkType
import ru.maxi.mobile.repositories.deeplink.requiredFeature
import ru.maxi.mobile.repositories.deeplink.requiredTabType
import ru.maxi.mobile.utils.MaxiNotificationManager
import javax.inject.Inject

/**
 * [ViewModel] основного экрана приложения с меню нижней навигации
 */
@HiltViewModel
class MainNavigationViewModel @Inject constructor(
    private val savedStateHandle: SavedStateHandle,
    private val maxiNotificationManager: MaxiNotificationManager,
    private val featureProvider: FeatureProvider,
    private val deepLinkInteractor: DeepLinkInteractor,
    private val birthdayGiftInteractor: ClientBirthdayInteractor,
    private val messagesInteractor: MessageInteractor,
    private val mainPageStoriesInteractor: MainPageStoriesInteractor,
    getNeedCardTabIndication: GetNeedCardTabIndicationUseCase,
) : ViewModel() {

    private var deepLinkFlowJob: Job? = null
    private val _navigationEvent = Channel<MainNavigationEvent>(Channel.BUFFERED)

    /** События навигации */
    val navigationEvent = _navigationEvent.receiveAsFlow()
        .onStart {
            switchTab(savedStateHandle.get<TabType>(SELECTED_TAB_TYPE_SAVE_KEY) ?: TabType.entries.first())
            deepLinkFlowJob?.cancel()
            deepLinkFlowJob = viewModelScope.launch {
                deepLinkInteractor.deepLinkFlow.collect(::processDeepLink)
            }
        }

    /** Индикация табов */
    val tabsIndication =
        combine(
            getNeedCardTabIndication.cardTabIndicationFlow,
            messagesInteractor.hasIndicationFlow,
        ) { cardIndication, messagesIndication ->
            val tabs = TabType.entries.associateWith { false }.toMutableMap()
            tabs[TabType.CARD_TAB] = cardIndication
            tabs[TabType.MESSAGES_TAB] = messagesIndication
            tabs.toMap()
        }

    private suspend fun processDeepLink(deepLink: DeepLink) {
        val requiredFeature = deepLink.type.requiredFeature
        if (requiredFeature != null && !featureProvider.isFeatureAvailable(requiredFeature)) {
            return
        }

        if (deepLink.type !is DeepLinkType.SwitchTab) {
            switchTab(
                tabType = deepLink.type.requiredTabType,
                clearNavigation = deepLink.clearNavigation,
            )
            // Освобождаем поток, чтобы фрагмент обработал переключение таба перед навигацией
            yield()
        }

        when (deepLink.type) {
            DeepLinkType.OpenAdventCalendar -> _navigationEvent.send(
                MainNavigationEvent.OpenAdventCalendar,
            )

            DeepLinkType.OpenBirthdayPromo -> {
                val featurePromoType = if (birthdayGiftInteractor.haveBirthdayGifts()) {
                    FeaturePromoType.BIRTHDAY_GIFTS
                } else {
                    FeaturePromoType.BIRTHDAY
                }

                _navigationEvent.send(
                    MainNavigationEvent.OpenFeaturePromo(
                        featurePromoType = featurePromoType,
                    ),
                )
            }

            DeepLinkType.OpenCart -> _navigationEvent.send(
                MainNavigationEvent.OpenCart,
            )

            DeepLinkType.OpenCashback -> _navigationEvent.send(
                MainNavigationEvent.OpenCashback,
            )

            is DeepLinkType.OpenCategoryCollection -> _navigationEvent.send(
                MainNavigationEvent.OpenCategoryCollection(
                    collectionId = deepLink.type.collectionId,
                ),
            )

            DeepLinkType.OpenChips -> _navigationEvent.send(
                MainNavigationEvent.OpenChips,
            )

            DeepLinkType.OpenClientData -> _navigationEvent.send(
                MainNavigationEvent.OpenClientData,
            )

            DeepLinkType.OpenClientExtraData -> _navigationEvent.send(
                MainNavigationEvent.OpenClientExtraData,
            )

            is DeepLinkType.OpenClub -> _navigationEvent.send(
                MainNavigationEvent.OpenClub(
                    clubId = deepLink.type.clubId,
                ),
            )

            is DeepLinkType.OpenClubCoupons -> _navigationEvent.send(
                MainNavigationEvent.OpenClubCoupons(
                    clubId = deepLink.type.clubId,
                ),
            )

            DeepLinkType.OpenClubsList -> _navigationEvent.send(
                MainNavigationEvent.OpenClubsList,
            )

            is DeepLinkType.OpenCoupons -> _navigationEvent.send(
                MainNavigationEvent.OpenCoupons(
                    couponId = deepLink.type.couponId,
                    eventSource = deepLink.type.eventSource,
                ),
            )

            DeepLinkType.OpenCouponsForChips -> _navigationEvent.send(
                MainNavigationEvent.OpenCouponForChips,
            )

            DeepLinkType.OpenCouponsForChipsPromo -> _navigationEvent.send(
                MainNavigationEvent.OpenFeaturePromo(
                    featurePromoType = FeaturePromoType.COUPON_FOR_CHIPS,
                ),
            )

            is DeepLinkType.OpenExternalLink -> {
                val url = deepLink.type.url

                AppLinkParser.parseUri(Uri.parse(url))?.let { newDeepLinkType ->
                    val newDeepLink = DeepLink(newDeepLinkType, deepLink.clearNavigation)
                    processDeepLink(newDeepLink)
                    return
                }

                val event = if (url.startsWith("https://${BuildConfig.MAXI_RETAIL_HOST}")) {
                    MainNavigationEvent.OpenWebFeature(
                        feature = WebFeature(Uri.parse(url)),
                    )
                } else {
                    MainNavigationEvent.OpenExternalUrl(
                        url = url,
                    )
                }
                _navigationEvent.send(event)
            }

            DeepLinkType.OpenGiftCardPromo -> _navigationEvent.send(
                MainNavigationEvent.OpenFeaturePromo(
                    FeaturePromoType.GIFT_CARD,
                ),
            )

            is DeepLinkType.OpenLottery -> _navigationEvent.send(
                MainNavigationEvent.OpenLottery(
                    deepLink.type.lotteryId,
                ),
            )

            DeepLinkType.OpenMarathon -> _navigationEvent.send(
                MainNavigationEvent.OpenMarathon,
            )

            DeepLinkType.OpenMaxiPay -> _navigationEvent.send(
                MainNavigationEvent.OpenMaxiPay,
            )

            is DeepLinkType.OpenMaxiPayPaymentConfirmation -> {
                _navigationEvent.send(
                    MainNavigationEvent.OpenMaxiPayPaymentConfirmation(
                        paymentUuid = deepLink.type.paymentUuid,
                    ),
                )
                maxiNotificationManager.hideNotification(deepLink.type.notificationId)
            }

            is DeepLinkType.OpenMaxiPayPaymentNotification -> _navigationEvent.send(
                MainNavigationEvent.OpenMaxiPayPaymentNotification(
                    paymentUuid = deepLink.type.paymentUuid,
                ),
            )

            DeepLinkType.OpenMomentDiscount -> _navigationEvent.send(
                MainNavigationEvent.OpenMomentDiscount,
            )

            is DeepLinkType.OpenOrderList -> _navigationEvent.send(
                MainNavigationEvent.OpenCatalogWithOrderList(
                    newOrderId = deepLink.type.newOrderId,
                    externalOrderId = deepLink.type.externalOrderId,
                ),
            )

            is DeepLinkType.OpenPartnersDiscounts -> _navigationEvent.send(
                MainNavigationEvent.OpenPartnersDiscounts(
                    discountId = deepLink.type.discountId,
                ),
            )

            DeepLinkType.OpenPersonalProductCollection -> _navigationEvent.send(
                MainNavigationEvent.OpenPersonalProductCollection(
                    collectionId = PERSONAL_PRODUCT_COLLECTION_ID,
                ),
            )

            DeepLinkType.OpenPopularProductsDiscount -> _navigationEvent.send(
                MainNavigationEvent.OpenCatalogWithPopularDiscount,
            )

            is DeepLinkType.OpenPost -> _navigationEvent.send(
                MainNavigationEvent.OpenPost(
                    postId = deepLink.type.postId,
                    eventSource = deepLink.type.eventSource,
                ),
            )

            is DeepLinkType.OpenProductCollection -> _navigationEvent.send(
                MainNavigationEvent.OpenProductCollection(
                    collectionId = deepLink.type.collectionId,
                ),
            )

            is DeepLinkType.OpenProductDetails -> _navigationEvent.send(
                MainNavigationEvent.OpenProductDetails(
                    categoryId = deepLink.type.categoryId,
                    productId = deepLink.type.productId,
                    eventSource = deepLink.type.eventSource,
                ),
            )

            is DeepLinkType.OpenProductsCategory -> _navigationEvent.send(
                MainNavigationEvent.OpenProductsCategory(
                    categoryId = deepLink.type.categoryId,
                ),
            )

            DeepLinkType.OpenSbpQrScanner -> _navigationEvent.send(
                MainNavigationEvent.OpenSbpQrScanner,
            )

            DeepLinkType.OpenScratchCards -> _navigationEvent.send(
                MainNavigationEvent.OpenScratchCards,
            )

            DeepLinkType.OpenShareChips -> _navigationEvent.send(
                MainNavigationEvent.OpenShareChips,
            )

            DeepLinkType.OpenShopList -> _navigationEvent.send(
                MainNavigationEvent.OpenShopList,
            )

            DeepLinkType.OpenShoppingList -> _navigationEvent.send(
                MainNavigationEvent.OpenShoppingList,
            )

            is DeepLinkType.OpenWebFeature -> _navigationEvent.send(
                MainNavigationEvent.OpenWebFeature(
                    feature = deepLink.type.feature,
                ),
            )

            DeepLinkType.OpenWelcomePackagePromo -> _navigationEvent.send(
                MainNavigationEvent.OpenFeaturePromo(
                    featurePromoType = FeaturePromoType.WELCOME_PACKAGE,
                ),
            )

            is DeepLinkType.ShowDeliveryPromoCode -> _navigationEvent.send(
                MainNavigationEvent.OpenCatalogWithCartPromoCode(
                    promoCode = deepLink.type.promoCode,
                ),
            )

            is DeepLinkType.ShowOfflinePromoCode -> _navigationEvent.send(
                MainNavigationEvent.OpenCardWithOfflinePromoCode(
                    promoCode = deepLink.type.promoCode,
                ),
            )

            DeepLinkType.OpenFeedbackRules -> {
                _navigationEvent.send(
                    MainNavigationEvent.OpenFeedbackRules,
                )
            }

            is DeepLinkType.OpenAchievements -> {
                _navigationEvent.send(
                    MainNavigationEvent.OpenAchievements(
                        initialTab = deepLink.type.initialTab,
                        achievementId = deepLink.type.achievementId,
                    ),
                )
            }

            is DeepLinkType.OpenMainPageStories -> {
                val startStoryId = deepLink.type.startStoryId ?: return
                _navigationEvent.send(
                    MainNavigationEvent.OpenMainPageStories(
                        filter = StoriesPreviewFilter.StoriesList(listOf(StoryId(startStoryId))),
                        storiesPreviewUseCase = mainPageStoriesInteractor,
                        startActivityOptions = null,
                    ),
                )
            }

            is DeepLinkType.SwitchTab -> switchTab(
                tabType = deepLink.type.requiredTabType,
                clearNavigation = deepLink.clearNavigation,
            )
        }
    }

    /**
     * Сменить таб навигации на [tabType]
     */
    fun switchTab(tabType: TabType) {
        viewModelScope.launch {
            switchTab(tabType, clearNavigation = false)
        }
    }

    private suspend fun switchTab(tabType: TabType, clearNavigation: Boolean) {
        _navigationEvent.send(
            MainNavigationEvent.SwitchTab(
                tabType = tabType,
                clearNavigation = clearNavigation,
            ),
        )
        savedStateHandle[SELECTED_TAB_TYPE_SAVE_KEY] = tabType
    }

    private companion object {
        const val PERSONAL_PRODUCT_COLLECTION_ID = -1L
        const val SELECTED_TAB_TYPE_SAVE_KEY = "selected_tab_type"
    }
}