package de.tsschulz.tt_tagebuch.shared.api.models

import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonElement

// --- Standard CRUD / Stammdaten ---

@Serializable
data class AddStandardTournamentBody(
    val clubId: Int,
    val tournamentName: String,
    val date: String,
    val winningSets: Int? = null,
    val allowsExternal: Boolean? = null,
    val isDoublesTournament: Boolean? = false,
)

@Serializable
data class AddMiniChampionshipBody(
    val clubId: Int,
    val ort: String,
    val date: String,
    val year: Int,
    val winningSets: Int? = null,
)

@Serializable
data class UpdateTournamentMetaBody(
    val name: String? = null,
    val date: String? = null,
    val winningSets: Int? = null,
    val numberOfTables: Int? = null,
    val isDoublesTournament: Boolean? = null,
)

// --- Modus / Gruppen / Spiele ---

@Serializable
data class SetTournamentModusBody(
    val clubId: Int,
    val tournamentId: Int,
    val type: String,
    val numberOfGroups: Int? = null,
    val advancingPerGroup: Int? = null,
)

@Serializable
data class TournamentClubTournamentBody(
    val clubId: Int,
    val tournamentId: Int,
)

@Serializable
data class TournamentCleanupOrphanedBody(
    val clubId: Int,
    val tournamentId: Int,
)

@Serializable
data class TournamentCreateGroupsBody(
    val clubId: Int,
    val tournamentId: Int,
    val numberOfGroups: Int? = null,
)

@Serializable
data class TournamentCreateGroupMatchesBody(
    val clubId: Int,
    val tournamentId: Int,
    val classId: Int? = null,
)

@Serializable
data class TournamentCreateGroupsPerClassBody(
    val clubId: Int,
    val tournamentId: Int,
    val groupsPerClass: Map<String, Int> = emptyMap(),
)

@Serializable
data class ManualGroupAssignmentEntry(
    val participantId: Int,
    val groupNumber: Int,
)

@Serializable
data class TournamentManualAssignGroupsBody(
    val clubId: Int,
    val tournamentId: Int,
    val assignments: List<ManualGroupAssignmentEntry> = emptyList(),
    val numberOfGroups: Int? = null,
    val maxGroupSize: Int? = null,
)

@Serializable
data class AssignParticipantToGroupBody(
    val clubId: Int,
    val tournamentId: Int,
    val participantId: Int,
    val groupNumber: Int,
    val isExternal: Boolean = false,
)

@Serializable
data class MergeTournamentPoolBody(
    val clubId: Int,
    val tournamentId: Int,
    val sourceClassId: Int,
    val targetClassId: Int,
    val strategy: String,
    val outOfCompetitionForSource: Boolean = false,
)

@Serializable
data class ResetTournamentPoolBody(
    val clubId: Int,
    val tournamentId: Int,
    val poolId: Int,
)

// --- Teilnehmer ---

@Serializable
data class TournamentGetParticipantsBody(
    val clubId: Int,
    val tournamentId: Int,
    val classId: Int? = null,
)

@Serializable
data class TournamentAddInternalParticipantBody(
    val clubId: Int,
    val classId: Int? = null,
    val participant: Int,
    val tournamentId: Int? = null,
)

@Serializable
data class TournamentRemoveInternalParticipantBody(
    val clubId: Int,
    val tournamentId: Int,
    val participantId: Int,
)

@Serializable
data class TournamentGetExternalParticipantsBody(
    val clubId: Int,
    val tournamentId: Int,
    val classId: Int? = null,
)

@Serializable
data class AddExternalTournamentParticipantBody(
    val clubId: Int,
    val tournamentId: Int,
    val classId: Int? = null,
    val firstName: String,
    val lastName: String,
    val club: String? = null,
    val birthDate: String? = null,
    val gender: String? = null,
    val email: String? = null,
    val address: String? = null,
)

@Serializable
data class RemoveExternalTournamentParticipantBody(
    val clubId: Int,
    val tournamentId: Int,
    val participantId: Int,
)

@Serializable
data class UpdateParticipantClassBody(
    val classId: Int? = null,
    val isExternal: Boolean? = false,
)

@Serializable
data class SeededFlagBody(val seeded: Boolean)

@Serializable
data class GaveUpFlagBody(val gaveUp: Boolean)

// --- Klassen ---

@Serializable
data class AddTournamentClassBody(
    val name: String,
    val isDoubles: Boolean? = false,
    val gender: String? = null,
    val minBirthYear: Int? = null,
    val maxBirthYear: Int? = null,
)

@Serializable
data class UpdateTournamentClassBody(
    val name: String? = null,
    val sortOrder: Int? = null,
    val isDoubles: Boolean? = null,
    val gender: String? = null,
    val minBirthYear: Int? = null,
    val maxBirthYear: Int? = null,
)

@Serializable
data class TournamentClassDto(
    val id: Int = 0,
    val tournamentId: Int? = null,
    val name: String = "",
    val sortOrder: Int? = null,
    @Serializable(with = FlexibleNullableBooleanSerializer::class)
    val isDoubles: Boolean? = null,
    val gender: String? = null,
    val minBirthYear: Int? = null,
    val maxBirthYear: Int? = null,
)

// --- Teilnehmer-Zeilen (intern) ---

@Serializable
data class TournamentParticipantMemberSnippetDto(
    val id: Int? = null,
    val firstName: String? = null,
    val lastName: String? = null,
    val gender: String? = null,
)

@Serializable
data class TournamentParticipantRowDto(
    val id: Int = 0,
    val tournamentId: Int? = null,
    val clubMemberId: Int? = null,
    val classId: Int? = null,
    val groupId: Int? = null,
    @Serializable(with = FlexibleNullableBooleanSerializer::class)
    val seeded: Boolean? = null,
    @Serializable(with = FlexibleNullableBooleanSerializer::class)
    val gaveUp: Boolean? = null,
    val member: TournamentParticipantMemberSnippetDto? = null,
)

@Serializable
data class TournamentExternalParticipantRowDto(
    val id: Int = 0,
    val tournamentId: Int? = null,
    val classId: Int? = null,
    val firstName: String? = null,
    val lastName: String? = null,
    val club: String? = null,
    @Serializable(with = FlexibleNullableBooleanSerializer::class)
    val seeded: Boolean? = null,
    @Serializable(with = FlexibleNullableBooleanSerializer::class)
    val gaveUp: Boolean? = null,
)

// --- Matches ---

@Serializable
data class TournamentMatchSetResultDto(
    val set: Int = 0,
    val pointsPlayer1: Int? = null,
    val pointsPlayer2: Int? = null,
)

@Serializable
data class TournamentMatchDto(
    val id: Int = 0,
    val tournamentId: Int? = null,
    val groupId: Int? = null,
    val classId: Int? = null,
    val groupRound: Int? = null,
    val round: String = "",
    val player1Id: Int? = null,
    val player2Id: Int? = null,
    @Serializable(with = FlexibleNullableBooleanSerializer::class)
    val isFinished: Boolean? = null,
    @Serializable(with = FlexibleNullableBooleanSerializer::class)
    val isActive: Boolean? = null,
    val result: String? = null,
    val tableNumber: Int? = null,
    val player1: JsonElement? = null,
    val player2: JsonElement? = null,
    val tournamentResults: List<TournamentMatchSetResultDto>? = null,
)

@Serializable
data class DistributeTablesResponseDto(
    val updated: List<TournamentMatchDto> = emptyList(),
    val message: String? = null,
)

@Serializable
data class TournamentAddMatchResultBody(
    val clubId: Int,
    val tournamentId: Int,
    val matchId: Int,
    val set: Int,
    val result: String,
)

@Serializable
data class TournamentFinishMatchBody(
    val clubId: Int,
    val tournamentId: Int,
    val matchId: Int,
)

@Serializable
data class TournamentMatchActiveBody(
    val isActive: Boolean,
)

@Serializable
data class TournamentMatchTableBody(
    val tableNumber: Int? = null,
)

@Serializable
data class TournamentDeleteMatchResultBody(
    val clubId: Int,
    val tournamentId: Int,
    val matchId: Int,
    val set: Int,
)

@Serializable
data class TournamentReopenMatchBody(
    val clubId: Int,
    val tournamentId: Int,
    val matchId: Int,
)

@Serializable
data class TournamentDeleteKnockoutBody(
    val clubId: Int,
    val tournamentId: Int,
    val classId: Int? = null,
)

// --- KO ---

@Serializable
data class TournamentStartKnockoutBody(
    val clubId: Int,
    val tournamentId: Int,
)

// --- Paarungen ---

@Serializable
data class CreateTournamentPairingBody(
    val player1Type: String,
    val player1Id: Int,
    val player2Type: String,
    val player2Id: Int,
    val seeded: Boolean? = false,
)

@Serializable
data class UpdateTournamentPairingBody(
    val player1Type: String? = null,
    val player1Id: Int? = null,
    val player2Type: String? = null,
    val player2Id: Int? = null,
    val seeded: Boolean? = null,
    val groupId: Int? = null,
)

// --- Stages ---

@Serializable
data class TournamentAdvanceStageBody(
    val clubId: Int,
    val tournamentId: Int,
    val fromStageIndex: Int? = 1,
    val toStageIndex: Int? = null,
)

@Serializable
data class TournamentUpsertStagesBody(
    val clubId: Int,
    val tournamentId: Int,
    val stages: JsonElement? = null,
    val advancement: JsonElement? = null,
    val advancements: JsonElement? = null,
)
