package com.tangem.feature.tester.presentation.featuretoggles.ui

import android.content.res.Configuration
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.util.fastForEachIndexed
import com.tangem.core.ui.components.PrimaryButton
import com.tangem.core.ui.components.TangemSwitch
import com.tangem.core.ui.components.divider.DividerWithPadding
import com.tangem.core.ui.ds2.search.TangemSearch
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.extensions.wrappedList
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.feature.tester.impl.R
import com.tangem.feature.tester.presentation.common.components.appbar.TopBarWithRefresh
import com.tangem.feature.tester.presentation.common.components.appbar.TopBarWithRefreshUM
import com.tangem.feature.tester.presentation.common.components.notification.CustomSetupNotification
import com.tangem.feature.tester.presentation.common.components.notification.InitialSetupNotification
import com.tangem.feature.tester.presentation.featuretoggles.state.FeatureToggleGroupUM
import com.tangem.feature.tester.presentation.featuretoggles.state.TesterFeatureToggleUM
import com.tangem.feature.tester.presentation.featuretoggles.state.FeatureTogglesScreenUM
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList

private val RESTART_BUTTON_OVERLAY_HEIGHT = 80.dp

/**
 * Screen with feature toggles list
 *
 * @param state screen state
 */
@OptIn(ExperimentalFoundationApi::class)
@Composable
internal fun FeatureTogglesScreen(state: FeatureTogglesScreenUM) {
    Box(
        modifier = Modifier
            .fillMaxSize()
            .background(TangemTheme.colors.background.secondary),
    ) {
        LazyColumn(
            modifier = Modifier.fillMaxSize(),
            contentPadding = PaddingValues(bottom = RESTART_BUTTON_OVERLAY_HEIGHT),
        ) {
            stickyHeader {
                Column(modifier = Modifier.background(TangemTheme.colors.background.secondary)) {
                    TopBarWithRefresh(state = state.topBar)
                    TangemSearch(
                        state = state.searchBar,
                        modifier = Modifier.padding(horizontal = 16.dp, vertical = 12.dp),
                    )
                }
            }

            customSetup(state.topBar, state.appVersion)

            emptySearch(state.featureToggleGroups, state.searchBar)

            featureTogglesList(state.featureToggleGroups, state.onToggleValueChange)
        }

        RestartButton(
            onRestartAppClick = state.onRestartAppClick,
            modifier = Modifier.align(Alignment.BottomCenter),
        )
    }
}

private fun LazyListScope.customSetup(topBar: TopBarWithRefreshUM, appVersion: String) {
    if (topBar.refreshButton.isVisible) {
        item(key = "warning_notification", contentType = "warning_notification") {
            CustomSetupNotification(
                subtitle = resourceReference(
                    id = R.string.feature_toggles_custom_setup_warning_description,
                    wrappedList(appVersion),
                ),
                modifier = Modifier
                    .animateItem()
                    .padding(horizontal = 16.dp, vertical = 8.dp),
            )
        }
    } else {
        item(key = "warning_notification", contentType = "warning_notification") {
            InitialSetupNotification(
                subtitle = resourceReference(
                    id = R.string.feature_toggles_initial_setup_warning_description,
                    wrappedList(appVersion),
                ),
                modifier = Modifier
                    .animateItem()
                    .padding(horizontal = 16.dp, vertical = 8.dp),
            )
        }
    }
}

private fun LazyListScope.emptySearch(featureToggleGroups: List<FeatureToggleGroupUM>, searchBar: TangemSearch.State) {
    if (featureToggleGroups.isEmpty() && searchBar.query.isNotBlank()) {
        item(key = "nothing_found", contentType = "nothing_found") {
            Text(
                text = stringResourceSafe(R.string.feature_toggles_no_feature_toggles_found),
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(TangemTheme.dimens.spacing16),
                color = TangemTheme.colors.text.tertiary,
                style = TangemTheme.typography.body2,
            )
        }
    }
}

@Composable
private fun RestartButton(onRestartAppClick: () -> Unit, modifier: Modifier = Modifier) {
    PrimaryButton(
        text = stringResourceSafe(id = R.string.restart_app),
        onClick = onRestartAppClick,
        modifier = modifier
            .fillMaxWidth()
            .background(TangemTheme.colors.background.secondary)
            .padding(TangemTheme.dimens.spacing16),
    )
}

private fun LazyListScope.featureTogglesList(
    featureToggleGroups: List<FeatureToggleGroupUM>,
    onToggleValueChange: (String, Boolean) -> Unit,
) {
    featureToggleGroups.fastForEachIndexed { index, group ->
        if (index != 0) {
            item(key = "divider_${group.status.name}", contentType = "group_divider") {
                DividerWithPadding(horizontal = 16.dp, vertical = 8.dp)
            }
        }

        item(key = "header_${group.status.name}", contentType = "group_header") {
            GroupHeader(title = "${group.status.emoji} ${group.status.title}")
        }

        items(
            items = group.toggles,
            key = TesterFeatureToggleUM::name,
            contentType = { "feature_toggle_item" },
        ) { featureToggle ->
            FeatureToggleItem(
                toggle = featureToggle,
                onCheckedChange = { isChange -> onToggleValueChange(featureToggle.name, isChange) },
            )
        }
    }
}

@Composable
private fun GroupHeader(title: String) {
    Text(
        text = title,
        modifier = Modifier
            .fillMaxWidth()
            .padding(
                horizontal = TangemTheme.dimens.spacing18,
                vertical = TangemTheme.dimens.spacing8,
            ),
        color = TangemTheme.colors.text.primary1,
        style = TangemTheme.typography.h3,
    )
}

@Composable
private fun FeatureToggleItem(toggle: TesterFeatureToggleUM, onCheckedChange: (Boolean) -> Unit) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .padding(
                horizontal = TangemTheme.dimens.spacing18,
                vertical = TangemTheme.dimens.spacing8,
            ),
        horizontalArrangement = Arrangement.SpaceBetween,
        verticalAlignment = Alignment.CenterVertically,
    ) {
        Column(modifier = Modifier.weight(1f)) {
            Text(
                text = toggle.name,
                color = TangemTheme.colors.text.primary1,
                overflow = TextOverflow.Ellipsis,
                maxLines = 1,
                style = TangemTheme.typography.body2,
            )
            Row(
                horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing4),
                verticalAlignment = Alignment.CenterVertically,
            ) {
                Text(
                    text = toggle.version,
                    color = TangemTheme.colors.text.tertiary,
                    overflow = TextOverflow.Ellipsis,
                    maxLines = 1,
                    style = TangemTheme.typography.caption2,
                )
                if (toggle.status == TesterFeatureToggleUM.Status.RELEASED && !toggle.isEnabled) {
                    Text(
                        text = "Disabled",
                        color = TangemTheme.colors.text.warning,
                        maxLines = 1,
                        style = TangemTheme.typography.caption2,
                    )
                }
            }
        }

        TangemSwitch(onCheckedChange = onCheckedChange, checked = toggle.isEnabled)
    }
}

@Preview
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun PreviewFeatureTogglesScreen() {
    TangemThemePreview {
        var isCustomSetup by remember { mutableStateOf(value = true) }

        FeatureTogglesScreen(
            state = FeatureTogglesScreenUM(
                topBar = TopBarWithRefreshUM(
                    titleResId = R.string.feature_toggles,
                    onBackClick = {},
                    refreshButton = TopBarWithRefreshUM.RefreshButton(
                        isVisible = isCustomSetup,
                        onRefreshClick = { isCustomSetup = false },
                    ),
                ),
                appVersion = "5.38",
                searchBar = TangemSearch.State(
                    placeholderText = stringReference(value = "Search"),
                    query = "",
                    onQueryChange = {},
                    isActive = false,
                    onActiveChange = {},
                ),
                featureToggleGroups = previewFeatureToggleGroups(),
                onToggleValueChange = { _, _ -> isCustomSetup = true },
                onRestartAppClick = {},
            ),
        )
    }
}

private fun previewFeatureToggleGroups(): ImmutableList<FeatureToggleGroupUM> {
    fun group(status: TesterFeatureToggleUM.Status, vararg toggles: Triple<String, String, Boolean>) =
        FeatureToggleGroupUM(
            status = status,
            toggles = toggles
                .map { (name, version, isEnabled) ->
                    TesterFeatureToggleUM(name = name, version = version, status = status, isEnabled = isEnabled)
                }
                .toImmutableList(),
        )

    return persistentListOf(
        group(TesterFeatureToggleUM.Status.PENDING, Triple("FEATURE_TOGGLE_2", "5.38", false)),
        group(TesterFeatureToggleUM.Status.PLANNED, Triple("FEATURE_TOGGLE_1", "5.40", true)),
        group(TesterFeatureToggleUM.Status.UNDEFINED, Triple("FEATURE_TOGGLE_4", "undefined", false)),
        group(
            TesterFeatureToggleUM.Status.RELEASED,
            Triple("FEATURE_TOGGLE_3", "5.15", true),
            Triple("FEATURE_TOGGLE_3_OFF", "5.15", false),
        ),
    )
}