package de.tsschulz.tt_tagebuch.shared.state

import de.tsschulz.tt_tagebuch.shared.api.TournamentsApi
import de.tsschulz.tt_tagebuch.shared.api.models.InternalTournamentDetailDto
import de.tsschulz.tt_tagebuch.shared.api.models.InternalTournamentSummaryDto
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update

enum class ClubTournamentDisplayFilter {
    Internal,
    External,
    Mini,
}

data class ClubInternalTournamentsState(
    val filter: ClubTournamentDisplayFilter = ClubTournamentDisplayFilter.Internal,
    val tournaments: List<InternalTournamentSummaryDto> = emptyList(),
    val selectedId: Int? = null,
    val detail: InternalTournamentDetailDto? = null,
    val isLoadingList: Boolean = false,
    val isLoadingDetail: Boolean = false,
    val error: String? = null,
)

class ClubInternalTournamentsManager(
    private val tournamentsApi: TournamentsApi,
) {
    private val _state = MutableStateFlow(ClubInternalTournamentsState())
    val state: StateFlow<ClubInternalTournamentsState> = _state.asStateFlow()

    fun clear() {
        _state.value = ClubInternalTournamentsState()
    }

    fun setFilter(filter: ClubTournamentDisplayFilter) {
        _state.update { it.copy(filter = filter, selectedId = null, detail = null, error = null) }
    }

    fun selectTournament(id: Int?) {
        _state.update { it.copy(selectedId = id, detail = null) }
    }

    suspend fun loadList(clubId: Int) {
        val filter = _state.value.filter
        _state.update { it.copy(isLoadingList = true, error = null) }
        try {
            val raw = when (filter) {
                ClubTournamentDisplayFilter.Mini -> tournamentsApi.listTournaments(clubId, type = "mini")
                else -> tournamentsApi.listTournaments(clubId, type = null)
            }
            val list = when (filter) {
                ClubTournamentDisplayFilter.Mini -> raw
                ClubTournamentDisplayFilter.Internal ->
                    raw.filter { it.miniChampionshipYear == null && it.allowsExternal != true }
                ClubTournamentDisplayFilter.External ->
                    raw.filter { it.miniChampionshipYear == null && it.allowsExternal == true }
            }
            _state.update { it.copy(tournaments = list, isLoadingList = false, error = null) }
        } catch (t: Throwable) {
            _state.update {
                it.copy(
                    isLoadingList = false,
                    error = t.toUserMessage("Vereins-Turniere konnten nicht geladen werden"),
                )
            }
        }
    }

    suspend fun loadDetail(clubId: Int, tournamentId: Int) {
        _state.update { it.copy(isLoadingDetail = true, error = null) }
        try {
            val d = tournamentsApi.getTournament(clubId, tournamentId)
            _state.update { it.copy(detail = d, isLoadingDetail = false, error = null) }
        } catch (t: Throwable) {
            _state.update {
                it.copy(
                    isLoadingDetail = false,
                    error = t.toUserMessage("Turnierdetails konnten nicht geladen werden"),
                )
            }
        }
    }
}
