package kr.co.vividnext.sodalive.live.room.chat

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Typeface
import android.text.SpannableString
import android.text.Spanned
import android.text.TextUtils
import android.text.style.ForegroundColorSpan
import android.text.style.StyleSpan
import android.view.View
import androidx.annotation.Keep
import androidx.core.content.ContextCompat
import androidx.core.content.res.ResourcesCompat
import androidx.core.view.setPadding
import androidx.viewbinding.ViewBinding
import coil.load
import coil.transform.RoundedCornersTransformation
import com.google.gson.annotations.SerializedName
import kr.co.vividnext.sodalive.R
import kr.co.vividnext.sodalive.common.CustomTypefaceSpan
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
import kr.co.vividnext.sodalive.databinding.ItemLiveRoomChatBinding
import kr.co.vividnext.sodalive.databinding.ItemLiveRoomDonationStatusChatBinding
import kr.co.vividnext.sodalive.databinding.ItemLiveRoomJoinChatBinding
import kr.co.vividnext.sodalive.extensions.dpToPx
import kr.co.vividnext.sodalive.extensions.moneyFormat
import kr.co.vividnext.sodalive.live.room.donation.GetLiveRoomDonationStatusResponse

enum class LiveRoomChatType {
    @SerializedName("CHAT")
    CHAT,

    @SerializedName("DONATION_STATUS")
    DONATION_STATUS,

    @SerializedName("JOIN")
    JOIN
}

abstract class LiveRoomChat {
    open var type: LiveRoomChatType = LiveRoomChatType.CHAT
    abstract fun bind(
        context: Context,
        binding: ViewBinding,
        onClickProfile: ((Long) -> Unit)? = null
    )
}

@Keep
data class LiveRoomJoinChat(
    val nickname: String
) : LiveRoomChat() {
    override var type = LiveRoomChatType.JOIN
    override fun bind(context: Context, binding: ViewBinding, onClickProfile: ((Long) -> Unit)?) {
        (binding as ItemLiveRoomJoinChatBinding).tvJoin.setTextColor(
            ContextCompat.getColor(context, R.color.color_eeeeee)
        )
        val str = "'$nickname'님이 입장하셨습니다."
        val spStr = SpannableString(str)

        spStr.setSpan(
            ForegroundColorSpan(
                ContextCompat.getColor(
                    context,
                    R.color.color_ffdc00
                )
            ),
            str.indexOf("'") + 1,
            str.indexOf("'님"),
            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
        )

        spStr.setSpan(
            StyleSpan(Typeface.BOLD),
            str.indexOf("'"),
            str.indexOf("'님"),
            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
        )

        (binding as ItemLiveRoomJoinChatBinding).tvJoin.text = spStr
        binding.root.setBackgroundResource(R.drawable.bg_round_corner_4_7_cc004462)
    }
}

@Keep
data class LiveRoomDonationStatusChat(
    val response: GetLiveRoomDonationStatusResponse? = null,
    val donationStatusString: String? = null
) : LiveRoomChat() {
    override var type = LiveRoomChatType.DONATION_STATUS
    override fun bind(context: Context, binding: ViewBinding, onClickProfile: ((Long) -> Unit)?) {
        if (donationStatusString != null) {
            (binding as ItemLiveRoomDonationStatusChatBinding)
                .tvDonationList
                .text = donationStatusString
        } else {
            (binding as ItemLiveRoomDonationStatusChatBinding)
                .tvDonationList
                .text = getDonationString(context)
        }
    }

    fun getDonationString(context: Context): String {
        if (response != null) {
            var donationStatusString: CharSequence = "[현재 라이브 후원현황]\n\n"
            for (index in response.donationList.indices) {
                val donation = response.donationList[index]
                val spChars = SpannableString(
                    "${index + 1}. " +
                        if (donation.nickname.length > 10) {
                            "${donation.nickname.substring(0, 10)} : "
                        } else {
                            "${donation.nickname} : "
                        } + "(${donation.can.moneyFormat()} 캔)\n"
                )
                spChars.setSpan(
                    ForegroundColorSpan(
                        ContextCompat.getColor(
                            context,
                            R.color.color_fdca2f
                        )
                    ),
                    spChars.indexOf(": (") + 3,
                    spChars.indexOf(")"),
                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                )

                donationStatusString = TextUtils.concat(
                    donationStatusString, spChars
                )
            }

            donationStatusString = TextUtils.concat(
                donationStatusString,
                "\n-------------------------\n\n"
            )

            donationStatusString = TextUtils.concat(
                donationStatusString,
                "후원인원 : ${response.totalCount} 명\n"
            )

            donationStatusString = TextUtils.concat(
                donationStatusString,
                "후원합계 : ${response.totalCan.moneyFormat()} 캔"
            )

            return donationStatusString.toString()
        } else {
            return ""
        }
    }
}

@Keep
data class LiveRoomNormalChat(
    @SerializedName("userId") val userId: Long,
    @SerializedName("profileUrl") val profileUrl: String,
    @SerializedName("nickname") val nickname: String,
    @SerializedName("rank") val rank: Int,
    @SerializedName("chat") val chat: String,
) : LiveRoomChat() {
    override fun bind(context: Context, binding: ViewBinding, onClickProfile: ((Long) -> Unit)?) {
        val itemBinding = binding as ItemLiveRoomChatBinding
        itemBinding.ivProfile.load(profileUrl) {
            crossfade(true)
            placeholder(R.drawable.ic_place_holder)
            transformations(RoundedCornersTransformation(23.3f.dpToPx()))
        }

        itemBinding.ivProfile.setOnClickListener {
            if (onClickProfile != null && userId != SharedPreferenceManager.userId) {
                onClickProfile(userId)
            }
        }

        itemBinding.tvChat.text = chat
        itemBinding.tvNickname.text = nickname

        itemBinding.ivBg.visibility = View.VISIBLE
        itemBinding.ivRoulette.visibility = View.GONE
        itemBinding.tvCreatorOrManager.visibility = View.GONE

        when (rank + 1) {
            -2 -> {
                itemBinding.ivBg.setImageResource(R.drawable.bg_circle_4999e3)
                itemBinding.ivCrown.setImageResource(R.drawable.ic_badge_manager)
                itemBinding.tvCreatorOrManager.setBackgroundResource(
                    R.drawable.bg_round_corner_2_4999e3
                )
                itemBinding.tvCreatorOrManager.text = "스탭"

                itemBinding.ivCrown.visibility = View.VISIBLE
                itemBinding.tvCreatorOrManager.visibility = View.VISIBLE
            }

            -1 -> {
                itemBinding.ivBg.setImageResource(R.drawable.bg_circle_3bb9f1)
                itemBinding.ivCrown.setImageResource(R.drawable.ic_crown)
                itemBinding.ivCrown.visibility = View.VISIBLE
            }

            1 -> {
                itemBinding.ivBg.setImageResource(R.drawable.bg_circle_ffdc00_fdca2f)
                itemBinding.ivCrown.setImageResource(R.drawable.ic_crown_1)
                itemBinding.ivCrown.visibility = View.VISIBLE
            }

            2 -> {
                itemBinding.ivBg.setImageResource(R.drawable.bg_circle_9f9f9f_dcdcdc)
                itemBinding.ivCrown.setImageResource(R.drawable.ic_crown_2)
                itemBinding.ivCrown.visibility = View.VISIBLE
            }

            3 -> {
                itemBinding.ivBg.setImageResource(R.drawable.bg_circle_e5a578_c67e4a)
                itemBinding.ivCrown.setImageResource(R.drawable.ic_crown_3)
                itemBinding.ivCrown.visibility = View.VISIBLE
            }

            else -> {
                itemBinding.ivBg.setImageResource(R.drawable.bg_circle_9f9f9f_bbbbbb)
                itemBinding.ivCrown.visibility = View.GONE
            }
        }

        val messageHorizontalPadding = 8.dpToPx().toInt()
        val messageVerticalPadding = 5.3f.dpToPx().toInt()
        itemBinding.llMessageBg.setPadding(
            messageHorizontalPadding,
            messageVerticalPadding,
            messageHorizontalPadding,
            messageVerticalPadding
        )

        if (SharedPreferenceManager.userId == userId) {
            itemBinding.llMessageBg.setBackgroundResource(R.drawable.bg_round_corner_3_3_553bb9f1)
        } else {
            itemBinding.llMessageBg.setBackgroundResource(R.drawable.bg_round_corner_3_3_99000000)
        }
        itemBinding.ivCan.visibility = View.GONE
        itemBinding.tvDonationMessage.visibility = View.GONE
        itemBinding.root.setBackgroundResource(0)
        itemBinding.root.setPadding(0)
    }
}

@Keep
data class LiveRoomDonationChat(
    @SerializedName("memberId") val memberId: Long,
    @SerializedName("profileUrl") val profileUrl: String,
    @SerializedName("nickname") val nickname: String,
    @SerializedName("chat") val chat: String,
    @SerializedName("can") val can: Int,
    @SerializedName("donationMessage") val donationMessage: String
) : LiveRoomChat() {
    @SuppressLint("SetTextI18n")
    override fun bind(context: Context, binding: ViewBinding, onClickProfile: ((Long) -> Unit)?) {
        val itemBinding = binding as ItemLiveRoomChatBinding
        val spChat = SpannableString(chat)
        spChat.setSpan(
            ForegroundColorSpan(
                ContextCompat.getColor(
                    context,
                    R.color.color_fdca2f
                )
            ),
            0,
            chat.indexOf("캔", 0, true) + 1,
            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
        )

        val spNickname = SpannableString("${nickname}님이")
        spNickname.setSpan(
            CustomTypefaceSpan(
                ResourcesCompat.getFont(
                    context,
                    R.font.gmarket_sans_medium
                )
            ),
            0,
            nickname.length,
            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
        )

        itemBinding.ivProfile.load(profileUrl) {
            crossfade(true)
            placeholder(R.drawable.ic_place_holder)
            transformations(RoundedCornersTransformation(23.3f.dpToPx()))
        }
        itemBinding.tvChat.text = spChat
        itemBinding.tvNickname.text = spNickname
        itemBinding.ivProfile.setOnClickListener {}

        itemBinding.ivCan.visibility = View.VISIBLE
        itemBinding.ivBg.visibility = View.GONE
        itemBinding.ivCrown.visibility = View.GONE
        itemBinding.ivRoulette.visibility = View.GONE
        itemBinding.tvCreatorOrManager.visibility = View.GONE

        if (donationMessage.isNotBlank()) {
            itemBinding.tvDonationMessage.text = "\"$donationMessage\""
            itemBinding.tvDonationMessage.visibility = View.VISIBLE
        } else {
            itemBinding.tvDonationMessage.visibility = View.GONE
        }

        itemBinding.llMessageBg.setPadding(0)
        itemBinding.llMessageBg.background = null

        if (spChat.contains("비밀")) {
            itemBinding.root.setBackgroundResource(R.drawable.bg_round_corner_6_7_cc59548f)
        } else {
            itemBinding.root.setBackgroundResource(
                when {
                    can >= 10000 -> {
                        R.drawable.bg_round_corner_6_7_ccc25264
                    }

                    can >= 5000 -> {
                        R.drawable.bg_round_corner_6_7_ccd85e37
                    }

                    can >= 1000 -> {
                        R.drawable.bg_round_corner_6_7_ccd38c38
                    }

                    can >= 500 -> {
                        R.drawable.bg_round_corner_6_7_cc59548f
                    }

                    can >= 100 -> {
                        R.drawable.bg_round_corner_6_7_cc4d6aa4
                    }

                    can >= 50 -> {
                        R.drawable.bg_round_corner_6_7_cc2d7390
                    }

                    else -> {
                        R.drawable.bg_round_corner_6_7_cc548f7d
                    }
                }
            )
        }
        itemBinding.root.setPadding(33)
    }
}

@Keep
data class LiveRoomRouletteDonationChat(
    @SerializedName("profileUrl") val profileUrl: String,
    @SerializedName("nickname") val nickname: String,
    @SerializedName("rouletteResult") val rouletteResult: String
) : LiveRoomChat() {
    override fun bind(context: Context, binding: ViewBinding, onClickProfile: ((Long) -> Unit)?) {
        val itemBinding = binding as ItemLiveRoomChatBinding
        val chat = "[$rouletteResult] 당첨!"
        val spChat = SpannableString(chat)
        spChat.setSpan(
            ForegroundColorSpan(
                ContextCompat.getColor(
                    context,
                    R.color.color_ffe500
                )
            ),
            0,
            chat.indexOf("]", 0, true) + 1,
            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
        )

        val spNickname = SpannableString("${nickname}님의 룰렛 결과?")
        spNickname.setSpan(
            StyleSpan(Typeface.NORMAL),
            0,
            nickname.length,
            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
        )

        itemBinding.ivProfile.load(profileUrl) {
            crossfade(true)
            placeholder(R.drawable.ic_place_holder)
            transformations(RoundedCornersTransformation(23.3f.dpToPx()))
        }
        itemBinding.tvChat.text = spChat
        itemBinding.tvNickname.text = spNickname
        itemBinding.ivProfile.setOnClickListener {}

        itemBinding.ivCan.visibility = View.GONE
        itemBinding.ivBg.visibility = View.GONE
        itemBinding.ivCrown.visibility = View.GONE
        itemBinding.tvCreatorOrManager.visibility = View.GONE
        itemBinding.ivRoulette.visibility = View.VISIBLE

        itemBinding.tvDonationMessage.visibility = View.GONE

        itemBinding.llMessageBg.setPadding(0)
        itemBinding.llMessageBg.background = null

        itemBinding.root.setBackgroundResource(R.drawable.bg_round_corner_6_7_ccc25264)
        itemBinding.root.setPadding(33)
    }
}
