package de.trainingstagebuch.app.network

import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.JsonObject
import okhttp3.MultipartBody
import okhttp3.RequestBody
import retrofit2.http.Body
import retrofit2.http.DELETE
import retrofit2.http.GET
import retrofit2.http.HTTP
import retrofit2.http.Multipart
import retrofit2.http.PATCH
import retrofit2.http.POST
import retrofit2.http.Part
import retrofit2.http.PUT
import retrofit2.http.Path
import retrofit2.http.Query
import retrofit2.http.QueryMap

@Suppress("LongMethod", "TooManyFunctions")
interface ApiService {

    // Auth & Session
    @POST("auth/register")
    suspend fun register(@Body request: RegisterRequest): BaseResponse<JsonElement>

    @POST("auth/login")
    suspend fun login(@Body request: LoginRequest): JsonObject

    @GET("auth/activate/{activationCode}")
    suspend fun activate(@Path("activationCode") activationCode: String): BaseResponse<JsonElement>

    @POST("auth/forgot-password")
    suspend fun forgotPassword(@Body body: JsonObject): BaseResponse<JsonElement>

    @POST("auth/reset-password")
    suspend fun resetPassword(@Body body: JsonObject): BaseResponse<JsonElement>

    @GET("session/status")
    suspend fun getSessionStatus(): BaseResponse<JsonElement>

    // Clubs
    @GET("clubs")
    suspend fun getClubs(): JsonElement

    @POST("clubs")
    suspend fun createClub(@Body request: CreateClubRequest): JsonElement

    @GET("clubs/{clubId}")
    suspend fun getClub(@Path("clubId") clubId: String): JsonElement

    @PUT("clubs/{clubId}/settings")
    suspend fun updateClubSettings(@Path("clubId") clubId: String, @Body body: JsonObject): BaseResponse<JsonElement>

    @GET("clubs/request/{clubId}")
    suspend fun requestClubAccess(@Path("clubId") clubId: String): BaseResponse<JsonElement>

    @GET("clubs/pending/{clubId}")
    suspend fun getPendingApprovals(@Path("clubId") clubId: String): JsonElement

    @POST("clubs/approve")
    suspend fun approveClubAccess(@Body body: JsonObject): BaseResponse<JsonElement>

    @POST("clubs/reject")
    suspend fun rejectClubAccess(@Body body: JsonObject): BaseResponse<JsonElement>

    // Permissions
    @GET("permissions/{clubId}")
    suspend fun getPermissions(@Path("clubId") clubId: String): JsonElement

    @GET("permissions/roles/available")
    suspend fun getAvailableRoles(): JsonElement

    @GET("permissions/structure/all")
    suspend fun getPermissionStructure(): JsonElement

    @GET("permissions/{clubId}/members")
    suspend fun getPermissionMembers(@Path("clubId") clubId: String, @Query("t") cacheBust: Long? = null): JsonElement

    @PUT("permissions/{clubId}/user/{userId}/role")
    suspend fun updateUserRole(@Path("clubId") clubId: String, @Path("userId") userId: String, @Body body: JsonObject): BaseResponse<JsonElement>

    @PUT("permissions/{clubId}/user/{userId}/status")
    suspend fun updateUserStatus(@Path("clubId") clubId: String, @Path("userId") userId: String, @Body body: JsonObject): BaseResponse<JsonElement>

    @PUT("permissions/{clubId}/user/{userId}/permissions")
    suspend fun updateUserPermissions(@Path("clubId") clubId: String, @Path("userId") userId: String, @Body body: JsonObject): BaseResponse<JsonElement>

    // Members
    @GET("clubmembers/get/{clubId}/{showAll}")
    suspend fun getClubMembers(@Path("clubId") clubId: String, @Path("showAll") showAll: Boolean): JsonElement

    @GET("clubmembers/notapproved/{clubId}")
    suspend fun getNotApprovedMembers(@Path("clubId") clubId: String): JsonElement

    @POST("clubmembers/set/{clubId}")
    suspend fun setClubMembers(@Path("clubId") clubId: String, @Body body: JsonObject): JsonElement

    @POST("clubmembers/update-ratings/{clubId}")
    suspend fun updateRatings(@Path("clubId") clubId: String): BaseResponse<JsonElement>

    @POST("clubmembers/quick-update-test-membership/{clubId}/{memberId}")
    suspend fun quickUpdateTestMembership(@Path("clubId") clubId: String, @Path("memberId") memberId: String): JsonElement

    @POST("clubmembers/quick-deactivate/{clubId}/{memberId}")
    suspend fun quickDeactivateMember(@Path("clubId") clubId: String, @Path("memberId") memberId: String): JsonElement

    @Multipart
    @POST("clubmembers/image/{clubId}/{memberId}")
    suspend fun uploadClubMemberImage(
        @Path("clubId") clubId: String,
        @Path("memberId") memberId: String,
        @Part image: MultipartBody.Part
    ): JsonElement

    @POST("clubmembers/image/{clubId}/{memberId}/{imageId}/primary")
    suspend fun setClubMemberPrimaryImage(
        @Path("clubId") clubId: String,
        @Path("memberId") memberId: String,
        @Path("imageId") imageId: String
    ): JsonElement

    @DELETE("clubmembers/image/{clubId}/{memberId}/{imageId}")
    suspend fun deleteClubMemberImage(
        @Path("clubId") clubId: String,
        @Path("memberId") memberId: String,
        @Path("imageId") imageId: String
    ): JsonElement

    @GET("clubmembers/gallery/{clubId}")
    suspend fun getClubMemberGallery(@Path("clubId") clubId: String, @Query("format") format: String = "json", @Query("size") size: Int? = null): JsonElement

    @GET("member-transfer-config/{clubId}")
    suspend fun getMemberTransferConfig(@Path("clubId") clubId: String): JsonElement

    @POST("member-transfer-config/{clubId}")
    suspend fun saveMemberTransferConfig(@Path("clubId") clubId: String, @Body body: JsonObject): JsonElement

    @DELETE("member-transfer-config/{clubId}")
    suspend fun deleteMemberTransferConfig(@Path("clubId") clubId: String): JsonElement

    @POST("clubmembers/transfer/{clubId}")
    suspend fun transferClubMembers(@Path("clubId") clubId: String, @Body body: JsonObject): JsonElement

    @GET("membernotes/{memberId}")
    suspend fun getMemberNotes(@Path("memberId") memberId: String, @Query("clubId") clubId: String): JsonElement

    @POST("membernotes")
    suspend fun addMemberNote(@Body body: JsonObject): JsonElement

    @HTTP(method = "DELETE", path = "membernotes/{noteId}", hasBody = true)
    suspend fun deleteMemberNote(@Path("noteId") noteId: String, @Body body: JsonObject): JsonElement

    // Diary
    @GET("diary/{clubId}")
    suspend fun getDiaryDates(@Path("clubId") clubId: String): JsonElement

    @POST("diary/{clubId}")
    suspend fun createDiaryDate(@Path("clubId") clubId: String, @Body body: JsonObject): JsonElement

    @PUT("diary/{clubId}")
    suspend fun updateDiaryTrainingTime(@Path("clubId") clubId: String, @Body body: JsonObject): BaseResponse<JsonElement>

    @DELETE("diary/{clubId}/{dateId}")
    suspend fun deleteDiaryDate(@Path("clubId") clubId: String, @Path("dateId") dateId: String): BaseResponse<JsonElement>

    @GET("participants/{dateId}")
    suspend fun getParticipants(@Path("dateId") dateId: String): JsonElement

    @POST("participants/add")
    suspend fun addParticipant(@Body body: JsonObject): JsonElement

    @POST("participants/remove")
    suspend fun removeParticipant(@Body body: JsonObject): BaseResponse<JsonElement>

    @PUT("participants/{dateId}/{memberId}/group")
    suspend fun updateParticipantGroup(@Path("dateId") dateId: String, @Path("memberId") memberId: String, @Body body: JsonObject): BaseResponse<JsonElement>

    @GET("activities/{dateId}")
    suspend fun getActivities(@Path("dateId") dateId: String): JsonElement

    @POST("activities/add")
    suspend fun addActivity(@Body body: JsonObject): JsonElement

    @GET("group/{clubId}/{dateId}")
    suspend fun getGroups(@Path("clubId") clubId: String, @Path("dateId") dateId: String): JsonElement

    @POST("group")
    suspend fun createGroup(@Body body: JsonObject): BaseResponse<JsonElement>

    @PUT("group/{groupId}")
    suspend fun updateGroup(@Path("groupId") groupId: String, @Body body: JsonObject): BaseResponse<JsonElement>

    @DELETE("group/{groupId}")
    suspend fun deleteGroup(@Path("groupId") groupId: String): BaseResponse<JsonElement>

    @HTTP(method = "DELETE", path = "group/{groupId}", hasBody = true)
    suspend fun deleteGroupWithBody(@Path("groupId") groupId: String, @Body body: JsonObject): BaseResponse<JsonElement>

    @GET("tags")
    suspend fun getTags(): JsonElement

    @POST("tags")
    suspend fun createTag(@Body body: JsonObject): JsonElement

    @POST("diary/tag/{clubId}/add-tag")
    suspend fun addTagToDiaryDate(@Path("clubId") clubId: String, @Body body: JsonObject): BaseResponse<JsonElement>

    @HTTP(method = "DELETE", path = "diary/{clubId}/tag", hasBody = true)
    suspend fun deleteTagFromDiaryDate(@Path("clubId") clubId: String, @Body body: JsonObject): BaseResponse<JsonElement>

    @GET("notes")
    suspend fun getNotes(@QueryMap query: Map<String, String>): JsonElement

    @GET("diarymember/{clubId}/note")
    suspend fun getDiaryMemberNotes(@Path("clubId") clubId: String, @QueryMap query: Map<String, String>): JsonElement

    @POST("diarymember/{clubId}/note")
    suspend fun addDiaryMemberNote(@Path("clubId") clubId: String, @Body body: JsonObject): JsonElement

    @DELETE("diarymember/{clubId}/note/{noteId}")
    suspend fun deleteDiaryMemberNote(@Path("clubId") clubId: String, @Path("noteId") noteId: String): JsonElement

    // Diary activities
    @GET("diary-date-activities/{clubId}/{dateId}")
    suspend fun getDiaryDateActivities(@Path("clubId") clubId: String, @Path("dateId") dateId: String): JsonElement

    @POST("diary-date-activities/{clubId}")
    suspend fun createDiaryDateActivity(@Path("clubId") clubId: String, @Body body: JsonObject): BaseResponse<JsonElement>

    @PUT("diary-date-activities/{clubId}/{activityId}")
    suspend fun updateDiaryDateActivity(@Path("clubId") clubId: String, @Path("activityId") activityId: String, @Body body: JsonObject): BaseResponse<JsonElement>

    @PUT("diary-date-activities/{clubId}/{activityId}/order")
    suspend fun updateDiaryDateActivityOrder(@Path("clubId") clubId: String, @Path("activityId") activityId: String, @Body body: JsonObject): BaseResponse<JsonElement>

    @DELETE("diary-date-activities/{clubId}/{activityId}")
    suspend fun deleteDiaryDateActivity(@Path("clubId") clubId: String, @Path("activityId") activityId: String): BaseResponse<JsonElement>

    @POST("diary-date-activities/group")
    suspend fun createGroupActivity(@Body body: JsonObject): BaseResponse<JsonElement>

    @PUT("diary-date-activities/group/{clubId}/{groupActivityId}")
    suspend fun updateGroupActivity(@Path("clubId") clubId: String, @Path("groupActivityId") groupActivityId: String, @Body body: JsonObject): BaseResponse<JsonElement>

    @DELETE("diary-date-activities/group/{clubId}/{groupActivityId}")
    suspend fun deleteGroupActivity(@Path("clubId") clubId: String, @Path("groupActivityId") groupActivityId: String): BaseResponse<JsonElement>

    @GET("diary-member-activities/{clubId}/{diaryDateActivityId}")
    suspend fun getDiaryMemberActivities(
        @Path("clubId") clubId: String,
        @Path("diaryDateActivityId") diaryDateActivityId: String
    ): JsonElement

    @POST("diary-member-activities/{clubId}/{diaryDateActivityId}")
    suspend fun setDiaryMemberActivities(
        @Path("clubId") clubId: String,
        @Path("diaryDateActivityId") diaryDateActivityId: String,
        @Body body: JsonObject
    ): BaseResponse<JsonElement>

    @DELETE("diary-member-activities/{clubId}/{diaryDateActivityId}/{participantId}")
    suspend fun deleteDiaryMemberActivity(
        @Path("clubId") clubId: String,
        @Path("diaryDateActivityId") diaryDateActivityId: String,
        @Path("participantId") participantId: String
    ): BaseResponse<JsonElement>

    @POST("accident")
    suspend fun createAccident(@Body body: JsonObject): BaseResponse<JsonElement>

    @GET("accident/{clubId}/{dateId}")
    suspend fun getAccidents(
        @Path("clubId") clubId: String,
        @Path("dateId") dateId: String
    ): JsonElement

    @GET("member-activities/{clubId}/{memberId}")
    suspend fun getMemberActivities(
        @Path("clubId") clubId: String,
        @Path("memberId") memberId: String,
        @Query("period") period: String? = null
    ): JsonElement

    @GET("member-activities/{clubId}/{memberId}/last-participations")
    suspend fun getMemberLastParticipations(
        @Path("clubId") clubId: String,
        @Path("memberId") memberId: String,
        @Query("limit") limit: Int = 3
    ): JsonElement

    @GET("predefined-activities")
    suspend fun getPredefinedActivities(): JsonElement

    @GET("predefined-activities/{id}")
    suspend fun getPredefinedActivity(@Path("id") id: String): JsonElement

    @GET("predefined-activities/search/query")
    suspend fun searchPredefinedActivities(
        @Query("q") query: String,
        @Query("limit") limit: Int = 10
    ): JsonElement

    @POST("predefined-activities")
    suspend fun createPredefinedActivity(@Body body: JsonObject): JsonElement

    @PUT("predefined-activities/{id}")
    suspend fun updatePredefinedActivity(@Path("id") id: String, @Body body: JsonObject): JsonElement

    @POST("predefined-activities/merge")
    suspend fun mergePredefinedActivities(@Body body: JsonObject): BaseResponse<JsonElement>

    @POST("predefined-activities/deduplicate")
    suspend fun deduplicatePredefinedActivities(@Body body: JsonObject): BaseResponse<JsonElement>

    @DELETE("predefined-activities/{id}/image/{imageId}")
    suspend fun deletePredefinedActivityImage(@Path("id") id: String, @Path("imageId") imageId: String): BaseResponse<JsonElement>

    // Training
    @GET("training-groups/{clubId}")
    suspend fun getTrainingGroups(@Path("clubId") clubId: String): JsonElement

    @GET("training-groups/{clubId}/member/{memberId}")
    suspend fun getMemberTrainingGroups(@Path("clubId") clubId: String, @Path("memberId") memberId: String): JsonElement

    @POST("training-groups/{clubId}")
    suspend fun createTrainingGroup(@Path("clubId") clubId: String, @Body body: JsonObject): BaseResponse<JsonElement>

    @PUT("training-groups/{clubId}/{groupId}")
    suspend fun updateTrainingGroup(@Path("clubId") clubId: String, @Path("groupId") groupId: String, @Body body: JsonObject): BaseResponse<JsonElement>

    @DELETE("training-groups/{clubId}/{groupId}")
    suspend fun deleteTrainingGroup(@Path("clubId") clubId: String, @Path("groupId") groupId: String): BaseResponse<JsonElement>

    @POST("training-groups/{clubId}/{groupId}/member/{memberId}")
    suspend fun addMemberToTrainingGroup(@Path("clubId") clubId: String, @Path("groupId") groupId: String, @Path("memberId") memberId: String): BaseResponse<JsonElement>

    @DELETE("training-groups/{clubId}/{groupId}/member/{memberId}")
    suspend fun removeMemberFromTrainingGroup(@Path("clubId") clubId: String, @Path("groupId") groupId: String, @Path("memberId") memberId: String): BaseResponse<JsonElement>

    @GET("training-times/{clubId}")
    suspend fun getTrainingTimes(@Path("clubId") clubId: String): JsonElement

    @POST("training-times/{clubId}")
    suspend fun createTrainingTime(@Path("clubId") clubId: String, @Body body: JsonObject): BaseResponse<JsonElement>

    @PUT("training-times/{clubId}/{timeId}")
    suspend fun updateTrainingTime(@Path("clubId") clubId: String, @Path("timeId") timeId: String, @Body body: JsonObject): BaseResponse<JsonElement>

    @DELETE("training-times/{clubId}/{timeId}")
    suspend fun deleteTrainingTime(@Path("clubId") clubId: String, @Path("timeId") timeId: String): BaseResponse<JsonElement>

    @GET("training-stats/{clubId}")
    suspend fun getTrainingStats(@Path("clubId") clubId: String): JsonElement

    // Match / Schedule
    @GET("matches/leagues/{clubId}/matches")
    suspend fun getLeagueMatches(@Path("clubId") clubId: String, @Query("seasonid") seasonId: String? = null): JsonElement

    @GET("matches/leagues/{clubId}/matches/{leagueId}")
    suspend fun getMatchesForLeague(@Path("clubId") clubId: String, @Path("leagueId") leagueId: String): JsonElement

    @GET("matches/leagues/{clubId}/table/{leagueId}")
    suspend fun getLeagueTable(@Path("clubId") clubId: String, @Path("leagueId") leagueId: String): JsonElement

    @GET("matches/leagues/{clubId}/stats/{leagueId}")
    suspend fun getLeaguePlayerStats(
        @Path("clubId") clubId: String,
        @Path("leagueId") leagueId: String,
        @Query("seasonid") seasonId: String? = null
    ): JsonElement

    @POST("matches/leagues/{clubId}/table/{leagueId}/fetch")
    suspend fun fetchLeagueTable(@Path("clubId") clubId: String, @Path("leagueId") leagueId: String): BaseResponse<JsonElement>

    @PATCH("matches/{matchId}/players")
    suspend fun updateMatchPlayers(@Path("matchId") matchId: String, @Body body: JsonObject): BaseResponse<JsonElement>

    // Teams & documents
    @GET("club-teams/club/{clubId}")
    suspend fun getClubTeams(@Path("clubId") clubId: String, @Query("seasonid") seasonId: String? = null): JsonElement

    @GET("club-teams/leagues/{clubId}")
    suspend fun getClubTeamLeagues(@Path("clubId") clubId: String, @Query("seasonid") seasonId: String? = null): JsonElement

    @POST("club-teams/club/{clubId}")
    suspend fun createClubTeam(@Path("clubId") clubId: String, @Body body: JsonObject): JsonElement

    @PUT("club-teams/{clubTeamId}")
    suspend fun updateClubTeam(@Path("clubTeamId") clubTeamId: String, @Body body: JsonObject): BaseResponse<JsonElement>

    @DELETE("club-teams/{clubTeamId}")
    suspend fun deleteClubTeam(@Path("clubTeamId") clubTeamId: String): BaseResponse<JsonElement>

    @GET("team-documents/club-team/{clubTeamId}")
    suspend fun getTeamDocuments(@Path("clubTeamId") clubTeamId: String): JsonElement

    @Multipart
    @POST("team-documents/club-team/{clubTeamId}/upload")
    suspend fun uploadTeamDocument(
        @Path("clubTeamId") clubTeamId: String,
        @retrofit2.http.Part file: MultipartBody.Part,
        @retrofit2.http.Part("documentType") documentType: RequestBody
    ): JsonElement

    @POST("team-documents/{documentId}/parse")
    suspend fun parseTeamDocument(@Path("documentId") documentId: String, @Query("leagueid") leagueId: String): JsonElement

    @GET("team-documents/{documentId}/download")
    suspend fun downloadTeamDocument(@Path("documentId") documentId: String): JsonElement

    // Tournament
    @GET("tournament/{clubId}")
    suspend fun getTournaments(@Path("clubId") clubId: String, @Query("type") type: String? = null): JsonElement

    @GET("tournament/{clubId}/{tournamentId}")
    suspend fun getTournament(@Path("clubId") clubId: String, @Path("tournamentId") tournamentId: String): JsonElement

    @POST("tournament")
    suspend fun createTournament(@Body body: JsonObject): BaseResponse<JsonElement>

    @POST("tournament/mini")
    suspend fun createMiniTournament(@Body body: JsonObject): BaseResponse<JsonElement>

    @PUT("tournament/{clubId}/{tournamentId}")
    suspend fun updateTournament(@Path("clubId") clubId: String, @Path("tournamentId") tournamentId: String, @Body body: JsonObject): BaseResponse<JsonElement>

    @POST("tournament/participant")
    suspend fun addTournamentParticipant(@Body body: JsonObject): BaseResponse<JsonElement>

    @HTTP(method = "DELETE", path = "tournament/participant", hasBody = true)
    suspend fun removeTournamentParticipant(@Body body: JsonObject): BaseResponse<JsonElement>

    @POST("tournament/participants")
    suspend fun getTournamentParticipants(@Body body: JsonObject): JsonElement

    @POST("tournament/external-participant")
    suspend fun addExternalTournamentParticipant(@Body body: JsonObject): BaseResponse<JsonElement>

    @HTTP(method = "DELETE", path = "tournament/external-participant", hasBody = true)
    suspend fun removeExternalTournamentParticipant(@Body body: JsonObject): BaseResponse<JsonElement>

    @POST("tournament/external-participants")
    suspend fun getExternalParticipants(@Body body: JsonObject): JsonElement

    @GET("tournament/groups")
    suspend fun getTournamentGroups(@Query("clubId") clubId: String, @Query("tournamentId") tournamentId: String): JsonElement

    @PUT("tournament/groups")
    suspend fun createTournamentGroups(@Body body: JsonObject): BaseResponse<JsonElement>

    @POST("tournament/groups/create")
    suspend fun createTournamentGroupsPerClass(@Body body: JsonObject): BaseResponse<JsonElement>

    @POST("tournament/groups")
    suspend fun fillTournamentGroups(@Body body: JsonObject): BaseResponse<JsonElement>

    @POST("tournament/matches/create")
    suspend fun createTournamentMatches(@Body body: JsonObject): BaseResponse<JsonElement>

    @POST("tournament/match/result")
    suspend fun addTournamentMatchResult(@Body body: JsonObject): BaseResponse<JsonElement>

    @HTTP(method = "DELETE", path = "tournament/match/result", hasBody = true)
    suspend fun deleteTournamentMatchResult(@Body body: JsonObject): BaseResponse<JsonElement>

    @POST("tournament/match/finish")
    suspend fun finishTournamentMatch(@Body body: JsonObject): BaseResponse<JsonElement>

    @POST("tournament/match/reopen")
    suspend fun reopenTournamentMatch(@Body body: JsonObject): BaseResponse<JsonElement>

    @POST("tournament/knockout")
    suspend fun startKnockout(@Body body: JsonObject): BaseResponse<JsonElement>

    @HTTP(method = "DELETE", path = "tournament/matches/knockout", hasBody = true)
    suspend fun deleteKnockoutMatches(@Body body: JsonObject): BaseResponse<JsonElement>

    @POST("tournament/modus")
    suspend fun setTournamentModus(@Body body: JsonObject): BaseResponse<JsonElement>

    @GET("tournament/matches/{clubId}/{tournamentId}")
    suspend fun getTournamentMatches(@Path("clubId") clubId: String, @Path("tournamentId") tournamentId: String): JsonElement

    @GET("tournament/classes/{clubId}/{tournamentId}")
    suspend fun getTournamentClasses(@Path("clubId") clubId: String, @Path("tournamentId") tournamentId: String): JsonElement

    @POST("tournament/class/{clubId}/{tournamentId}")
    suspend fun createTournamentClass(@Path("clubId") clubId: String, @Path("tournamentId") tournamentId: String, @Body body: JsonObject): BaseResponse<JsonElement>

    @PUT("tournament/class/{clubId}/{tournamentId}/{classId}")
    suspend fun updateTournamentClass(@Path("clubId") clubId: String, @Path("tournamentId") tournamentId: String, @Path("classId") classId: String, @Body body: JsonObject): BaseResponse<JsonElement>

    @DELETE("tournament/class/{clubId}/{tournamentId}/{classId}")
    suspend fun deleteTournamentClass(@Path("clubId") clubId: String, @Path("tournamentId") tournamentId: String, @Path("classId") classId: String): BaseResponse<JsonElement>

    @GET("tournament/stages")
    suspend fun getTournamentStages(@Query("clubId") clubId: String, @Query("tournamentId") tournamentId: String): JsonElement

    @PUT("tournament/stages")
    suspend fun updateTournamentStages(@Body body: JsonObject): BaseResponse<JsonElement>

    @POST("tournament/stages/advance")
    suspend fun advanceTournamentStage(@Body body: JsonObject): BaseResponse<JsonElement>

    // Official tournaments
    @GET("official-tournaments/{clubId}")
    suspend fun getOfficialTournaments(@Path("clubId") clubId: String): JsonElement

    @GET("official-tournaments/{clubId}/participations/summary")
    suspend fun getOfficialTournamentSummary(@Path("clubId") clubId: String): JsonElement

    @Multipart
    @POST("official-tournaments/{clubId}/upload")
    suspend fun uploadOfficialTournamentPdf(
        @Path("clubId") clubId: String,
        @Part pdf: MultipartBody.Part
    ): JsonElement

    @GET("official-tournaments/{clubId}/{id}")
    suspend fun getOfficialTournament(@Path("clubId") clubId: String, @Path("id") id: String): JsonElement

    @POST("official-tournaments/{clubId}/{id}/participation")
    suspend fun upsertOfficialParticipation(@Path("clubId") clubId: String, @Path("id") id: String, @Body body: JsonObject): BaseResponse<JsonElement>

    @POST("official-tournaments/{clubId}/{id}/status")
    suspend fun updateOfficialStatus(@Path("clubId") clubId: String, @Path("id") id: String, @Body body: JsonObject): BaseResponse<JsonElement>

    @DELETE("official-tournaments/{clubId}/{id}")
    suspend fun deleteOfficialTournament(@Path("clubId") clubId: String, @Path("id") id: String): BaseResponse<JsonElement>

    // MyTischtennis
    @GET("mytischtennis/account")
    suspend fun getMyTischtennisAccount(): JsonElement

    @GET("mytischtennis/status")
    suspend fun getMyTischtennisStatus(): JsonElement

    @POST("mytischtennis/verify")
    suspend fun verifyMyTischtennis(@Body body: JsonObject): JsonElement

    @POST("mytischtennis/account")
    suspend fun upsertMyTischtennisAccount(@Body body: JsonObject): BaseResponse<JsonElement>

    @DELETE("mytischtennis/account")
    suspend fun deleteMyTischtennisAccount(): BaseResponse<JsonElement>

    @GET("mytischtennis/update-history")
    suspend fun getMyTischtennisUpdateHistory(): JsonElement

    @POST("mytischtennis/parse-url")
    suspend fun parseMyTischtennisUrl(@Body body: JsonObject): JsonElement

    @POST("mytischtennis/configure-team")
    suspend fun configureMyTischtennisTeam(@Body body: JsonObject): BaseResponse<JsonElement>

    @POST("mytischtennis/configure-league")
    suspend fun configureMyTischtennisLeague(@Body body: JsonObject): BaseResponse<JsonElement>

    @POST("mytischtennis/fetch-team-data/async")
    suspend fun startMyTischtennisFetchJob(@Body body: JsonObject): JsonElement

    @GET("mytischtennis/fetch-team-data/jobs/{jobId}")
    suspend fun getMyTischtennisFetchJob(@Path("jobId") jobId: String): JsonElement

    // Logs
    @GET("logs")
    suspend fun getLogs(@QueryMap params: Map<String, String>): JsonElement

    @GET("logs/{id}")
    suspend fun getLogDetail(@Path("id") id: String): JsonElement

    @GET("logs/scheduler/last-executions")
    suspend fun getSchedulerExecutions(@Query("clubId") clubId: String? = null): JsonElement

    // NuScore
    @POST("nuscore/init-cookies/{code}")
    suspend fun initNuscoreCookies(@Path("code") code: String): BaseResponse<JsonElement>

    @GET("nuscore/meetinginfo/{code}")
    suspend fun getNuscoreMeetingInfo(@Path("code") code: String): JsonElement

    @GET("nuscore/meetingdetails/{uuid}")
    suspend fun getNuscoreMeetingDetails(@Path("uuid") uuid: String): JsonElement

    @PUT("nuscore/validate/{uuid}")
    suspend fun validateNuscoreReport(@Path("uuid") uuid: String, @Body body: JsonObject): JsonElement

    @PUT("nuscore/submit/{uuid}")
    suspend fun submitNuscoreReport(@Path("uuid") uuid: String, @Body body: JsonObject): JsonElement

    @POST("nuscore/broadcast-draft")
    suspend fun broadcastNuscoreDraft(@Body body: JsonObject): BaseResponse<JsonElement>
}
