package de.tsschulz.timeclock

import android.graphics.Color
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.widget.TextView
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateOf
import androidx.core.view.WindowCompat
import androidx.lifecycle.viewmodel.compose.viewModel
import de.tsschulz.timeclock.ui.TimeClockApp
import de.tsschulz.timeclock.ui.admin.AdminViewModel
import de.tsschulz.timeclock.ui.auth.AuthViewModel
import de.tsschulz.timeclock.ui.booking.BookingViewModel
import de.tsschulz.timeclock.ui.settings.SettingsViewModel
import de.tsschulz.timeclock.ui.theme.TimeClockTheme
import de.tsschulz.timeclock.ui.time.TimeViewModel

class MainActivity : ComponentActivity() {
    private val oauthCallback = mutableStateOf<OAuthCallback?>(null)

    @Suppress("DEPRECATION")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        oauthCallback.value = intent.toOAuthCallback()
        Log.i(TAG, "MainActivity.onCreate")
        window.statusBarColor = Color.rgb(240, 255, 236)
        window.navigationBarColor = Color.WHITE
        try {
            setContent {
                val authViewModel: AuthViewModel = viewModel(factory = AuthViewModel.Factory(application))
                val timeViewModel: TimeViewModel = viewModel(factory = TimeViewModel.Factory(application))
                val bookingViewModel: BookingViewModel = viewModel(factory = BookingViewModel.Factory(application))
                val settingsViewModel: SettingsViewModel = viewModel(factory = SettingsViewModel.Factory(application))
                val adminViewModel: AdminViewModel = viewModel(factory = AdminViewModel.Factory(application))
                val callback = oauthCallback.value
                LaunchedEffect(callback) {
                    when (callback) {
                        is OAuthCallback.Token -> {
                            authViewModel.completeOAuthToken(callback.token)
                            oauthCallback.value = null
                        }
                        is OAuthCallback.Pending -> {
                            authViewModel.requireOAuthLink(callback.pendingToken, callback.email)
                            oauthCallback.value = null
                        }
                        null -> Unit
                    }
                }
                TimeClockTheme {
                    TimeClockApp(
                        authViewModel = authViewModel,
                        timeViewModel = timeViewModel,
                        bookingViewModel = bookingViewModel,
                        settingsViewModel = settingsViewModel,
                        adminViewModel = adminViewModel,
                    )
                }
            }
        } catch (e: Throwable) {
            Log.e(TAG, "Failed to create Compose content", e)
            setContentView(
                TextView(this).apply {
                    text = "Die App konnte nicht gestartet werden.\n${e.message.orEmpty()}"
                    setTextColor(Color.BLACK)
                    setBackgroundColor(Color.WHITE)
                    setPadding(32, 32, 32, 32)
                },
            )
        }
        window.decorView.post {
            val controller = WindowCompat.getInsetsController(window, window.decorView)
            controller.isAppearanceLightStatusBars = true
            controller.isAppearanceLightNavigationBars = true
        }
    }

    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        setIntent(intent)
        oauthCallback.value = intent.toOAuthCallback()
    }

    private fun Intent?.toOAuthCallback(): OAuthCallback? {
        val data = this?.data ?: return null
        if (data.scheme != "timeclock" || data.host != "oauth-callback") return null
        val token = data.getQueryParameter("token")
        if (!token.isNullOrBlank()) return OAuthCallback.Token(token)
        val pending = data.getQueryParameter("pending")
        if (!pending.isNullOrBlank()) return OAuthCallback.Pending(pending, data.getQueryParameter("email"))
        return null
    }

    private companion object {
        const val TAG = "TimeClockStartup"
    }
}

private sealed class OAuthCallback {
    data class Token(val token: String) : OAuthCallback()
    data class Pending(val pendingToken: String, val email: String?) : OAuthCallback()
}
