const val GRID_COLUMN_COUNT = 4
@OptIn(ExperimentalTvMaterial3Api::class, ExperimentalComposeUiApi::class)
@Composable
fun MoviesScreenTv(
    viewModel: MoviesViewModel = koinViewModel(),
    onMovieClick: (MovieItem) -> Unit,
    onFocusBackToTab: FocusRequester? = null,
    //contentEntryRequester: FocusRequester,
    homeLeft: FocusRequester?,
    homeRight: FocusRequester? = null
    //onShowFilters: () -> Unit
) {
    val uiState by viewModel.uiState.collectAsState()
    val gridState = rememberLazyGridState()
    val scope = rememberCoroutineScope()
    val shouldLoadMore = remember {
        derivedStateOf {
            if (uiState.movies.size < 4) {
                false
            } else {
                val lastVisibleItem = gridState.layoutInfo.visibleItemsInfo.lastOrNull()?.index ?: 0
                val totalItems = uiState.movies.size
                lastVisibleItem >= totalItems - 4
            }
        }
    }
    LaunchedEffect(shouldLoadMore.value) {
        val canLoad = uiState.canLoadMore && !uiState.isLoading && !uiState.isLoadingMore
        if (shouldLoadMore.value && canLoad) {
            viewModel.loadMoreMovies()
        }
    }
    //ALL CONTAINER FOCUS HANDLE
    // 1. Создаем FocusRequester'ы
    val parentFocusRequester = remember { FocusRequester() }
    val childFocusRequester = remember { FocusRequester() }
    // 2. Модификатор для родительского контейнера
    val parentModifier = Modifier
        .focusRequester(parentFocusRequester)
        .focusProperties {
            onExit = {
                parentFocusRequester.saveFocusedChild() // Сохраняем текущий фокус при выходе
                FocusRequester.Default
            }
            enter = {
                if (parentFocusRequester.restoreFocusedChild()) {
                    FocusRequester.Cancel // Если восстановили фокус - отменяем стандартное поведение
                } else {
                    childFocusRequester // Иначе фокусируемся на дочернем элементе
                }
            }
        }
    // 3. Модификатор для дочернего элемента
    val childModifier = Modifier.focusRequester(childFocusRequester)
    val x2 =  FocusRequesterModifiers(parentModifier, childModifier)
    //ALL CONTAINER FOCUS HANDLE
    Column(modifier = x2.parentModifier.fillMaxSize().focusGroup()/*FOCUS_GROUP*/) {
        if (uiState.isLoading && uiState.movies.isEmpty()) {
            LoadingViewTv(modifier = Modifier.fillMaxSize())
        } else if (uiState.error != null && uiState.movies.isEmpty()) {
            val backToUpOrHomeModifier = Modifier.focusProperties {
                onFocusBackToTab?.let { up = it }
                homeLeft?.let { left = it }
            }
            ErrorViewTv(
                modifier = backToUpOrHomeModifier,
                message = uiState.error ?: "",
                onRetry = {
                    viewModel.refreshMovies()
                })
        } else {
            var lastFocusedIndex by remember { mutableStateOf<Int?>(0) }
            LazyVerticalGrid(
                columns = GridCells.Fixed(GRID_COLUMN_COUNT),
                contentPadding = PaddingValues(16.dp),
                verticalArrangement = Arrangement.spacedBy(16.dp),
                horizontalArrangement = Arrangement.spacedBy(16.dp),
                modifier = Modifier.fillMaxSize().focusGroup(),//@@@@
                content = {
                    itemsIndexed(uiState.movies) { index, movie ->
                        val modifier = Modifier.focusEdges(
                            index = index,
                            gridColumnCount = GRID_COLUMN_COUNT,
                            homeLeft = homeLeft,
                            homeRight = homeRight,
                            scope = scope,
                            onFocusBackToTab = onFocusBackToTab
                        )
                        AnimatedVisibility(
                            visible = true,
                            enter = fadeIn(
                                animationSpec = spring(
                                    dampingRatio = Spring.DampingRatioMediumBouncy,
                                    stiffness = Spring.StiffnessLow
                                )
                            ),
                            exit = fadeOut()
                        ) {
                            MovieCardTv(
                                modifier = modifier.then(if (index == lastFocusedIndex) x2.childModifier else Modifier)
                                    .onFocusChanged { state ->
                                    if (state.isFocused) {
                                        lastFocusedIndex = index
                                    }
                                },
                                movie = movie,
                                onClick = { onMovieClick(movie) }
                            )
//                            LaunchedEffect(lastFocusedIndex) {
//                                if (lastFocusedIndex == index) {
//                                    itemFocusRequester.requestFocus()
//                                }
//                            }
                        }
                    }
                    if (uiState.isLoadingMore) {
                        item(span = { GridItemSpan(maxLineSpan) }) {
                            Box(
                                modifier = Modifier
                                    .fillMaxWidth()
                                    .padding(16.dp),
                                contentAlignment = Alignment.Center
                            ) {
                                LoadingViewTv(
                                    style = MaterialTheme.typography.bodyLarge
                                )
                            }
                        }
                    }
                },
                state = gridState
            )
            LaunchedEffect(Unit) {
                parentFocusRequester.requestFocus(scope = scope)
            }
        }
    }
}
fun Modifier.focusEdges(
    index: Int,
    gridColumnCount: Int,
    homeLeft: FocusRequester? = null,
    homeRight: FocusRequester? = null,
    scope: CoroutineScope,
    onFocusBackToTab: FocusRequester? = null
): Modifier {
    var m = this
    if (onFocusBackToTab != null && index < gridColumnCount) {
        m = m.focusProperties { up = onFocusBackToTab }
    }
    m = m.onKeyEvent { keyEvent ->
        if (keyEvent.type != KeyEventType.KeyDown) return@onKeyEvent false
        when (keyEvent.key) {
            Key.DirectionLeft -> {
                if (index % gridColumnCount == 0 && homeLeft != null) {
                    homeLeft.requestFocus(scope = scope)
                    true
                } else false
            }
            Key.DirectionRight -> {
                if ((index + 1) % gridColumnCount == 0 && homeRight != null) {
                    homeRight.requestFocus(scope = scope)
                    true
                } else false
            }
            else -> false
        }
    }
    return m
}
//@Composable
//fun <T>CG0(
//    state: LazyGridState,
//    items: List<T>,
//    content: LazyGridScope.() -> Unit
//) {
//    LazyVerticalGrid(
//        columns = GridCells.Fixed(GRID_COLUMN_COUNT),
//        contentPadding = PaddingValues(16.dp),
//        verticalArrangement = Arrangement.spacedBy(16.dp),
//        horizontalArrangement = Arrangement.spacedBy(16.dp),
//        modifier = Modifier.fillMaxSize(),
//        state = state,
//        content = content
//    )
//}
@Composable
fun CinemaLazyVerticalGrid(
    state: LazyGridState,
    content: LazyGridScope.() -> Unit
) {
    LazyVerticalGrid(
        columns = GridCells.Fixed(GRID_COLUMN_COUNT),
        contentPadding = PaddingValues(16.dp),
        verticalArrangement = Arrangement.spacedBy(16.dp),
        horizontalArrangement = Arrangement.spacedBy(16.dp),
        modifier = Modifier.fillMaxSize(),
        state = state,
        content = content
    )
}
//@Composable
//fun TvAdaptiveGrid(
//    items: List<Any>,
//    state: LazyGridState,
//    content: @Composable (item: Any, index: Int) -> Unit,
//    home: FocusRequester? = null,
//) {
//    CG0(state = state) {
//        itemsIndexed(items) { index, item ->
//            content(item, index)
//        }
//    }
//}
/**
 * Стандартная адаптивная сетка для TV
 */
@Composable
fun TvAdaptiveGridDefault(
    items: List<Any>,
    modifier: Modifier = Modifier,
    contentPadding: PaddingValues = tvScreenPadding,
    horizontalArrangement: androidx.compose.foundation.layout.Arrangement.Horizontal = androidx.compose.foundation.layout.Arrangement.spacedBy(
        tvCardSpacing
    ),
    verticalArrangement: androidx.compose.foundation.layout.Arrangement.Vertical = androidx.compose.foundation.layout.Arrangement.spacedBy(
        tvCardSpacing
    ),
    content: @Composable (item: Any, index: Int) -> Unit
) {
    LazyVerticalGrid(
        columns = GridCells.Adaptive(minSize = TvSizes.GRID_MIN_SIZE.dp),
        contentPadding = contentPadding,
        horizontalArrangement = horizontalArrangement,
        verticalArrangement = verticalArrangement,
        modifier = modifier
    ) {
        itemsIndexed(items) { index, item ->
            content(item, index)
        }
    }
}