package de.tsschulz.tt_tagebuch.shared.api

import de.tsschulz.tt_tagebuch.shared.api.http.AuthedHttpClient
import de.tsschulz.tt_tagebuch.shared.api.models.Member
import de.tsschulz.tt_tagebuch.shared.api.models.MemberPlayInterestRowDto
import de.tsschulz.tt_tagebuch.shared.api.models.MemberPlayInterestSetBody
import de.tsschulz.tt_tagebuch.shared.api.models.MemberQuickMutationResponse
import de.tsschulz.tt_tagebuch.shared.api.models.MemberSetBody
import de.tsschulz.tt_tagebuch.shared.api.models.MemberTransferRunBody
import io.ktor.client.call.body
import io.ktor.client.request.forms.formData
import io.ktor.client.request.delete
import io.ktor.client.request.get
import io.ktor.client.request.parameter
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 io.ktor.client.request.forms.MultiPartFormDataContent
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonObject

@Serializable
data class MemberNoteMutationBody(
    val clubId: Int,
    val memberId: Int? = null,
    val content: String? = null,
)

class MembersApi(
    private val client: AuthedHttpClient,
) {
    suspend fun listMembers(clubId: Int, showAll: Boolean = true): List<Member> {
        return client.http.get("/api/clubmembers/get/$clubId/$showAll").body()
    }

    suspend fun listPlayInterests(clubId: Int, seasonId: Int, lineupHalf: String): List<MemberPlayInterestRowDto> {
        return client.http.get("/api/clubmembers/play-interest/$clubId") {
            parameter("seasonId", seasonId)
            parameter("lineupHalf", lineupHalf)
        }.body()
    }

    suspend fun setPlayInterest(clubId: Int, body: MemberPlayInterestSetBody) {
        client.http.post("/api/clubmembers/play-interest/$clubId") {
            setBody(body)
        }
    }

    suspend fun setMember(clubId: Int, body: MemberSetBody) {
        client.http.post("/api/clubmembers/set/$clubId") {
            setBody(body)
        }
    }

    suspend fun updateRatingsFromMyTischtennis(clubId: Int) {
        client.http.post("/api/clubmembers/update-ratings/$clubId")
    }

    suspend fun quickUpdateTestMembership(clubId: Int, memberId: Int): MemberQuickMutationResponse {
        return client.http.post("/api/clubmembers/quick-update-test-membership/$clubId/$memberId").body()
    }

    suspend fun quickUpdateMemberFormHandedOver(clubId: Int, memberId: Int): MemberQuickMutationResponse {
        return client.http.post("/api/clubmembers/quick-update-member-form/$clubId/$memberId").body()
    }

    suspend fun quickDeactivateMember(clubId: Int, memberId: Int): MemberQuickMutationResponse {
        return client.http.post("/api/clubmembers/quick-deactivate/$clubId/$memberId").body()
    }

    suspend fun requestClickTtRegistration(clubId: Int, memberId: Int): MemberQuickMutationResponse {
        return client.http.post("/api/clubmembers/clicktt-registration/$clubId/$memberId").body()
    }

    suspend fun listMemberNotes(clubId: Int, memberId: Int): List<de.tsschulz.tt_tagebuch.shared.api.models.DiaryMemberNoteDto> {
        return client.http.get("/api/member-notes/$memberId") {
            parameter("clubId", clubId)
        }.body()
    }

    suspend fun addMemberNote(clubId: Int, memberId: Int, content: String): List<de.tsschulz.tt_tagebuch.shared.api.models.DiaryMemberNoteDto> {
        return client.http.post("/api/member-notes") {
            setBody(MemberNoteMutationBody(clubId = clubId, memberId = memberId, content = content))
        }.body()
    }

    suspend fun deleteMemberNote(clubId: Int, noteId: Int): List<de.tsschulz.tt_tagebuch.shared.api.models.DiaryMemberNoteDto> {
        return client.http.delete("/api/member-notes/$noteId") {
            setBody(MemberNoteMutationBody(clubId = clubId))
        }.body()
    }

    suspend fun transferMembers(clubId: Int, body: MemberTransferRunBody): JsonObject {
        return client.http.post("/api/clubmembers/transfer/$clubId") {
            setBody(body)
        }.body()
    }

    suspend fun uploadMemberImage(clubId: Int, memberId: Int, imageBytes: ByteArray, makePrimary: Boolean = true) {
        client.http.post("/api/clubmembers/image/$clubId/$memberId") {
            if (makePrimary) {
                parameter("makePrimary", "true")
            }
            contentType(ContentType.MultiPart.FormData)
            setBody(
                MultiPartFormDataContent(
                    formData {
                        append(
                            "image",
                            imageBytes,
                            Headers.build {
                                append(HttpHeaders.ContentType, "image/jpeg")
                                append(HttpHeaders.ContentDisposition, "filename=\"member.jpg\"")
                            },
                        )
                    },
                ),
            )
        }
    }
}

