package tech.nut.nut_player_android.models

import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
import tech.nut.player.model.statistic.GetStat
import tech.nut.player.model.statistic.PostStat
import tech.nut.player.model.statistic.Stat
import tech.nut.player.model.statistic.StatisticType
import tech.nut.player.model.subtitle.Caption
import tech.nut.player.model.subtitle.CaptionType

internal fun String.getMappedContent(): MappedContent {
    val flutterPlayerContent = this.getFlutterPlayerContent()
    return MappedContent(
        content = flutterPlayerContent.content,
        captions = flutterPlayerContent.captions?.toSubtitles()?.ifEmpty { null },
        stats = flutterPlayerContent.stats?.toStats()?.ifEmpty { null },
    )
}

private fun String.getFlutterPlayerContent(): FlutterPlayerContent {
    val jsonDecoder = Json {
        ignoreUnknownKeys = true
        useAlternativeNames = false
    }
    return jsonDecoder.decodeFromString(this)
}

private fun String.mapToStatisticType(): StatisticType? = when (this) {
    "video_start" -> StatisticType.VIDEO_START
    "video_load" -> StatisticType.VIDEO_LOAD
    "video_end" -> StatisticType.VIDEO_END
    else -> null
}

private fun List<FlutterPlayerStat>.toStats(): List<Stat> =
    mapNotNull { rawStat ->
        val type = rawStat.name.mapToStatisticType() ?: return@mapNotNull null
        when {
            rawStat.method.uppercase() == "GET" ->
                GetStat(
                    type = type,
                    urlTemplate = rawStat.urlTemplate,
                    start = rawStat.start,
                    count = rawStat.count,
                    delay = rawStat.delay,
                )

            rawStat.body != null ->
                PostStat(
                    type = type,
                    urlTemplate = rawStat.urlTemplate,
                    start = rawStat.start,
                    count = rawStat.count,
                    delay = rawStat.delay,
                    body = rawStat.body,
                )

            else -> null
        }
    }

private fun List<FlutterPlayerCaption>.toSubtitles(): List<Caption> =
    mapNotNull { rawSubtitle ->
        with(rawSubtitle) {
            if (language != null && url != null && title != null && type != null) {
                Caption(
                    title = title,
                    url = url,
                    language = language,
                    type = CaptionType.values().associateBy(CaptionType::value)[type.uppercase()]
                        ?: return@mapNotNull null
                )
            } else {
                null
            }
        }
    }