package de.trainingstagebuch.app.viewmodel

import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.viewModelScope
import de.trainingstagebuch.app.R
import de.trainingstagebuch.app.repository.MyTischtennisAccountData
import de.trainingstagebuch.app.repository.MyTischtennisAccountResult
import de.trainingstagebuch.app.repository.MyTischtennisActionResult
import de.trainingstagebuch.app.repository.MyTischtennisStatusData
import de.trainingstagebuch.app.repository.MyTischtennisStatusResult
import de.trainingstagebuch.app.services.AppServices
import de.trainingstagebuch.app.utils.UiText
import de.trainingstagebuch.app.utils.ViewModelStateUtils
import kotlinx.coroutines.async
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch

data class MyTischtennisAccountUiState(
    val loading: Boolean = false,
    val saving: Boolean = false,
    val verifying: Boolean = false,
    val deleting: Boolean = false,
    val account: MyTischtennisAccountData? = null,
    val status: MyTischtennisStatusData? = null,
    val formEmail: String = "",
    val formPassword: String = "",
    val errorMessage: UiText? = null,
    val successMessage: UiText? = null
)

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

    private val accountService = AppServices.myTischtennisAccountService

    private val _state = MutableStateFlow(MyTischtennisAccountUiState())
    val state: StateFlow<MyTischtennisAccountUiState> = _state.asStateFlow()

    init {
        load()
    }

    fun load() {
        viewModelScope.launch {
            _state.update { it.copy(loading = true, errorMessage = null) }

            val accountDeferred = async { accountService.loadAccount() }
            val statusDeferred = async { accountService.loadStatus() }

            val accountResult = accountDeferred.await()
            val statusResult = statusDeferred.await()

            val account = (accountResult as? MyTischtennisAccountResult.Success)?.account
            val status = (statusResult as? MyTischtennisStatusResult.Success)?.status
            val accountError = (accountResult as? MyTischtennisAccountResult.Error)?.message
            val statusError = (statusResult as? MyTischtennisStatusResult.Error)?.message
            val error = accountError ?: statusError

            _state.update {
                it.copy(
                    loading = false,
                    account = account,
                    status = status,
                    formEmail = account?.email.orEmpty(),
                    formPassword = "",
                    errorMessage = error?.let { msg ->
                        ViewModelStateUtils.dynamicOrFallback(msg, UiText(R.string.mytischtennis_load_error))
                    }
                )
            }
        }
    }

    fun onEmailChanged(value: String) {
        _state.update { it.copy(formEmail = value) }
    }

    fun onPasswordChanged(value: String) {
        _state.update { it.copy(formPassword = value) }
    }

    fun saveAccount() {
        val current = _state.value
        val email = current.formEmail.trim()
        if (email.isBlank()) {
            _state.update { it.copy(errorMessage = UiText(R.string.mytischtennis_email_required)) }
            return
        }

        viewModelScope.launch {
            _state.update { it.copy(saving = true, errorMessage = null, successMessage = null) }
            when (val result = accountService.saveAccount(email, current.formPassword.ifBlank { null })) {
                is MyTischtennisActionResult.Success -> {
                    _state.update {
                        it.copy(
                            saving = false,
                            formPassword = "",
                            successMessage = ViewModelStateUtils.dynamicOrFallback(
                                result.message,
                                UiText(R.string.mytischtennis_account_saved)
                            )
                        )
                    }
                    load()
                }

                is MyTischtennisActionResult.Error -> {
                    _state.update {
                        it.copy(
                            saving = false,
                            errorMessage = ViewModelStateUtils.dynamicOrFallback(
                                result.message,
                                UiText(R.string.mytischtennis_save_error)
                            )
                        )
                    }
                }
            }
        }
    }

    fun verifyLogin() {
        viewModelScope.launch {
            _state.update { it.copy(verifying = true, errorMessage = null, successMessage = null) }
            when (val result = accountService.verify(_state.value.formPassword.ifBlank { null })) {
                is MyTischtennisActionResult.Success -> {
                    _state.update {
                        it.copy(
                            verifying = false,
                            formPassword = "",
                            successMessage = ViewModelStateUtils.dynamicOrFallback(
                                result.message,
                                UiText(R.string.mytischtennis_verify_success)
                            )
                        )
                    }
                    load()
                }

                is MyTischtennisActionResult.Error -> {
                    _state.update {
                        it.copy(
                            verifying = false,
                            errorMessage = ViewModelStateUtils.dynamicOrFallback(
                                result.message,
                                UiText(R.string.mytischtennis_verify_error)
                            )
                        )
                    }
                }
            }
        }
    }

    fun unlinkAccount() {
        viewModelScope.launch {
            _state.update { it.copy(deleting = true, errorMessage = null, successMessage = null) }
            when (val result = accountService.unlinkAccount()) {
                is MyTischtennisActionResult.Success -> {
                    _state.update {
                        it.copy(
                            deleting = false,
                            account = null,
                            status = null,
                            formPassword = "",
                            successMessage = ViewModelStateUtils.dynamicOrFallback(
                                result.message,
                                UiText(R.string.mytischtennis_unlink_success)
                            )
                        )
                    }
                }

                is MyTischtennisActionResult.Error -> {
                    _state.update {
                        it.copy(
                            deleting = false,
                            errorMessage = ViewModelStateUtils.dynamicOrFallback(
                                result.message,
                                UiText(R.string.mytischtennis_unlink_error)
                            )
                        )
                    }
                }
            }
        }
    }

    fun clearMessages() {
        _state.update { it.copy(errorMessage = null, successMessage = null) }
    }
}
