package com.optix.android.ui.navigation

import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Hub
import androidx.compose.material.icons.filled.Psychology
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.foundation.layout.padding
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import com.optix.android.data.repository.SettingsRepositoryImpl
import com.optix.android.ui.screens.ai.AiScreen
import com.optix.android.ui.screens.ai.AiViewModel
import com.optix.android.ui.screens.disclaimer.DisclaimerScreen
import com.optix.android.ui.screens.lanmap.LanMapScreen
import com.optix.android.ui.screens.lanmap.LanMapViewModel
import kotlinx.coroutines.launch

sealed class Screen(val route: String, val label: String, val icon: ImageVector) {
    data object Network : Screen("network", "CONSOLE", Icons.Default.Hub)
    data object Chat : Screen("chat", "BRAIN", Icons.Default.Psychology)
}

@Composable
fun AppNavigation(settingsRepository: SettingsRepositoryImpl) {
    val disclaimerAccepted by settingsRepository.disclaimerAccepted().collectAsState(initial = null)
    val scope = rememberCoroutineScope()

    if (disclaimerAccepted == null) return
    if (disclaimerAccepted == false) {
        DisclaimerScreen(onAccept = { scope.launch { settingsRepository.acceptDisclaimer() } })
        return
    }

    val navController = rememberNavController()
    val lanMapViewModel: LanMapViewModel = hiltViewModel()
    val aiViewModel: AiViewModel = hiltViewModel()

    val mapState by lanMapViewModel.uiState.collectAsState()
    val aiState by aiViewModel.uiState.collectAsState()

    val runningByRoute = mapOf(
        Screen.Network.route to (mapState.scanning || mapState.portScanning.isNotEmpty() || mapState.isRunning),
        Screen.Chat.route to aiState.isStreaming,
    )

    fun navigate(screen: Screen) = navController.navigate(screen.route) {
        popUpTo(navController.graph.findStartDestination().id) { saveState = true }
        launchSingleTop = true
        restoreState = true
    }

    Scaffold(containerColor = MaterialTheme.colorScheme.background) { innerPadding ->
        NavHost(
            navController = navController,
            startDestination = Screen.Chat.route,
            modifier = Modifier.padding(innerPadding),
        ) {
            composable(Screen.Network.route) {
                LanMapScreen(
                    viewModel = lanMapViewModel,
                    currentScreen = Screen.Network,
                    runningByRoute = runningByRoute,
                    onNavigate = ::navigate,
                )
            }
            composable(Screen.Chat.route) {
                AiScreen(
                    viewModel = aiViewModel,
                    settingsRepository = settingsRepository,
                    currentScreen = Screen.Chat,
                    runningByRoute = runningByRoute,
                    onNavigate = ::navigate,
                )
            }
        }
    }
}
