package de.trainingstagebuch.app.services

import de.trainingstagebuch.app.repository.DomainSocketEvent
import de.trainingstagebuch.app.repository.MembersResult
import de.trainingstagebuch.app.repository.OfficialTournamentSummaryResult
import de.trainingstagebuch.app.repository.OfficialTournamentsResult
import de.trainingstagebuch.app.repository.OfficialTournamentUploadResult
import de.trainingstagebuch.app.repository.OfficialTournamentDetailResult
import de.trainingstagebuch.app.repository.OfficialTournamentActionResult
import de.trainingstagebuch.app.repository.TournamentActionResult
import de.trainingstagebuch.app.repository.TournamentDetailResult
import de.trainingstagebuch.app.repository.TournamentListResult
import de.trainingstagebuch.app.repository.TournamentMatchesResult
import de.trainingstagebuch.app.repository.TournamentParticipantsResult
import de.trainingstagebuch.app.repository.TrainingstagebuchRepository
import kotlinx.coroutines.flow.SharedFlow

class TournamentService(
    private val repository: TrainingstagebuchRepository
) {
    val socketEvents: SharedFlow<DomainSocketEvent> = repository.socketDomainEvents

    suspend fun loadTournaments(clubId: String, type: String? = null): TournamentListResult =
        repository.loadTournaments(clubId, type)

    suspend fun loadTournament(clubId: String, tournamentId: String): TournamentDetailResult =
        repository.loadTournament(clubId, tournamentId)

    suspend fun createTournament(clubId: String, name: String, date: String, winningSets: Int): TournamentActionResult =
        repository.createTournament(clubId, name, date, winningSets)

    suspend fun createMiniTournament(
        clubId: String,
        location: String,
        date: String,
        year: Int,
        winningSets: Int
    ): TournamentActionResult = repository.createMiniTournament(clubId, location, date, year, winningSets)

    suspend fun updateTournamentConfig(
        clubId: String,
        tournamentId: String,
        name: String,
        date: String?,
        winningSets: Int,
        numberOfTables: Int?,
        isGroupTournament: Boolean
    ): TournamentActionResult = repository.updateTournamentConfig(
        clubId = clubId,
        tournamentId = tournamentId,
        name = name,
        date = date,
        winningSets = winningSets,
        numberOfTables = numberOfTables,
        isGroupTournament = isGroupTournament
    )

    suspend fun loadParticipants(clubId: String, tournamentId: String, classId: String? = null): TournamentParticipantsResult =
        repository.loadTournamentParticipants(clubId, tournamentId, classId)

    suspend fun addParticipant(clubId: String, tournamentId: String, memberId: String, classId: String? = null): TournamentActionResult =
        repository.addTournamentParticipant(clubId, tournamentId, memberId, classId)

    suspend fun removeParticipant(clubId: String, tournamentId: String, participantId: String): TournamentActionResult =
        repository.removeTournamentParticipant(clubId, tournamentId, participantId)

    suspend fun loadMatches(clubId: String, tournamentId: String): TournamentMatchesResult =
        repository.loadTournamentMatches(clubId, tournamentId)

    suspend fun saveMatchResult(
        clubId: String,
        tournamentId: String,
        matchId: String,
        result: String
    ): TournamentActionResult = repository.saveTournamentMatchResult(clubId, tournamentId, matchId, result)

    suspend fun loadMembers(clubId: String): MembersResult = repository.loadMembers(clubId, showAll = true)

    suspend fun loadOfficialTournaments(clubId: String): OfficialTournamentsResult =
        repository.loadOfficialTournaments(clubId)

    suspend fun loadOfficialSummary(clubId: String): OfficialTournamentSummaryResult =
        repository.loadOfficialTournamentSummary(clubId)

    suspend fun uploadOfficialTournamentPdf(
        clubId: String,
        fileName: String,
        bytes: ByteArray
    ): OfficialTournamentUploadResult = repository.uploadOfficialTournamentPdf(clubId, fileName, bytes)

    suspend fun loadOfficialTournamentDetail(clubId: String, tournamentId: String): OfficialTournamentDetailResult =
        repository.loadOfficialTournamentDetail(clubId, tournamentId)

    suspend fun upsertOfficialParticipation(
        clubId: String,
        tournamentId: String,
        competitionId: Int,
        memberId: String,
        wants: Boolean,
        registered: Boolean,
        participated: Boolean,
        placement: String?
    ): OfficialTournamentActionResult = repository.upsertOfficialParticipation(
        clubId = clubId,
        tournamentId = tournamentId,
        competitionId = competitionId,
        memberId = memberId,
        wants = wants,
        registered = registered,
        participated = participated,
        placement = placement
    )

    suspend fun updateOfficialParticipationStatus(
        clubId: String,
        tournamentId: String,
        competitionId: Int,
        memberId: String,
        action: String
    ): OfficialTournamentActionResult = repository.updateOfficialParticipationStatus(
        clubId = clubId,
        tournamentId = tournamentId,
        competitionId = competitionId,
        memberId = memberId,
        action = action
    )

    suspend fun deleteOfficialTournament(clubId: String, tournamentId: String): OfficialTournamentActionResult =
        repository.deleteOfficialTournament(clubId, tournamentId)
}
