package top.yeij.cyrene.ui.navigation

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.Chat
import androidx.compose.material.icons.filled.DevicesOther
import androidx.compose.material.icons.filled.Person
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.NavigationRail
import androidx.compose.material3.NavigationRailItem
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clipToBounds
import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import top.yeij.cyrene.ui.screens.chat.ChatScreen
import top.yeij.cyrene.ui.screens.iot.IoTScreen
import top.yeij.cyrene.ui.screens.login.LoginScreen
import top.yeij.cyrene.ui.screens.about.AboutScreen
import top.yeij.cyrene.ui.screens.profile.ProfileScreen
import top.yeij.cyrene.ui.screens.settings.KeepAlivePage
import top.yeij.cyrene.ui.screens.settings.SettingsScreen
import top.yeij.cyrene.util.RuntimeLog

object Routes {
    const val LOGIN = "login"
    const val MAIN = "main"
    const val CHAT = "chat"
    const val IOT = "iot"
    const val SETTINGS = "settings"
    const val ABOUT = "about"
    const val KEEP_ALIVE = "keep_alive"
}

@Composable
fun CyreneNavGraph(
    navController: NavHostController,
    startDestination: String,
    isDefaultAssistant: Boolean,
    onOpenAssistantSettings: () -> Unit,
) {
    // After process death, the NavController may restore a stale back stack
    // (e.g. showing SETTINGS instead of MAIN). Reset to the intended start.
    LaunchedEffect(Unit) {
        val entries = navController.currentBackStack.value
        val currentRoute = navController.currentDestination?.route
        RuntimeLog.general("nav", "NavGraph start — currentRoute=$currentRoute backStackSize=${entries.size}")
        if (entries.size > 1 && entries.first().destination.route != startDestination) {
            RuntimeLog.general("nav", "Resetting stale back stack to $startDestination")
            navController.popBackStack(startDestination, inclusive = true)
            navController.navigate(startDestination)
        }
    }

    NavHost(
        navController = navController,
        startDestination = startDestination,
    ) {
        composable(Routes.LOGIN) {
            LoginScreen(
                onLoginSuccess = {
                    navController.navigate(Routes.MAIN) {
                        popUpTo(Routes.LOGIN) { inclusive = true }
                    }
                },
            )
        }

        composable(Routes.MAIN) {
            MainScreen(
                navController = navController,
                isDefaultAssistant = isDefaultAssistant,
                onOpenAssistantSettings = onOpenAssistantSettings,
            )
        }

        composable(Routes.SETTINGS) {
            SettingsScreen(
                onBack = {
                    if (navController.currentDestination?.route == Routes.SETTINGS) {
                        navController.popBackStack()
                    }
                },
                onNavigateToKeepAlive = { navController.navigate(Routes.KEEP_ALIVE) },
            )
        }

        composable(Routes.KEEP_ALIVE) {
            KeepAlivePage(
                onBack = {
                    if (navController.currentDestination?.route == Routes.KEEP_ALIVE) {
                        navController.popBackStack()
                    }
                },
            )
        }

        composable(Routes.ABOUT) {
            AboutScreen(
                onBack = {
                    if (navController.currentDestination?.route == Routes.ABOUT) {
                        navController.popBackStack()
                    }
                },
            )
        }
    }
}

data class BottomNavItem(
    val label: String,
    val icon: @Composable () -> Unit,
    val route: String,
)

@Composable
fun MainScreen(
    navController: NavHostController,
    isDefaultAssistant: Boolean,
    onOpenAssistantSettings: () -> Unit,
) {
    val items = listOf(
        BottomNavItem(
            label = "对话",
            icon = { Icon(Icons.AutoMirrored.Filled.Chat, contentDescription = "对话") },
            route = Routes.CHAT,
        ),
        BottomNavItem(
            label = "设备",
            icon = { Icon(Icons.Filled.DevicesOther, contentDescription = "设备") },
            route = Routes.IOT,
        ),
        BottomNavItem(
            label = "我的",
            icon = { Icon(Icons.Filled.Person, contentDescription = "我的") },
            route = "profile",
        ),
    )

    var selectedTab by rememberSaveable { mutableIntStateOf(0) }

    Row(
        modifier = Modifier
            .fillMaxSize()
            .statusBarsPadding(),
    ) {
        NavigationRail {
            items.forEachIndexed { index, item ->
                NavigationRailItem(
                    selected = selectedTab == index,
                    onClick = {
                        selectedTab = index
                        RuntimeLog.general("nav", "Tab switched to ${item.label} (index=$index)")
                    },
                    icon = item.icon,
                    label = { Text(item.label) },
                )
            }
        }

        Box(
            modifier = Modifier
                .weight(1f)
                .fillMaxHeight()
                .clipToBounds()
                .background(MaterialTheme.colorScheme.background),
        ) {
            // Keep all tabs alive by offsetting hidden ones off-screen.
            // clipToBounds ensures they don't intercept touches outside the visible area.
            Box(
                modifier = Modifier
                    .fillMaxSize()
                    .offset(x = if (selectedTab == 0) 0.dp else 2000.dp),
            ) {
                ChatScreen()
            }
            Box(
                modifier = Modifier
                    .fillMaxSize()
                    .offset(x = if (selectedTab == 1) 0.dp else 2000.dp),
            ) {
                IoTScreen()
            }
            Box(
                modifier = Modifier
                    .fillMaxSize()
                    .offset(x = if (selectedTab == 2) 0.dp else 2000.dp),
            ) {
                ProfileScreen(
                    onNavigateToSettings = { navController.navigate(Routes.SETTINGS) },
                    onNavigateToAbout = { navController.navigate(Routes.ABOUT) },
                    onLogout = {
                        navController.navigate(Routes.LOGIN) {
                            popUpTo(Routes.MAIN) { inclusive = true }
                        }
                    },
                    onNavigateToLogin = {
                        navController.navigate(Routes.LOGIN)
                    },
                    isDefaultAssistant = isDefaultAssistant,
                    onOpenAssistantSettings = onOpenAssistantSettings,
                )
            }
        }
    }
}
