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.TrainingDayStatsItem
import de.trainingstagebuch.app.repository.MemberActivityStatItem
import de.trainingstagebuch.app.repository.MemberActivityStatsResult
import de.trainingstagebuch.app.repository.MemberParticipationItem
import de.trainingstagebuch.app.repository.TrainingStatsMember
import de.trainingstagebuch.app.repository.TrainingStatsResult
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 TrainingStatsViewModel(application: Application) : AndroidViewModel(application) {
    private val authService = AppServices.authService
    private val trainingStatsService = AppServices.trainingStatsService

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

    init {
        load()
    }

    fun load() {
        viewModelScope.launch {
            val clubId = authService.session.first().currentClub?.trim().orEmpty()
            if (clubId.isBlank()) {
                _state.update {
                    it.copy(
                        loading = false,
                        errorMessage = UiText(R.string.error_no_current_club)
                    )
                }
                return@launch
            }
            _state.update { it.copy(loading = true, errorMessage = null) }
            when (val result = trainingStatsService.loadTrainingStats(clubId)) {
                is TrainingStatsResult.Success -> {
                    _state.update {
                        it.copy(
                            loading = false,
                            members = result.data.members,
                            trainingDays = result.data.trainingDays,
                            trainingsCount12Months = result.data.trainingsCount12Months,
                            trainingsCount3Months = result.data.trainingsCount3Months
                        )
                    }
                }

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

    fun toggleTrainingDays() {
        _state.update { it.copy(showTrainingDays = !it.showTrainingDays) }
    }

    fun toggleMembers() {
        _state.update { it.copy(showMembers = !it.showMembers) }
    }

    fun sortBy(field: TrainingStatsSortField) {
        _state.update {
            if (it.sortField == field) {
                it.copy(sortDirection = if (it.sortDirection == SortDirection.Asc) SortDirection.Desc else SortDirection.Asc)
            } else {
                it.copy(sortField = field, sortDirection = SortDirection.Desc)
            }
        }
    }

    fun showMemberDetails(memberId: String) {
        _state.update {
            it.copy(
                selectedMemberId = memberId,
                detailsLoading = true,
                detailsErrorMessage = null,
                memberActivityStats = emptyList(),
                memberLastParticipations = emptyList()
            )
        }
        loadMemberDetails(memberId)
    }

    fun closeMemberDetails() {
        _state.update {
            it.copy(
                selectedMemberId = null,
                detailsLoading = false,
                detailsErrorMessage = null,
                memberActivityStats = emptyList(),
                memberLastParticipations = emptyList()
            )
        }
    }

    fun retryLoad() {
        load()
    }

    fun retryMemberDetails() {
        val memberId = _state.value.selectedMemberId ?: return
        loadMemberDetails(memberId)
    }

    private fun loadMemberDetails(memberId: String) {
        viewModelScope.launch {
            val clubId = authService.session.first().currentClub?.trim().orEmpty()
            if (clubId.isBlank()) {
                _state.update {
                    it.copy(
                        detailsLoading = false,
                        detailsErrorMessage = UiText(R.string.error_no_current_club)
                    )
                }
                return@launch
            }
            _state.update { it.copy(detailsLoading = true, detailsErrorMessage = null) }
            when (val result = trainingStatsService.loadMemberActivityStats(clubId, memberId)) {
                is MemberActivityStatsResult.Success -> {
                    _state.update {
                        it.copy(
                            detailsLoading = false,
                            memberActivityStats = result.stats,
                            memberLastParticipations = result.lastParticipations
                        )
                    }
                }

                is MemberActivityStatsResult.Error -> {
                    _state.update {
                        it.copy(
                            detailsLoading = false,
                            detailsErrorMessage = ViewModelStateUtils.normalizeUiText(
                                ErrorMessageFormatter.dynamicWithOptionalCode(result.message, result.code)
                            )
                        )
                    }
                }
            }
        }
    }
}

data class TrainingStatsUiState(
    val loading: Boolean = false,
    val members: List<TrainingStatsMember> = emptyList(),
    val trainingDays: List<TrainingDayStatsItem> = emptyList(),
    val trainingsCount12Months: Int = 0,
    val trainingsCount3Months: Int = 0,
    val showTrainingDays: Boolean = true,
    val showMembers: Boolean = false,
    val sortField: TrainingStatsSortField = TrainingStatsSortField.Name,
    val sortDirection: SortDirection = SortDirection.Asc,
    val selectedMemberId: String? = null,
    val errorMessage: UiText? = null,
    val detailsLoading: Boolean = false,
    val detailsErrorMessage: UiText? = null,
    val memberActivityStats: List<MemberActivityStatItem> = emptyList(),
    val memberLastParticipations: List<MemberParticipationItem> = emptyList()
)

enum class TrainingStatsSortField {
    Name,
    Participation12Months,
    Participation3Months,
    ParticipationTotal,
    LastTraining
}

enum class SortDirection {
    Asc,
    Desc
}
