package dev.ulfrx.recipe.ui.screens.shell

import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.core.FastOutSlowInEasing
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.togetherWith
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.lazy.grid.rememberLazyGridState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import dev.ulfrx.recipe.navigation.RootNavDisplay
import dev.ulfrx.recipe.navigation.TabNavigator
import dev.ulfrx.recipe.ui.components.glass.GlassBackdropSource
import dev.ulfrx.recipe.ui.components.glass.LocalGlassBackdropState
import dev.ulfrx.recipe.ui.components.glass.rememberGlassBackdropState
import dev.ulfrx.recipe.ui.components.overlay.LocalOverlayDismisser
import dev.ulfrx.recipe.ui.components.overlay.OverlayDismisser
import dev.ulfrx.recipe.ui.screens.search.SearchScreen
import dev.ulfrx.recipe.ui.screens.search.ShellSearchViewModel
import dev.ulfrx.recipe.ui.theme.RecipeTheme
import org.koin.compose.viewmodel.koinViewModel

@Preview
@Composable
fun AppShell(modifier: Modifier = Modifier) {
    val navigator = remember { TabNavigator() }
    val searchVm: ShellSearchViewModel = koinViewModel()
    val catalogGridState = rememberLazyGridState()
    val searchState by searchVm.state.collectAsStateWithLifecycle()
    val backdropState = rememberGlassBackdropState()
    val overlayDismisser = remember { OverlayDismisser() }

    CompositionLocalProvider(
        LocalGlassBackdropState provides backdropState,
        LocalOverlayDismisser provides overlayDismisser,
    ) {
        Box(
            modifier =
                modifier
                    .fillMaxSize()
                    .background(RecipeTheme.colors.background),
        ) {
            GlassBackdropSource(
                state = backdropState,
                modifier = Modifier.fillMaxSize(),
            ) {
                AnimatedContent(
                    targetState = searchState.isOpen,
                    modifier = Modifier.fillMaxSize(),
                    transitionSpec = {
                        fadeIn(tween(durationMillis = 200, easing = FastOutSlowInEasing)) togetherWith
                            fadeOut(tween(durationMillis = 200, easing = FastOutSlowInEasing))
                    },
                    label = "AppShell body",
                ) { searchOpen ->
                    if (searchOpen) {
                        SearchScreen(
                            viewModel = searchVm,
                            catalogGridState = catalogGridState,
                        )
                    } else {
                        RootNavDisplay(
                            navigator = navigator,
                            modifier = Modifier.fillMaxSize(),
                        )
                    }
                }
            }

            ShellBottomChrome(
                activeTab = navigator.activeTab,
                onTabSelect = { tab ->
                    overlayDismisser.dismissAll()
                    navigator.selectTab(tab)
                },
                search =
                    SearchHandlers(
                        state = searchState,
                        onOpen = searchVm::open,
                        onQueryChange = searchVm::onQueryChange,
                        onClose = searchVm::close,
                        onFocus = searchVm::focus,
                        onUnfocus = searchVm::unfocus,
                    ),
                modifier = Modifier.align(Alignment.BottomCenter),
            )
        }
    }
}
