package de.tsschulz.tt_tagebuch.shared.api.serialization

import kotlinx.serialization.KSerializer
import kotlinx.serialization.builtins.ListSerializer
import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.json.JsonArray
import kotlinx.serialization.json.JsonDecoder
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.JsonNull
import kotlinx.serialization.json.JsonPrimitive

/**
 * Backend liefert `playersReady` / `playersPlanned` / `playersPlayed` als JSON-Spalte: mal `null`,
 * mal leeres Objekt statt Array. Die Web-UI parst das nicht strikt; kotlinx.serialization würde sonst
 * bei HTTP 200 trotzdem abbrechen.
 */
object LenientIntListSerializer : KSerializer<List<Int>> {
    private val delegate = ListSerializer(Int.serializer())
    override val descriptor: SerialDescriptor = delegate.descriptor

    override fun serialize(encoder: Encoder, value: List<Int>) {
        delegate.serialize(encoder, value)
    }

    override fun deserialize(decoder: Decoder): List<Int> {
        if (decoder !is JsonDecoder) {
            return delegate.deserialize(decoder)
        }
        return when (val element = decoder.decodeJsonElement()) {
            JsonNull -> emptyList()
            is JsonArray -> element.mapNotNull { parseIntJsonElement(it) }
            else -> emptyList()
        }
    }

    private fun parseIntJsonElement(el: JsonElement): Int? {
        val p = el as? JsonPrimitive ?: return null
        val c = p.content
        if (c.isBlank()) return null
        c.toIntOrNull()?.let { return it }
        c.toDoubleOrNull()?.let { return it.toInt() }
        return null
    }
}
