package com.remax.visualnovel.ui.chat.message.call.manager
import com.remax.visualnovel.extension.convertFromJson
import java.nio.charset.StandardCharsets


/**
 * text		字幕文本。
 *
 * language		字幕语言。
 *
 * userId		字幕源的 ID。如果字幕源是人类用户，则此值为人类用户的 UserId。如果字幕源是 AI 代理，则此值为 AI 代理的 UserId。
 *
 * sequence	整数	字幕序列号。
 *
 * definite	布尔值	字幕是否为完整的句段。
 * * true：是。
 * * false：否。
 *
 * paragraph	布尔值	副标题是否为完整句子。
 * * true：是。
 * * false：否。
 *
 * roundId	整数	 对话的回合 ID。
 *
 * 在不同的使用场景下，你可以根据definite、paragraph和sequence字段来决定如何处理字幕。
 * 实时字幕显示：
 * 如果paragraph=false且definite= false，则用较新的字幕（序列号更高）替换较旧的字幕。
 * 如果paragraph=false且definite= true，则开始一个新句子并替换前一个句子。
 * 如果paragraph= true，则表示一个完整句子的结束。此时继续解析并显示字幕将导致重复显示。
 */
data class SubtitleMsgData(
    val definite: Boolean?,
    val language: String?,
    val paragraph: Boolean?,
    val sequence: Int?,
    val text: String?,
    val userId: String?
)


data class SubtitleData(
    val data: List<SubtitleMsgData>?,
)

class BinaryMessageHandler() {
    fun unpack(message: ByteArray, callback: (SubtitleMsgData) -> Unit): Boolean {
        val kSubtitleHeaderSize = 8
        if (message.size < kSubtitleHeaderSize) {
            return false
        }
        // Magic number "subv"
        val magic = ((message[0].toInt() and 0xFF shl 24) or
                (message[1].toInt() and 0xFF shl 16) or
                (message[2].toInt() and 0xFF shl 8) or
                (message[3].toInt() and 0xFF)).toUInt()
        if (magic != 0x73756276U) {
            RTCManager.log("unpack magic != 0x73756276U")
            return false
        }

        val length = ((message[4].toInt() and 0xFF shl 24) or
                (message[5].toInt() and 0xFF shl 16) or
                (message[6].toInt() and 0xFF shl 8) or
                (message[7].toInt() and 0xFF)).toUInt()

        if (message.size - kSubtitleHeaderSize != length.toInt()) {
            RTCManager.log("unpack != length.toInt()")
            return false
        }

        if (length > 0U) {
            val subtitleBytes = message.copyOfRange(kSubtitleHeaderSize, message.size)
            parseData(String(subtitleBytes, StandardCharsets.UTF_8), callback)
        } else {
            parseData("", callback)
        }
        return true
    }

    // Parse
    private fun parseData(msg: String, callback: (SubtitleMsgData) -> Unit) {
        val subtitles = msg.convertFromJson<SubtitleData>()
        // 这里可以进一步处理 subtitles 列表，例如打印或存储
        subtitles?.data?.forEach {
            RTCManager.log("Parsed subtitles: $it")
            callback.invoke(it)
        }
    }
}