package com.tangem.features.feed.components.feed

import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.State
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.LifecycleStartEffect
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.arkivanov.decompose.ComponentContext
import com.arkivanov.decompose.extensions.compose.subscribeAsState
import com.arkivanov.decompose.router.slot.childSlot
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.decompose.context.child
import com.tangem.core.decompose.context.childByContext
import com.tangem.core.decompose.model.getOrCreateModel
import com.tangem.core.ui.components.bottomsheets.state.BottomSheetState
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
import com.tangem.core.ui.decompose.ComposableContentComponent
import com.tangem.core.ui.decompose.ComposableModularBottomSheetContentComponent
import com.tangem.core.ui.decompose.EmptyComposableBottomSheetComponent
import com.tangem.features.commonfeatures.api.addtoportfolio.AddToPortfolioComponent
import com.tangem.features.feed.model.feed.FeedComponentModel
import com.tangem.features.feed.model.feed.FeedModelClickIntents
import com.tangem.features.feed.ui.feed.FeedList
import com.tangem.features.feed.ui.feed.FeedListHeader
import com.tangem.features.promobanners.api.PromoBannersBlockComponent

internal class DefaultFeedComponent(
    appComponentContext: AppComponentContext,
    private val params: FeedParams,
    private val addToPortfolioComponentFactory: AddToPortfolioComponent.Factory,
    private val promoBannersBlockComponentFactory: PromoBannersBlockComponent.Factory,
) : ComposableModularBottomSheetContentComponent, AppComponentContext by appComponentContext {

    private val feedComponentModel = getOrCreateModel<FeedComponentModel, FeedParams>(params = params)

    private val promoBannersBlockComponent: PromoBannersBlockComponent by lazy {
        promoBannersBlockComponentFactory.create(
            context = child("promoBannersBlockComponent"),
            params = PromoBannersBlockComponent.Params(
                placeholder = PromoBannersBlockComponent.Placeholder.FEED,
                isInitiallyVisibleOnScreen = false,
            ),
        )
    }

    private val bottomSheetSlot = childSlot(
        source = feedComponentModel.bottomSheetNavigation,
        serializer = null,
        handleBackButton = false,
        childFactory = ::bottomSheetChild,
    )

    @Composable
    override fun Title(bottomSheetState: State<BottomSheetState>) {
        val state by feedComponentModel.state.collectAsStateWithLifecycle()
        FeedListHeader(
            isSearchBarClickable = bottomSheetState.value == BottomSheetState.EXPANDED,
            feedListSearchBar = state.feedListSearchBar,
        )
    }

    @Composable
    override fun Content(
        bottomSheetState: State<BottomSheetState>,
        contentPadding: PaddingValues,
        modifier: Modifier,
    ) {
        val isExpanded = bottomSheetState.value == BottomSheetState.EXPANDED
        LaunchedEffect(isExpanded) {
            promoBannersBlockComponent.setVisibleOnScreen(isExpanded)
        }

        LifecycleStartEffect(Unit) {
            feedComponentModel.isVisibleOnScreen.value = true
            onStopOrDispose {
                feedComponentModel.isVisibleOnScreen.value = false
            }
        }

        val bottomSheet by bottomSheetSlot.subscribeAsState()
        val state by feedComponentModel.state.collectAsStateWithLifecycle()
        FeedList(
            modifier = modifier,
            state = state,
            promoBannersBlockComponent = ComposableContentComponent { promoModifier ->
                promoBannersBlockComponent.ContentWithPadding(
                    modifier = promoModifier,
                    horizontalItemPadding = 16.dp,
                    walletId = null,
                )
            },
            contentPadding = contentPadding,
        )
        bottomSheet.child?.instance?.BottomSheet()
    }

    private fun bottomSheetChild(
        config: FeedBottomSheetRoute,
        componentContext: ComponentContext,
    ): ComposableBottomSheetComponent = when (config) {
        is FeedBottomSheetRoute.AddToPortfolio -> {
            val manager = checkNotNull(feedComponentModel.currentAddToPortfolioManager) {
                "currentAddToPortfolioManager must be set before activating AddToPortfolio slot"
            }
            addToPortfolioComponentFactory.create(
                context = childByContext(componentContext),
                params = AddToPortfolioComponent.Params(addToPortfolioManager = manager),
            )
        }
        is FeedBottomSheetRoute.NetworkFilter -> EmptyComposableBottomSheetComponent
        is FeedBottomSheetRoute.TypeFilter -> EmptyComposableBottomSheetComponent
    }

    data class FeedParams(val feedClickIntents: FeedModelClickIntents)
}