package de.oaa.xxx.app.ui.viewmodel

import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.viewModelScope
import de.oaa.xxx.app.data.api.ApiClient
import de.oaa.xxx.app.data.local.TokenStore
import de.oaa.xxx.app.data.model.RegistrationRequest
import de.oaa.xxx.app.data.model.User
import de.oaa.xxx.app.util.sha256
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch

sealed class AuthState {
    object Idle : AuthState()
    object Loading : AuthState()
    data class LoggedIn(val user: User) : AuthState()
    object LoggedOut : AuthState()
    data class Registered(val message: String) : AuthState()
    data class Error(val message: String) : AuthState()
}

class AuthViewModel(application: Application) : AndroidViewModel(application) {

    private val tokenStore = TokenStore(application)
    private val _state = MutableStateFlow<AuthState>(AuthState.Idle)
    val state: StateFlow<AuthState> = _state

    init {
        checkSession()
    }

    private fun checkSession() {
        viewModelScope.launch {
            val token = tokenStore.jwtToken.first()
            if (token != null) {
                ApiClient.setJwtToken(token)
                val resp = runCatching { ApiClient.authApi.me() }.getOrNull()
                if (resp?.isSuccessful == true && resp.body() != null) {
                    _state.value = AuthState.LoggedIn(resp.body()!!)
                } else {
                    tokenStore.clear()
                    _state.value = AuthState.LoggedOut
                }
            } else {
                _state.value = AuthState.LoggedOut
            }
        }
    }

    fun login(email: String, password: String) {
        viewModelScope.launch {
            _state.value = AuthState.Loading
            try {
                val hash = sha256(password)
                val resp = ApiClient.authApi.login(email, hash)
                if (resp.isSuccessful && resp.body() != null) {
                    val user = resp.body()!!
                    val jwt = ApiClient.getJwtToken()
                    if (jwt != null) tokenStore.saveToken(jwt)
                    tokenStore.saveUser(user.userId ?: "", user.name ?: "")
                    _state.value = AuthState.LoggedIn(user)
                } else {
                    _state.value = AuthState.Error("E-Mail oder Passwort falsch")
                }
            } catch (e: Exception) {
                _state.value = AuthState.Error(e.message ?: "Verbindungsfehler")
            }
        }
    }

    fun register(name: String, email: String, password: String) {
        viewModelScope.launch {
            _state.value = AuthState.Loading
            try {
                val hash = sha256(password)
                val resp = ApiClient.authApi.register(RegistrationRequest(name, email, hash))
                if (resp.isSuccessful) {
                    _state.value = AuthState.Registered("Registrierung erfolgreich! Bitte E-Mail bestätigen.")
                } else {
                    _state.value = AuthState.Error("Registrierung fehlgeschlagen")
                }
            } catch (e: Exception) {
                _state.value = AuthState.Error(e.message ?: "Verbindungsfehler")
            }
        }
    }

    fun logout() {
        viewModelScope.launch {
            runCatching { ApiClient.authApi.logout() }
            ApiClient.clearCookies()
            tokenStore.clear()
            _state.value = AuthState.LoggedOut
        }
    }

    fun clearError() {
        if (_state.value is AuthState.Error || _state.value is AuthState.Registered) {
            _state.value = AuthState.LoggedOut
        }
    }
}
