package com.tangem.feature.tester.presentation

import androidx.compose.foundation.layout.systemBarsPadding
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import com.google.accompanist.systemuicontroller.rememberSystemUiController
import com.tangem.common.routing.AppRouter
import com.tangem.core.navigation.finisher.AppFinisher
import com.tangem.core.ui.UiDependencies
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.screen.ComposeActivity
import com.tangem.feature.tester.presentation.accounts.ui.AccountsScreen
import com.tangem.feature.tester.presentation.accounts.viewmodel.TesterAccountsViewModel
import com.tangem.feature.tester.presentation.actions.TesterActionsScreen
import com.tangem.feature.tester.presentation.actions.TesterActionsViewModel
import com.tangem.feature.tester.presentation.addresses.ui.AddressesInfoScreen
import com.tangem.feature.tester.presentation.addresses.viewmodels.AddressesInfoViewModel
import com.tangem.feature.tester.presentation.backendauth.ui.BackendAuthStatusScreen
import com.tangem.feature.tester.presentation.backendauth.viewmodels.BackendAuthStatusViewModel
import com.tangem.feature.tester.presentation.environments.ui.EnvironmentTogglesScreen
import com.tangem.feature.tester.presentation.environments.viewmodels.EnvironmentsTogglesViewModel
import com.tangem.feature.tester.presentation.excludedblockchains.ExcludedBlockchainsScreen
import com.tangem.feature.tester.presentation.excludedblockchains.ExcludedBlockchainsViewModel
import com.tangem.feature.tester.presentation.featuretoggles.ui.FeatureTogglesScreen
import com.tangem.feature.tester.presentation.featuretoggles.viewmodels.FeatureTogglesViewModel
import com.tangem.feature.tester.presentation.menu.state.TesterMenuUM
import com.tangem.feature.tester.presentation.menu.state.TesterMenuUM.ButtonUM
import com.tangem.feature.tester.presentation.menu.ui.TesterMenuScreen
import com.tangem.feature.tester.presentation.navigation.InnerTesterRouter
import com.tangem.feature.tester.presentation.navigation.TesterScreen
import com.tangem.feature.tester.presentation.providers.ui.BlockchainProvidersScreen
import com.tangem.feature.tester.presentation.providers.viewmodel.BlockchainProvidersViewModel
import com.tangem.feature.tester.presentation.sellredirect.ui.SellRedirectGeneratorScreen
import com.tangem.feature.tester.presentation.sellredirect.viewmodels.SellRedirectGeneratorViewModel
import com.tangem.feature.tester.presentation.storybook.ui.StoryBookScreen
import com.tangem.feature.tester.presentation.storybook.viewmodel.StoryBookViewModel
import com.tangem.feature.tester.presentation.testpush.ui.TestPushScreen
import com.tangem.feature.tester.presentation.testpush.viewmodel.TestPushViewModel
import com.tangem.features.survey.SurveyLaunchData
import com.tangem.features.survey.SurveySparrowLauncher
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.collections.immutable.persistentSetOf
import javax.inject.Inject

/** Activity for testers */
@AndroidEntryPoint
internal class TesterActivity : ComposeActivity() {

    @Inject
    override lateinit var uiDependencies: UiDependencies

    @Inject
    lateinit var innerTesterRouter: InnerTesterRouter

    @Inject
    lateinit var appFinisher: AppFinisher

    @Inject
    lateinit var appRouter: AppRouter

    @Inject
    lateinit var surveySparrowLauncher: SurveySparrowLauncher

    @Composable
    override fun ScreenContent(modifier: Modifier) {
        val systemBarsColor = TangemTheme.colors.background.secondary
        val systemUiController = rememberSystemUiController()
        systemUiController.setSystemBarsColor(systemBarsColor)

        TesterNavHost()
    }

    @Suppress("TopLevelComposableFunctions", "LongMethod", "CyclomaticComplexMethod")
    @Composable
    private fun TesterNavHost() {
        val navController = rememberNavController().also { innerTesterRouter.setNavController(it) }

        NavHost(
            modifier = Modifier.systemBarsPadding(),
            navController = navController,
            startDestination = TesterScreen.MENU.name,
        ) {
            composable(route = TesterScreen.MENU.name) {
                TesterMenuScreen(
                    state = TesterMenuUM(
                        onBackClick = { appRouter.pop { finish() } },
                        buttons = persistentSetOf(
                            ButtonUM.FEATURE_TOGGLES,
                            ButtonUM.EXCLUDED_BLOCKCHAINS,
                            ButtonUM.ENVIRONMENT_TOGGLES,
                            ButtonUM.BLOCKCHAIN_PROVIDERS,
                            ButtonUM.TESTER_ACTIONS,
                            ButtonUM.TEST_PUSHES,
                            ButtonUM.ACCOUNTS,
                            ButtonUM.ADDRESSES_INFO,
                            ButtonUM.STORY_BOOK,
                            ButtonUM.SURVEY_SPARROW,
                            ButtonUM.BACKEND_AUTH_STATUS,
                            ButtonUM.SELL_REDIRECT_GENERATOR,
                        ),
                        onButtonClick = { buttonUM ->
                            val route = when (buttonUM) {
                                ButtonUM.FEATURE_TOGGLES -> TesterScreen.FEATURE_TOGGLES
                                ButtonUM.EXCLUDED_BLOCKCHAINS -> TesterScreen.EXCLUDED_BLOCKCHAINS
                                ButtonUM.ENVIRONMENT_TOGGLES -> TesterScreen.ENVIRONMENTS_TOGGLES
                                ButtonUM.BLOCKCHAIN_PROVIDERS -> TesterScreen.BLOCKCHAIN_PROVIDERS
                                ButtonUM.TESTER_ACTIONS -> TesterScreen.TESTER_ACTIONS
                                ButtonUM.TEST_PUSHES -> TesterScreen.TEST_PUSHES
                                ButtonUM.ACCOUNTS -> TesterScreen.ACCOUNTS
                                ButtonUM.ADDRESSES_INFO -> TesterScreen.ADDRESSES_INFO
                                ButtonUM.STORY_BOOK -> TesterScreen.STORY_BOOK
                                ButtonUM.SURVEY_SPARROW -> TesterScreen.SURVEY_SPARROW
                                ButtonUM.BACKEND_AUTH_STATUS -> TesterScreen.BACKEND_AUTH_STATUS
                                ButtonUM.SELL_REDIRECT_GENERATOR -> TesterScreen.SELL_REDIRECT_GENERATOR
                            }

                            innerTesterRouter.open(route)
                        },
                    ),
                )
            }

            composable(route = TesterScreen.FEATURE_TOGGLES.name) {
                val viewModel = hiltViewModel<FeatureTogglesViewModel>().apply {
                    setupInteractions(innerTesterRouter, appFinisher)
                }

                val state by viewModel.state.collectAsStateWithLifecycle()
                FeatureTogglesScreen(state = state)
            }

            composable(route = TesterScreen.ENVIRONMENTS_TOGGLES.name) {
                val viewModel = hiltViewModel<EnvironmentsTogglesViewModel>().apply {
                    setupNavigation(innerTesterRouter)
                }

                EnvironmentTogglesScreen(
                    uiModel = viewModel.uiState.collectAsState().value,
                )
            }

            composable(route = TesterScreen.TESTER_ACTIONS.name) {
                val viewModel = hiltViewModel<TesterActionsViewModel>().apply {
                    setupNavigation(innerTesterRouter)
                }

                TesterActionsScreen(state = viewModel.uiState)
            }

            composable(route = TesterScreen.EXCLUDED_BLOCKCHAINS.name) {
                val viewModel = hiltViewModel<ExcludedBlockchainsViewModel>().apply {
                    setupNavigation(innerTesterRouter, appFinisher)
                }

                val state by viewModel.state.collectAsStateWithLifecycle()
                ExcludedBlockchainsScreen(state = state)
            }

            composable(route = TesterScreen.BLOCKCHAIN_PROVIDERS.name) {
                val viewModel = hiltViewModel<BlockchainProvidersViewModel>().apply {
                    setupNavigation(innerTesterRouter, appFinisher)
                }

                val state by viewModel.state.collectAsStateWithLifecycle()
                BlockchainProvidersScreen(state)
            }

            composable(route = TesterScreen.TEST_PUSHES.name) {
                val viewModel = hiltViewModel<TestPushViewModel>().apply {
                    setupNavigation(innerTesterRouter)
                }
                val state by viewModel.uiState.collectAsStateWithLifecycle()

                TestPushScreen(state, viewModel)
            }

            composable(route = TesterScreen.ACCOUNTS.name) {
                val viewModel = hiltViewModel<TesterAccountsViewModel>().apply {
                    setupNavigation(innerTesterRouter)
                }
                val state by viewModel.uiState.collectAsStateWithLifecycle()

                AccountsScreen(state)
            }

            composable(route = TesterScreen.ADDRESSES_INFO.name) {
                val viewModel = hiltViewModel<AddressesInfoViewModel>()

                LaunchedEffect(viewModel) {
                    viewModel.setupNavigation(innerTesterRouter)
                }

                val state by viewModel.uiState.collectAsStateWithLifecycle()

                AddressesInfoScreen(state)
            }

            composable(route = TesterScreen.STORY_BOOK.name) {
                val viewModel = hiltViewModel<StoryBookViewModel>().apply {
                    setupNavigation(innerTesterRouter)
                }
                val state by viewModel.uiState.collectAsStateWithLifecycle()

                StoryBookScreen(state)
            }

            composable(route = TesterScreen.SURVEY_SPARROW.name) {
                LaunchedEffect(Unit) {
                    val isSuccess = startSurveySparrow()
                    if (isSuccess) {
                        innerTesterRouter.back()
                    }
                }
            }

            composable(route = TesterScreen.BACKEND_AUTH_STATUS.name) {
                val viewModel = hiltViewModel<BackendAuthStatusViewModel>().apply {
                    setupNavigation(innerTesterRouter)
                }
                val state by viewModel.uiState.collectAsStateWithLifecycle()

                BackendAuthStatusScreen(state)
            }

            composable(route = TesterScreen.SELL_REDIRECT_GENERATOR.name) {
                val viewModel = hiltViewModel<SellRedirectGeneratorViewModel>().apply {
                    setupNavigation(innerTesterRouter)
                }
                val state by viewModel.uiState.collectAsStateWithLifecycle()

                SellRedirectGeneratorScreen(state)
            }
        }
    }

    private fun startSurveySparrow(): Boolean {
        surveySparrowLauncher.present(
            activity = this,
            data = SurveyLaunchData(domain = DOMAIN, token = TEST_SHARE_TOKEN, customParams = emptyMap()),
        )

        return true
    }

    private companion object {
        const val DOMAIN = "tangem.surveysparrow.com"
        const val TEST_SHARE_TOKEN = "ntt-84iF22PDajmervYneMW4kv"
    }
}