package com.anypreta.bountyboard.ui.nav

import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.compose.ui.Modifier
import com.anypreta.bountyboard.data.AppContainer
import com.anypreta.bountyboard.di.LocalAppContainer
import com.anypreta.bountyboard.di.containerVMFactory
import com.anypreta.bountyboard.ui.auth.AuthFlow
import com.anypreta.bountyboard.ui.auth.ForcedChangePasswordScreen
import com.anypreta.bountyboard.ui.components.LoadingBox
import com.anypreta.bountyboard.ui.theme.BB
import kotlinx.coroutines.launch

class RootViewModel(private val container: AppContainer) : ViewModel() {
    var booted by mutableStateOf(false)
        private set

    init {
        bootstrap()
    }

    fun bootstrap() {
        viewModelScope.launch {
            try {
                val r = container.repo.call { me() }
                container.session.setSession(r.user, r.mustChangePassword, r.oidcEnabled)
            } catch (_: Exception) {
                container.session.clear()
            } finally {
                booted = true
            }
        }
    }
}

@Composable
fun AppRoot() {
    val container = LocalAppContainer.current
    val vm: RootViewModel = viewModel(factory = containerVMFactory(container) { RootViewModel(it) })
    val user by container.session.user.collectAsStateWithLifecycle()
    val mustChange by container.session.mustChangePassword.collectAsStateWithLifecycle()

    Surface(color = BB.colors.bg, modifier = Modifier.fillMaxSize()) {
        when {
            !vm.booted -> LoadingBox()
            user == null -> AuthFlow()
            mustChange -> ForcedChangePasswordScreen()
            else -> MainShell()
        }
    }
}
