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.ClubActionResult
import de.trainingstagebuch.app.repository.PendingApprovalUser
import de.trainingstagebuch.app.repository.PendingApprovalsResult
import de.trainingstagebuch.app.services.AppServices
import de.trainingstagebuch.app.utils.ErrorMessageFormatter
import de.trainingstagebuch.app.utils.UiText
import de.trainingstagebuch.app.utils.ViewModelStateUtils
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch

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

    private val authService = AppServices.authService
    private val homeService = AppServices.homeService

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

    init {
        load()
    }

    fun load() {
        viewModelScope.launch {
            val clubId = resolveClubId() ?: return@launch
            _state.update { it.copy(status = PendingApprovalsStatus.Loading, errorMessage = null) }
            when (val result = homeService.loadPendingApprovals(clubId)) {
                is PendingApprovalsResult.Success -> {
                    _state.update {
                        it.copy(
                            status = PendingApprovalsStatus.Success,
                            users = result.users
                        )
                    }
                }

                is PendingApprovalsResult.Error -> {
                    _state.update {
                        it.copy(
                            status = PendingApprovalsStatus.Error,
                            errorMessage = ViewModelStateUtils.normalizeUiText(
                                ErrorMessageFormatter.dynamicWithOptionalCode(result.message, result.code)
                            )
                        )
                    }
                }
            }
        }
    }

    fun approveUser(userId: String) {
        performAction(userId) { clubId -> homeService.approvePendingUser(clubId, userId) }
    }

    fun rejectUser(userId: String) {
        performAction(userId) { clubId -> homeService.rejectPendingUser(clubId, userId) }
    }

    private fun performAction(userId: String, action: suspend (String) -> ClubActionResult) {
        viewModelScope.launch {
            val clubId = resolveClubId() ?: return@launch
            _state.update { it.copy(actionLoading = true, errorMessage = null, successMessage = null) }
            when (val result = action(clubId)) {
                is ClubActionResult.Success -> {
                    _state.update {
                        it.copy(
                            actionLoading = false,
                            users = it.users.filterNot { user -> user.id == userId },
                            successMessage = UiText(R.string.pending_approvals_action_success)
                        )
                    }
                }

                is ClubActionResult.Error -> {
                    _state.update {
                        it.copy(
                            actionLoading = false,
                            errorMessage = ViewModelStateUtils.normalizeUiText(
                                ErrorMessageFormatter.dynamicWithOptionalCode(result.message, result.code)
                            )
                        )
                    }
                }
            }
        }
    }

    private suspend fun resolveClubId(): String? {
        val clubId = authService.session.first().currentClub?.trim().orEmpty()
        if (clubId.isBlank()) {
            _state.update { it.copy(status = PendingApprovalsStatus.Error, errorMessage = UiText(R.string.error_no_current_club)) }
            return null
        }
        return clubId
    }
}

data class PendingApprovalsUiState(
    val status: PendingApprovalsStatus = PendingApprovalsStatus.Idle,
    val users: List<PendingApprovalUser> = emptyList(),
    val actionLoading: Boolean = false,
    val errorMessage: UiText? = null,
    val successMessage: UiText? = null
)

enum class PendingApprovalsStatus {
    Idle,
    Loading,
    Success,
    Error
}
