package com.adealink.weparty.module.room.chat.data

import com.adealink.frame.data.json.froJsonErrorNull
import com.adealink.weparty.commonui.recycleview.diffutil.BaseListItemData
import com.adealink.weparty.module.profile.data.UserInfo
import com.adealink.weparty.module.room.chat.livemessage.ILiveMessage
import com.google.gson.annotations.SerializedName
import io.trtc.tuikit.atomicxcore.api.barrage.Barrage
import io.trtc.tuikit.atomicxcore.api.barrage.BarrageType

const val MESSAGE_TYPE = "type"

//房间用户消息子类型
const val MESSAGE_TYPE_TEXT = "0"

//房间消息
const val ROOM_MESSAGE_ENTER_ROOM = "room_message_enter_room"

//送礼消息
const val ROOM_MESSAGE_SEND_GIFT = "room_message_send_gift"

//fun Barrage.isSupportMessage(): Boolean {
//    if (messageType == BarrageType.TEXT) {
//        return true
//    }
//    return false
//}

/**
 * 子线程执行, 耗时
 */
fun List<Barrage>.toMessages(filterUnSupport: Boolean = true): List<Message> {
    return map { it.toMessage() }
        .filter { it !is UnknownMessage }
}

fun Barrage.toMessage(): Message {
    if (messageType == BarrageType.TEXT) {
        when (extensionInfo[MESSAGE_TYPE]) {
            MESSAGE_TYPE_TEXT -> {
                return TextMessage(this)
            }
        }
        if (businessID == ROOM_MESSAGE_ENTER_ROOM) {
            return EnterRoomMessage(this)
        }
        if (businessID == ROOM_MESSAGE_SEND_GIFT) {
            return SendGiftMessage(this, froJsonErrorNull(this.data, SendGiftContent::class.java))
        }
    }
    return UnknownMessage(this)
}

sealed class Message(open val barrage: Barrage) : ILiveMessage, BaseListItemData {

    var senderUserInfo: UserInfo? = null

    fun senderUid(): String {
        return barrage.sender.userID
    }


    var index = -1L
    override fun index(): Long {
        return index
    }

    override fun areContentsTheSame(newItem: Any): Boolean {
        return newItem is Message
                && barrage.sequence == newItem.barrage.sequence
                && barrage.timestampInSecond == newItem.barrage.timestampInSecond
                && barrage.sender == newItem.barrage.sender
    }
}

data class EnterRoomMessage(override val barrage: Barrage) : Message(barrage)

data class TextMessage(override val barrage: Barrage) : Message(barrage) {
    fun getText(): String {
        return barrage.textContent
    }
}

data class SendGiftMessage(override val barrage: Barrage, val content: SendGiftContent?) : Message(barrage)
data class SendGiftContent(
    @SerializedName("sender") val sender: String,
    @SerializedName("receiver") val receiver: String,
    @SerializedName("quantity") val quantity: Long,
    @SerializedName("resId") val resId: String,
    @SerializedName("users") val users: Map<String, NotificationUserInfo>
) {
    fun getSenderName(): String {
        return users[sender]?.nickname ?: sender
    }

    fun getReceiverName(): String {
        return users[receiver]?.nickname ?: receiver
    }
}

data class UnknownMessage(override val barrage: Barrage) : Message(barrage)