package com.anypreta.bountyboard.ui.auth

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.anypreta.bountyboard.data.AppContainer
import com.anypreta.bountyboard.data.net.ChangePasswordRequest
import com.anypreta.bountyboard.data.net.ForgotRequest
import com.anypreta.bountyboard.data.net.LoginRequest
import com.anypreta.bountyboard.data.net.RegisterRequest
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import kotlinx.coroutines.launch

class AuthViewModel(private val container: AppContainer) : ViewModel() {

    var loading by mutableStateOf(false)
        private set
    var error by mutableStateOf<String?>(null)
        private set
    var info by mutableStateOf<String?>(null)
        private set

    val initialBaseUrl: String get() = container.baseUrl.value

    fun applyBaseUrl(url: String, onApplied: () -> Unit = {}) {
        viewModelScope.launch {
            val normalized = com.anypreta.bountyboard.data.net.HostSelectionInterceptor.normalize(url)
            container.setBaseUrl(normalized)
            container.settings.setBaseUrl(normalized)
            info = "Server set to $normalized"
            error = null
            onApplied()
        }
    }

    fun login(email: String, password: String) {
        if (email.isBlank() || password.isBlank()) {
            error = "Enter your email and password."
            return
        }
        loading = true; error = null; info = null
        viewModelScope.launch {
            try {
                val r = container.repo.call { login(LoginRequest(email.trim(), password)) }
                container.session.setSession(r.user, r.mustChangePassword, r.oidcEnabled)
            } catch (e: Exception) {
                error = e.message ?: "Login failed."
            } finally {
                loading = false
            }
        }
    }

    fun register(email: String, name: String, password: String) {
        when {
            name.isBlank() -> { error = "Enter your name."; return }
            email.isBlank() -> { error = "Enter your email."; return }
            password.length < 8 -> { error = "Password must be at least 8 characters."; return }
        }
        loading = true; error = null; info = null
        viewModelScope.launch {
            try {
                val r = container.repo.call { register(RegisterRequest(email.trim(), name.trim(), password)) }
                container.session.setSession(r.user, r.mustChangePassword, r.oidcEnabled)
            } catch (e: Exception) {
                error = e.message ?: "Registration failed."
            } finally {
                loading = false
            }
        }
    }

    fun forgot(email: String, onDone: () -> Unit) {
        if (email.isBlank()) { error = "Enter your email."; return }
        loading = true; error = null; info = null
        viewModelScope.launch {
            try {
                container.repo.call { forgot(ForgotRequest(email.trim())) }
                info = "If an account exists, a reset link has been sent."
                onDone()
            } catch (e: Exception) {
                error = e.message ?: "Could not send reset email."
            } finally {
                loading = false
            }
        }
    }

    fun changePassword(current: String, new: String, onDone: () -> Unit) {
        when {
            current.isBlank() -> { error = "Enter your current password."; return }
            new.length < 8 -> { error = "New password must be at least 8 characters."; return }
        }
        loading = true; error = null; info = null
        viewModelScope.launch {
            try {
                container.repo.action { changePassword(ChangePasswordRequest(current, new)) }
                // Refresh session flags.
                val me = container.repo.call { me() }
                container.session.setSession(me.user, me.mustChangePassword, me.oidcEnabled)
                onDone()
            } catch (e: Exception) {
                error = e.message ?: "Could not change password."
            } finally {
                loading = false
            }
        }
    }

    /** After the OIDC WebView flow lands the session cookie, establish the session. */
    fun completeOidc(onResult: (Boolean) -> Unit) {
        loading = true; error = null
        viewModelScope.launch {
            try {
                val me = container.repo.call { me() }
                container.session.setSession(me.user, me.mustChangePassword, me.oidcEnabled)
                onResult(true)
            } catch (e: Exception) {
                error = "SSO sign-in failed: ${e.message}"
                onResult(false)
            } finally {
                loading = false
            }
        }
    }

    fun clearMessages() {
        error = null; info = null
    }
}
