package net.buzzert.kordophonedroid.ui

import androidx.compose.material.AlertDialog
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.NavHost
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navDeepLink
import kotlinx.coroutines.flow.collectLatest
import net.buzzert.kordophone.backend.server.ChatRepository

import net.buzzert.kordophonedroid.data.AppContainer
import net.buzzert.kordophonedroid.ui.attachments.AttachmentViewer
import net.buzzert.kordophonedroid.ui.theme.KordophoneTheme
import net.buzzert.kordophonedroid.ui.conversationlist.ConversationListScreen
import net.buzzert.kordophonedroid.ui.messagelist.MessageListScreen
import net.buzzert.kordophonedroid.ui.settings.SettingsScreen

sealed class Destination(val route: String) {
    object ConversationList : Destination("conversations")

    object Settings : Destination("settings")

    object MessageList : Destination("messages/{id}") {
        fun createRoute(data: String) = "messages/$data"
    }

    object AttachmentViewer : Destination("attachment/{guid}") {
        fun createRoute(guid: String) = "attachment/$guid"
    }
}

val LocalNavController = compositionLocalOf<NavHostController> { error("No nav host") }

@Composable
fun ErrorDialog(title: String, body: String, onDismiss: () -> Unit) {
    AlertDialog(
        onDismissRequest = { onDismiss() },
        title = { Text(title) },
        text = { Text(body) },
        confirmButton = {
            Button(onClick = { onDismiss() }) {
                Text("OK")
            }
        }
    )
}

@Composable
fun KordophoneApp(
    appContainer: AppContainer = hiltViewModel(),
) {
    KordophoneTheme {
        val navController = rememberNavController()
        val errorVisible = remember { mutableStateOf<ChatRepository.Error?>(null)  }
        val error = appContainer.repository.errorEncounteredChannel.collectAsStateWithLifecycle(
            initialValue = null
        )
        
        LaunchedEffect(key1 = error.value) {
            errorVisible.value = error.value
        }

        CompositionLocalProvider(LocalNavController provides navController) {
            NavHost(
                navController = navController,
                startDestination = Destination.ConversationList.route,
            ) {
                composable(Destination.ConversationList.route) {
                    ConversationListScreen()
                }

                composable(
                    route = Destination.MessageList.route,
                    deepLinks = listOf(navDeepLink { uriPattern = "kordophone://messages/{id}" })
                ) {
                    val conversationID = it.arguments?.getString("id")!!
                    MessageListScreen(conversationGUID = conversationID)
                }

                composable(Destination.Settings.route) {
                    SettingsScreen()
                }

                composable(Destination.AttachmentViewer.route) {
                    val guid = it.arguments?.getString("guid")!!
                    AttachmentViewer(attachmentGuid = guid)
                }
            }
        }

        errorVisible.value?.let {
            ErrorDialog(title = it.title, body = it.description) {
                errorVisible.value = null
            }
        }
    }
}