package de.tsschulz.tt_tagebuch.shared.api

import de.tsschulz.tt_tagebuch.shared.api.http.AuthedHttpClient
import de.tsschulz.tt_tagebuch.shared.api.models.OfficialParticipationBucketDto
import de.tsschulz.tt_tagebuch.shared.api.models.OfficialParsedTournamentEnvelopeDto
import de.tsschulz.tt_tagebuch.shared.api.models.OfficialPatchTournamentBody
import de.tsschulz.tt_tagebuch.shared.api.models.OfficialParticipantStatusBody
import de.tsschulz.tt_tagebuch.shared.api.models.OfficialParticipantStatusResponseDto
import de.tsschulz.tt_tagebuch.shared.api.models.OfficialTournamentListRowDto
import de.tsschulz.tt_tagebuch.shared.api.models.OfficialTournamentUploadResultDto
import de.tsschulz.tt_tagebuch.shared.api.models.OfficialUpsertParticipationBody
import de.tsschulz.tt_tagebuch.shared.api.models.OfficialUpsertParticipationResponseDto
import io.ktor.client.call.body
import io.ktor.client.request.delete
import io.ktor.client.request.forms.MultiPartFormDataContent
import io.ktor.client.request.forms.formData
import io.ktor.client.request.get
import io.ktor.client.request.patch
import io.ktor.client.request.post
import io.ktor.client.request.setBody
import io.ktor.http.ContentType
import io.ktor.http.Headers
import io.ktor.http.HttpHeaders
import io.ktor.http.contentType
import kotlinx.serialization.json.JsonElement

class OfficialTournamentsApi(
    private val client: AuthedHttpClient,
) {
    suspend fun listForClub(clubId: Int): List<OfficialTournamentListRowDto> {
        return client.http.get("/api/official-tournaments/$clubId").body()
    }

    suspend fun listParticipationSummary(clubId: Int): List<OfficialParticipationBucketDto> {
        return client.http.get("/api/official-tournaments/$clubId/participations/summary").body()
    }

    suspend fun uploadPdf(clubId: Int, pdfBytes: ByteArray, fileName: String = "turnier.pdf"): OfficialTournamentUploadResultDto {
        return client.http.post("/api/official-tournaments/$clubId/upload") {
            contentType(ContentType.MultiPart.FormData)
            setBody(
                MultiPartFormDataContent(
                    formData {
                        append(
                            "pdf",
                            pdfBytes,
                            Headers.build {
                                append(HttpHeaders.ContentType, "application/pdf")
                                append(
                                    HttpHeaders.ContentDisposition,
                                    "filename=\"${fileName.replace("\"", "")}\"",
                                )
                            },
                        )
                    },
                ),
            )
        }.body()
    }

    suspend fun getParsed(clubId: Int, tournamentId: Int): OfficialParsedTournamentEnvelopeDto {
        return client.http.get("/api/official-tournaments/$clubId/$tournamentId").body()
    }

    suspend fun patchTournament(clubId: Int, tournamentId: Int, body: OfficialPatchTournamentBody): JsonElement {
        return client.http.patch("/api/official-tournaments/$clubId/$tournamentId") {
            setBody(body)
        }.body()
    }

    suspend fun deleteTournament(clubId: Int, tournamentId: Int) {
        client.http.delete("/api/official-tournaments/$clubId/$tournamentId")
    }

    suspend fun upsertParticipation(
        clubId: Int,
        tournamentId: Int,
        body: OfficialUpsertParticipationBody,
    ): OfficialUpsertParticipationResponseDto {
        return client.http.post("/api/official-tournaments/$clubId/$tournamentId/participation") {
            setBody(body)
        }.body()
    }

    suspend fun updateParticipantStatus(
        clubId: Int,
        tournamentId: Int,
        body: OfficialParticipantStatusBody,
    ): OfficialParticipantStatusResponseDto {
        return client.http.post("/api/official-tournaments/$clubId/$tournamentId/status") {
            setBody(body)
        }.body()
    }

    suspend fun autoRegister(clubId: Int, tournamentId: Int): JsonElement {
        return client.http.post("/api/official-tournaments/$clubId/$tournamentId/auto-register").body()
    }
}
