package com.atridad.openclimb.ui

import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import androidx.navigation.toRoute
import com.atridad.openclimb.data.database.OpenClimbDatabase
import com.atridad.openclimb.data.repository.ClimbRepository
import com.atridad.openclimb.navigation.Screen
import com.atridad.openclimb.navigation.bottomNavigationItems
import com.atridad.openclimb.ui.screens.*
import com.atridad.openclimb.ui.viewmodel.ClimbViewModel
import com.atridad.openclimb.ui.viewmodel.ClimbViewModelFactory

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun OpenClimbApp() {
    val navController = rememberNavController()
    val context = LocalContext.current
    val currentBackStackEntry by navController.currentBackStackEntryAsState()
    val currentDestination = currentBackStackEntry?.destination?.route
    
    val database = remember { OpenClimbDatabase.getDatabase(context) }
    val repository = remember { ClimbRepository(database, context) }
    val viewModel: ClimbViewModel = viewModel(
        factory = ClimbViewModelFactory(repository)
    )
    
    // FAB configuration
    var fabConfig by remember { mutableStateOf<FabConfig?>(null) }

    Scaffold(
        bottomBar = {
            OpenClimbBottomNavigation(navController = navController)
        },
        floatingActionButton = {
            fabConfig?.let { config ->
                FloatingActionButton(
                    onClick = config.onClick,
                    containerColor = MaterialTheme.colorScheme.primary
                ) {
                    Icon(
                        imageVector = config.icon,
                        contentDescription = config.contentDescription
                    )
                }
            }
        }
    ) { innerPadding ->
        NavHost(
            navController = navController,
            startDestination = Screen.Sessions,
            modifier = Modifier.padding(innerPadding)
        ) {
            // Main screens
            composable<Screen.Sessions> {
                val gyms by viewModel.gyms.collectAsState()
                val activeSession by viewModel.activeSession.collectAsState()
                LaunchedEffect(gyms, activeSession) {
                    fabConfig = if (gyms.isNotEmpty() && activeSession == null) {
                        FabConfig(
                            icon = Icons.Default.Add,
                            contentDescription = "Start Session",
                            onClick = { 
                                if (gyms.size == 1) {
                                    viewModel.startSession(context, gyms.first().id)
                                } else {
                                    navController.navigate(Screen.AddEditSession())
                                }
                            }
                        )
                    } else {
                        null
                    }
                }
                SessionsScreen(
                    viewModel = viewModel,
                    onNavigateToSessionDetail = { sessionId ->
                        navController.navigate(Screen.SessionDetail(sessionId))
                    },
                    onNavigateToAddSession = { gymId ->
                        navController.navigate(Screen.AddEditSession(gymId = gymId))
                    }
                )
            }
            
            composable<Screen.Problems> {
                val gyms by viewModel.gyms.collectAsState()
                LaunchedEffect(gyms) {
                    fabConfig = if (gyms.isNotEmpty()) {
                        FabConfig(
                            icon = Icons.Default.Add,
                            contentDescription = "Add Problem",
                            onClick = { 
                                navController.navigate(Screen.AddEditProblem())
                            }
                        )
                    } else {
                        null
                    }
                }
                ProblemsScreen(
                    viewModel = viewModel,
                    onNavigateToProblemDetail = { problemId ->
                        navController.navigate(Screen.ProblemDetail(problemId))
                    },
                    onNavigateToAddProblem = { gymId ->
                        navController.navigate(Screen.AddEditProblem(gymId = gymId))
                    }
                )
            }
            
            composable<Screen.Analytics> {
                LaunchedEffect(Unit) {
                    fabConfig = null // No FAB for analytics
                }
                AnalyticsScreen(viewModel = viewModel)
            }
            
            composable<Screen.Gyms> {
                LaunchedEffect(Unit) {
                    fabConfig = FabConfig(
                        icon = Icons.Default.Add,
                        contentDescription = "Add Gym",
                        onClick = { 
                            navController.navigate(Screen.AddEditGym())
                        }
                    )
                }
                GymsScreen(
                    viewModel = viewModel,
                    onNavigateToGymDetail = { gymId ->
                        navController.navigate(Screen.GymDetail(gymId))
                    },
                    onNavigateToAddGym = {
                        navController.navigate(Screen.AddEditGym())
                    }
                )
            }
            
            composable<Screen.Settings> {
                LaunchedEffect(Unit) {
                    fabConfig = null // No FAB for settings
                }
                SettingsScreen(viewModel = viewModel)
            }
            
            // Detail screens
            composable<Screen.SessionDetail> { backStackEntry ->
                val args = backStackEntry.toRoute<Screen.SessionDetail>()
                SessionDetailScreen(
                    sessionId = args.sessionId,
                    viewModel = viewModel,
                    onNavigateBack = { navController.popBackStack() },
                    onNavigateToEdit = { sessionId ->
                        navController.navigate(Screen.AddEditSession(sessionId = sessionId))
                    }
                )
            }
            
            composable<Screen.ProblemDetail> { backStackEntry ->
                val args = backStackEntry.toRoute<Screen.ProblemDetail>()
                ProblemDetailScreen(
                    problemId = args.problemId,
                    viewModel = viewModel,
                    onNavigateBack = { navController.popBackStack() },
                    onNavigateToEdit = { problemId ->
                        navController.navigate(Screen.AddEditProblem(problemId = problemId))
                    }
                )
            }
            
            composable<Screen.GymDetail> { backStackEntry ->
                val args = backStackEntry.toRoute<Screen.GymDetail>()
                GymDetailScreen(
                    gymId = args.gymId,
                    viewModel = viewModel,
                    onNavigateBack = { navController.popBackStack() },
                    onNavigateToEdit = { gymId ->
                        navController.navigate(Screen.AddEditGym(gymId = gymId))
                    }
                )
            }
            

            composable<Screen.AddEditGym> { backStackEntry ->
                val args = backStackEntry.toRoute<Screen.AddEditGym>()
                AddEditGymScreen(
                    gymId = args.gymId,
                    viewModel = viewModel,
                    onNavigateBack = { navController.popBackStack() }
                )
            }
            
            composable<Screen.AddEditProblem> { backStackEntry ->
                val args = backStackEntry.toRoute<Screen.AddEditProblem>()
                AddEditProblemScreen(
                    problemId = args.problemId,
                    gymId = args.gymId,
                    viewModel = viewModel,
                    onNavigateBack = { navController.popBackStack() }
                )
            }
            
            composable<Screen.AddEditSession> { backStackEntry ->
                val args = backStackEntry.toRoute<Screen.AddEditSession>()
                AddEditSessionScreen(
                    sessionId = args.sessionId,
                    gymId = args.gymId,
                    viewModel = viewModel,
                    onNavigateBack = { navController.popBackStack() }
                )
            }
        }
    }
}

@Composable
fun OpenClimbBottomNavigation(navController: NavHostController) {
    val navBackStackEntry by navController.currentBackStackEntryAsState()
    val currentRoute = navBackStackEntry?.destination?.route
    
    NavigationBar {
        bottomNavigationItems.forEach { item ->
            val isSelected = when (item.screen) {
                is Screen.Sessions -> currentRoute?.contains("Session") == true
                is Screen.Problems -> currentRoute?.contains("Problem") == true  
                is Screen.Gyms -> currentRoute?.contains("Gym") == true
                is Screen.Analytics -> currentRoute?.contains("Analytics") == true
                is Screen.Settings -> currentRoute?.contains("Settings") == true
                else -> currentRoute?.contains(item.screen::class.simpleName ?: "") == true
            }
            
            NavigationBarItem(
                icon = { Icon(item.icon, contentDescription = item.label) },
                label = { Text(item.label) },
                selected = isSelected,
                onClick = {
                    navController.navigate(item.screen) {
                        // Pop up to the start destination of the graph to
                        // avoid building up a large stack of destinations
                        // on the back stack as users select items
                        popUpTo(Screen.Sessions) {
                            saveState = true
                        }
                        // Avoid multiple copies of the same destination when
                        // reselecting the same item
                        launchSingleTop = true
                        // Restore state when reselecting a previously selected item
                        restoreState = true
                    }
                }
            )
        }
    }
}

data class FabConfig(
    val icon: androidx.compose.ui.graphics.vector.ImageVector,
    val contentDescription: String,
    val onClick: () -> Unit
)


