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

import com.adealink.frame.data.json.froJsonErrorNull
import com.google.gson.annotations.SerializedName
import io.trtc.tuikit.atomicxcore.api.barrage.Barrage
import io.trtc.tuikit.atomicxcore.api.barrage.BarrageType

fun Barrage.isSupportNotification(): Boolean {
    if (messageType == BarrageType.CUSTOM) {
        return true
    }
    return false
}

fun List<Barrage>.toNotifications(): List<Notification> {
    return filter { it.isSupportNotification() }
        .map { it.toNotification() }
}

fun Barrage.toNotification(): Notification {
    if (messageType == BarrageType.CUSTOM) {
        val content = when (NotificationCmd.getCmdType(businessID)) {
            NotificationCmd.CLEAR_MIC_APPLY -> {
                froJsonErrorNull<ClearMicNotificationContent>(data) ?: UnknownNotificationContent()
            }

            NotificationCmd.SEND_GIFT -> {
                froJsonErrorNull<List<SendGiftNotificationData>>(data)?.let {
                    SendGiftNotificationContent(it)
                } ?: UnknownNotificationContent()
            }

            NotificationCmd.UNKNOWN -> {
                UnknownNotificationContent()
            }
        }

        return Notification(this, content)
    }
    return Notification(this, UnknownNotificationContent())
}

data class Notification(
    val barrage: Barrage,
    val content: NotificationContent
)


enum class NotificationCmd(val cmd: String, val clazz: Class<*>?) {
    CLEAR_MIC_APPLY("mic.clear", ClearMicNotificationContent::class.java),
    SEND_GIFT("room.gift", SendGiftNotificationContent::class.java),

    UNKNOWN("unknown", UnknownNotificationContent::class.java);

    companion object {

        fun getCmdType(cmd: String): NotificationCmd {
            for (entry in entries) {
                if (entry.cmd.equals(cmd, ignoreCase = true)) {
                    return entry
                }
            }
            return UNKNOWN
        }

        fun getCmdClass(cmd: String): Class<*>? {
            return getCmdType(cmd).clazz
        }
    }
}


sealed class NotificationContent(@SerializedName("cmd") val cmd: NotificationCmd)

data class ClearMicNotificationContent(
    @SerializedName("type") val type: Int, //嘉宾:1, 陪玩师:2
    @SerializedName("time") val ts: Long,
) : NotificationContent(NotificationCmd.CLEAR_MIC_APPLY) {
    fun isClearGuest(): Boolean {
        return type == 1
    }

    fun isClearPlaymate(): Boolean {
        return type == 2
    }
}

data class SendGiftNotificationContent(
    @SerializedName("list") val list: List<SendGiftNotificationData>
) : NotificationContent(NotificationCmd.SEND_GIFT)

data class SendGiftNotificationData(
    @SerializedName("sender") val sender: String, //
    @SerializedName("receivers") val receivers: List<String>, //
    @SerializedName("quantity") val quantity: Long,
    @SerializedName("resId") val resId: String,
    @SerializedName("users") val users: Map<String, NotificationUserInfo>
) {

    fun getUserInfo(uid: String): NotificationUserInfo {
        return users[uid] ?: NotificationUserInfo.emptyUserInfo(uid)
    }
}

data class NotificationUserInfo(
    @SerializedName("id") val uid: String,
    @SerializedName("nickname") val nickname: String,
) {
    companion object {
        @JvmStatic
        fun emptyUserInfo(uid: String): NotificationUserInfo {
            return NotificationUserInfo(uid, uid)
        }
    }
}


class UnknownNotificationContent : NotificationContent(NotificationCmd.UNKNOWN)
