package com.swago.room.adapter

import android.graphics.Bitmap
import android.graphics.Color
import android.os.Build
import android.text.*
import android.text.method.LinkMovementMethod
import android.text.style.ClickableSpan
import android.text.style.ForegroundColorSpan
import android.text.style.ImageSpan
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.swago.baseswago.cusview.LiangView
import com.swago.baseswago.cusview.SwagoLevelView
import com.swago.baseswago.im.IRoomChat
import com.swago.baseswago.im.RoomMsgType
import com.swago.baseswago.model.im.RoomChatMsgBean
import com.swago.baseswago.model.im.UserJoinRoomBean
import com.swago.formatAr
import com.swago.room.R
import com.swago.room.adapter.bitmap.CenterAlignImageSpan
import com.swago.room.adapter.bitmap.CustomImageSpan
import com.swago.room.adapter.bitmap.HtmlImageGetter
import java.util.*
import kotlin.collections.ArrayList

/**
 *@date 2021/10/23 19:17
 *description:
 */
class RoomChatAdapter :
    BaseQuickAdapter<IRoomChat, BaseViewHolder>(R.layout.item_chat, arrayListOf()) {

    /**
     * 图标bitmap缓存
     */
    private val iconBitmapCachePool: HashMap<String, Bitmap> = HashMap()
    private val localImageKey = ArrayList<String>()

    companion object {
        const val LEVEL_KEY = "level"
        const val PRETTY_KEY = "pretty"//靓号
        const val VIP_KEY = "pretty"//每日首冲
        const val IS_OFFICIAL = "official"
        const val IS_SERVICE = "service"
        const val IS_CROWN = "crown"
        const val IS_CUP = "cup"
        const val IS_ADMIN = "admin"
    }

    init {
        localImageKey.add(LEVEL_KEY)
        localImageKey.add(PRETTY_KEY)
        localImageKey.add(VIP_KEY)
        localImageKey.add(IS_OFFICIAL)
        localImageKey.add(IS_SERVICE)
        localImageKey.add(IS_CROWN)
        localImageKey.add(IS_CUP)
        localImageKey.add(IS_ADMIN)
    }

    var showUserInfoDialog: ((iChatMsg: IRoomChat) -> Unit)? = null


    override fun convert(helper: BaseViewHolder, item: IRoomChat) {
        var count = 0
        helper.apply {
            val tvContent = itemView.findViewById<TextView>(R.id.tvContent)
            var span: SpannableString? = null
            when (item.getMsgType()) {
                RoomMsgType.ROOM_CHAT_TEXT -> {
                    val sb = StringBuffer()
                    if (item is RoomChatMsgBean&&item.isAdmin==1) {
                        count++
                        sb.append("<img src='" + "file:///xx/")
                            .append(IS_ADMIN).append(".png")
                            .append("'> ")
                    }

                    if (item.getIsPrettyId()) {
                        count++
                        sb.append("<img src='" + "file:///xx/")
                            .append(PRETTY_KEY).append(".png")
                            .append("'> ")
                    }

                    if (item.getIsBenefit() == 1) {
                        count++
                        sb.append("<img src='" + "file:///xx/")
                            .append(VIP_KEY).append(".png")
                            .append("'> ")
                    }

                    if (item is RoomChatMsgBean&&item.isCrown==1) {
                        count++
                        sb.append("<img src='" + "file:///xx/")
                            .append(IS_CROWN).append(".png")
                            .append("'> ")
                    }

                    if (item is RoomChatMsgBean&&item.isCup==1) {
                        count++
                        sb.append("<img src='" + "file:///xx/")
                            .append(IS_CUP).append(".png")
                            .append("'> ")
                    }

                    if (item is RoomChatMsgBean&&item.isService==1){
                        count++
                        sb.append("<img src='" + "file:///xx/")
                            .append(IS_SERVICE).append(".png")
                            .append("'> ")
                    }

                    if (item is RoomChatMsgBean&&item.isOfficial==1){
                        count++
                        sb.append("<img src='" + "file:///xx/")
                            .append(IS_OFFICIAL).append(".png")
                            .append("'> ")
                    }

                    count++
                    sb.append("<img src='" + "file:///xx/")
                        .append(LEVEL_KEY).append(".png")
                        .append("'> ")

                    sb.append(item.getSenderName())
                        .append("：")
                        .append(item.getMsgContent())

                    val glideImageGetter = HtmlImageGetter(mContext, tvContent, 14, localImageKey)
                    val fromHtml = Html.fromHtml(sb.toString(), glideImageGetter, null)
                    span = SpannableString(fromHtml)
                    setHtml(span, helper, item)


                    if (span.length < item.getSenderName().length + count) {
                        span.setSpan(
                            object : ClickableSpan() {
                                override fun onClick(widget: View) {
                                    showUserInfoDialog?.invoke(item)
                                }

                                override fun updateDrawState(ds: TextPaint) {}

                            },
                            0,
                            span.length,
                            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                        )
                    } else {
                        span.setSpan(
                            object : ClickableSpan() {
                                override fun onClick(widget: View) {
                                    showUserInfoDialog?.invoke(item)
                                }

                                override fun updateDrawState(ds: TextPaint) {}

                            },
                            0,
                            item.getSenderName().length + count,
                            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                        )
                    }



                    if (item.getIsBenefit() == 1) {
                        setBackgroundRes(R.id.tvContent, R.drawable.shape_e87230_ddb558_all_20)
                    } else {
                        setBackgroundRes(R.id.tvContent, R.drawable.shape_20000000_14)
                    }
                }

                RoomMsgType.SYSTEM_MESSAGE -> {
                    span = SpannableString(item.getMsgContent())
                    setBackgroundRes(R.id.tvContent, R.drawable.shape_20000000_14)
                }
                RoomMsgType.BECOME_MANAGER -> {
                    span = SpannableString(item.getMsgContent())
                    setBackgroundRes(R.id.tvContent, R.drawable.shape_20000000_14)
                    span.setSpan(
                        ForegroundColorSpan(
                            ContextCompat.getColor(
                                itemView.context,
                                R.color._ff9300
                            )
                        ), 0, item.getMsgContent().length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
                }
                RoomMsgType.FOLLOW_MESSAGE -> {
                    setBackgroundRes(R.id.tvContent, R.drawable.shape_20000000_14)
                    val sb = StringBuffer()

                    if (item.getIsPrettyId()) {
                        count++
                        sb.append("<img src='" + "file:///xx/")
                            .append(PRETTY_KEY).append(".png")
                            .append("'> ")
                    }

                    if (item.getIsBenefit() == 1) {
                        count++
                        sb.append("<img src='" + "file:///xx/")
                            .append(VIP_KEY).append(".png")
                            .append("'> ")
                    }

                    if (item is RoomChatMsgBean&&item.isCrown==1) {
                        count++
                        sb.append("<img src='" + "file:///xx/")
                            .append(IS_CROWN).append(".png")
                            .append("'> ")
                    }

                    if (item is RoomChatMsgBean&&item.isCup==1) {
                        count++
                        sb.append("<img src='" + "file:///xx/")
                            .append(IS_CUP).append(".png")
                            .append("'> ")
                    }

                    if (item is RoomChatMsgBean&&item.isService==1){
                        count++
                        sb.append("<img src='" + "file:///xx/")
                            .append(IS_SERVICE).append(".png")
                            .append("'> ")
                    }

                    if (item is RoomChatMsgBean&&item.isOfficial==1){
                        count++
                        sb.append("<img src='" + "file:///xx/")
                            .append(IS_OFFICIAL).append(".png")
                            .append("'> ")
                    }

                    count++
                    sb.append("<img src='" + "file:///xx/")
                        .append(LEVEL_KEY).append(".png")
                        .append("'> ")

                    sb.append(item.getSenderName())
                        .append("：")
                        .append(" <font color='#ffd917'>")
                        .append(item.getMsgContent())
                        .append("</font>")

                    val glideImageGetter = HtmlImageGetter(mContext, tvContent, 14, localImageKey)
                    val fromHtml = Html.fromHtml(sb.toString(), glideImageGetter, null)
                    span = SpannableString(fromHtml)
                    setHtml(span, helper, item)

                    if (span.length < item.getSenderName().length + count) {
                        span.setSpan(
                            object : ClickableSpan() {
                                override fun onClick(widget: View) {
                                    showUserInfoDialog?.invoke(item)
                                }

                                override fun updateDrawState(ds: TextPaint) {}

                            },
                            0,
                            span.length,
                            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                        )
                    } else {
                        span.setSpan(
                            object : ClickableSpan() {
                                override fun onClick(widget: View) {
                                    showUserInfoDialog?.invoke(item)
                                }

                                override fun updateDrawState(ds: TextPaint) {}

                            },
                            0,
                            item.getSenderName().length + count,
                            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                        )
                    }

                }
                RoomMsgType.USER_ENTER_ROOM -> {
                    val sb = StringBuffer()

                    if (item is UserJoinRoomBean&&item.isAdmin==1) {
                        count++
                        sb.append("<img src='" + "file:///xx/")
                            .append(IS_ADMIN).append(".png")
                            .append("'> ")
                    }

                    if (item.getIsPrettyId()) {
                        count++
                        sb.append("<img src='" + "file:///xx/")
                            .append(PRETTY_KEY).append(".png")
                            .append("'> ")
                    }

                    if (item.getIsBenefit() == 1) {
                        count++
                        sb.append("<img src='" + "file:///xx/")
                            .append(VIP_KEY).append(".png")
                            .append("'> ")
                    }

                    if (item is RoomChatMsgBean&&item.isCrown==1) {
                        count++
                        sb.append("<img src='" + "file:///xx/")
                            .append(IS_CROWN).append(".png")
                            .append("'> ")
                    }

                    if (item is RoomChatMsgBean&&item.isCup==1) {
                        count++
                        sb.append("<img src='" + "file:///xx/")
                            .append(IS_CUP).append(".png")
                            .append("'> ")
                    }

                    if (item is RoomChatMsgBean&&item.isService==1){
                        count++
                        sb.append("<img src='" + "file:///xx/")
                            .append(IS_SERVICE).append(".png")
                            .append("'> ")
                    }

                    if (item is RoomChatMsgBean&&item.isOfficial==1){
                        count++
                        sb.append("<img src='" + "file:///xx/")
                            .append(IS_OFFICIAL).append(".png")
                            .append("'> ")
                    }

                    count++
                    sb.append("<img src='" + "file:///xx/")
                        .append(LEVEL_KEY).append(".png")
                        .append("'> ")

                    sb.append(item.getSenderName())
                        .append("：")
                        .append(item.getMsgContent())

                    val glideImageGetter = HtmlImageGetter(mContext, tvContent, 14, localImageKey)
                    val fromHtml = Html.fromHtml(sb.toString(), glideImageGetter, null)
                    span = SpannableString(fromHtml)
                    setHtml(span, helper, item)

                    if (span.length < item.getSenderName().length + count) {
                        span.setSpan(
                            object : ClickableSpan() {
                                override fun onClick(widget: View) {
                                    showUserInfoDialog?.invoke(item)
                                }

                                override fun updateDrawState(ds: TextPaint) {}

                            },
                            0,
                            span.length,
                            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                        )
                    } else {
                        span.setSpan(
                            object : ClickableSpan() {
                                override fun onClick(widget: View) {
                                    showUserInfoDialog?.invoke(item)
                                }

                                override fun updateDrawState(ds: TextPaint) {}

                            },
                            0,
                            item.getSenderName().length + count,
                            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                        )
                    }

                    if (item.getIsBenefit() == 1) {
                        setBackgroundRes(R.id.tvContent, R.drawable.shape_ff56b7_14)
                    } else {
                        when (item.getUserLevel()) {
                            in 0..37 -> {
                                setBackgroundRes(R.id.tvContent, R.drawable.shape_20000000_14)
                            }
                            in 38..54 -> {
                                setBackgroundRes(R.id.tvContent, R.drawable.shape_6c55ff_20)
                            }
                            in 55..75 -> {
                                setBackgroundRes(R.id.tvContent, R.drawable.shape_6720d1_180c72_20)
                            }
                            in 76..97 -> {
                                setBackgroundRes(R.id.tvContent, R.drawable.shape_f8614b_8c2922_20)
                            }
                            in 98..1000 -> {
                                setBackgroundRes(R.id.tvContent, R.drawable.shape_434343_000000_20)
                            }
                        }
                    }

                }
            }
            tvContent.movementMethod = LinkMovementMethod.getInstance()
            tvContent.highlightColor = Color.TRANSPARENT
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                tvContent.text = span?.formatAr()?:""
            }else{
                tvContent.text = span
            }
        }
    }


    private fun setHtml(span: SpannableString, helper: BaseViewHolder, item: IRoomChat) {
        try {
            val imageSpans = span.getSpans(0, span.length, ImageSpan::class.java)
            var i = 0
            val size = imageSpans.size
            while (i < size) {
                val imageSpan = imageSpans[i]
                val d = imageSpan.drawable
                val newImageSpan =
                    CenterAlignImageSpan(d, ImageSpan.ALIGN_BASELINE)
                val start = span.getSpanStart(imageSpan)
                val end = span.getSpanEnd(imageSpan)
                val clickableSpans = span.getSpans(start, end, ClickableSpan::class.java)
                if (clickableSpans != null && clickableSpans.isNotEmpty()) {
                    for (cs in clickableSpans) {
                        span.removeSpan(cs)
                    }
                }
                if (imageSpan.source != null && imageSpan!!.source!!.contains(LEVEL_KEY)) {
                    span.setSpan(
                        setLevel(item.getUserLevel(), helper.itemView as ViewGroup),
                        start,
                        end,
                        Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                    )
                }else if(imageSpan.source != null && imageSpan!!.source!!.contains(IS_ADMIN)){
                    span.setSpan(
                        setAdmin(helper.itemView as ViewGroup),
                        start,
                        end,
                        Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                    )
                }  else if(imageSpan.source != null && imageSpan!!.source!!.contains(PRETTY_KEY)){
                    span.setSpan(
                        setPrettyId(item.getSenderId(), helper.itemView as ViewGroup),
                        start,
                        end,
                        Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                    )
                } else if(imageSpan.source != null && imageSpan!!.source!!.contains(IS_SERVICE)){
                    span.setSpan(
                        setService(helper.itemView as ViewGroup),
                        start,
                        end,
                        Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                    )
                } else if(imageSpan.source != null && imageSpan!!.source!!.contains(IS_OFFICIAL)){
                    span.setSpan(
                        setOfficial(helper.itemView as ViewGroup),
                        start,
                        end,
                        Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                    )
                }else if(imageSpan.source != null && imageSpan!!.source!!.contains(VIP_KEY)){
                    span.setSpan(
                        setVip(helper.itemView as ViewGroup),
                        start,
                        end,
                        Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                    )
                }else if(imageSpan.source != null && imageSpan!!.source!!.contains(IS_CROWN)){
                    span.setSpan(
                        setCrown(helper.itemView as ViewGroup),
                        start,
                        end,
                        Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                    )
                }else if(imageSpan.source != null && imageSpan!!.source!!.contains(IS_CUP)){
                    span.setSpan(
                        setCup(helper.itemView as ViewGroup),
                        start,
                        end,
                        Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                    )
                }else {
                    span.setSpan(newImageSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
                }
                span.removeSpan(imageSpan)
                i++
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    private fun setAdmin(viewGroup: ViewGroup): CustomImageSpan {
        var bm = iconBitmapCachePool["admin"]
        if (bm == null) {
            val view = LayoutInflater.from(mContext)
                .inflate(R.layout.item_admin, viewGroup, false) as ConstraintLayout
            view.measure(
                View.MeasureSpec.makeMeasureSpec(
                    (1 shl 30) - 1,
                    View.MeasureSpec.AT_MOST
                ),
                View.MeasureSpec.makeMeasureSpec(
                    (1 shl 30) - 1,
                    View.MeasureSpec.AT_MOST
                )
            )
            bm = convertViewToBitmap(view)
            if (bm != null) {
                iconBitmapCachePool["admin"] = bm
            }
        }
        return CustomImageSpan(mContext, bm, CustomImageSpan.ALIGN_FONTCENTER)
    }

    private fun setCup(viewGroup: ViewGroup): CustomImageSpan {
        var bm = iconBitmapCachePool["cup"]
        if (bm == null) {
            val view = LayoutInflater.from(mContext)
                .inflate(R.layout.item_cup, viewGroup, false) as ConstraintLayout
            view.measure(
                View.MeasureSpec.makeMeasureSpec(
                    (1 shl 30) - 1,
                    View.MeasureSpec.AT_MOST
                ),
                View.MeasureSpec.makeMeasureSpec(
                    (1 shl 30) - 1,
                    View.MeasureSpec.AT_MOST
                )
            )
            bm = convertViewToBitmap(view)
            if (bm != null) {
                iconBitmapCachePool["cup"] = bm
            }
        }
        return CustomImageSpan(mContext, bm, CustomImageSpan.ALIGN_FONTCENTER)
    }

    private fun setCrown(viewGroup: ViewGroup): CustomImageSpan {
        var bm = iconBitmapCachePool["crown"]
        if (bm == null) {
            val view = LayoutInflater.from(mContext)
                .inflate(R.layout.item_crown, viewGroup, false) as ConstraintLayout
            view.measure(
                View.MeasureSpec.makeMeasureSpec(
                    (1 shl 30) - 1,
                    View.MeasureSpec.AT_MOST
                ),
                View.MeasureSpec.makeMeasureSpec(
                    (1 shl 30) - 1,
                    View.MeasureSpec.AT_MOST
                )
            )
            bm = convertViewToBitmap(view)
            if (bm != null) {
                iconBitmapCachePool["crown"] = bm
            }
        }
        return CustomImageSpan(mContext, bm, CustomImageSpan.ALIGN_FONTCENTER)
    }

    private fun setVip(viewGroup: ViewGroup): CustomImageSpan {
        var bm = iconBitmapCachePool["vip"]
        if (bm == null) {
            val view = LayoutInflater.from(mContext)
                .inflate(R.layout.item_vip, viewGroup, false) as ConstraintLayout
            view.measure(
                View.MeasureSpec.makeMeasureSpec(
                    (1 shl 30) - 1,
                    View.MeasureSpec.AT_MOST
                ),
                View.MeasureSpec.makeMeasureSpec(
                    (1 shl 30) - 1,
                    View.MeasureSpec.AT_MOST
                )
            )
            bm = convertViewToBitmap(view)
            if (bm != null) {
                iconBitmapCachePool["vip"] = bm
            }
        }
        return CustomImageSpan(mContext, bm, CustomImageSpan.ALIGN_FONTCENTER)
    }


    private fun setService(viewGroup: ViewGroup):CustomImageSpan {
        var bm = iconBitmapCachePool["service"]
        if (bm == null) {
            val view = LayoutInflater.from(mContext)
                .inflate(R.layout.item_service, viewGroup, false) as ConstraintLayout
            view.measure(
                View.MeasureSpec.makeMeasureSpec(
                    (1 shl 30) - 1,
                    View.MeasureSpec.AT_MOST
                ),
                View.MeasureSpec.makeMeasureSpec(
                    (1 shl 30) - 1,
                    View.MeasureSpec.AT_MOST
                )
            )
            bm = convertViewToBitmap(view)
            if (bm != null) {
                iconBitmapCachePool["service"] = bm
            }
        }
        return CustomImageSpan(mContext, bm, CustomImageSpan.ALIGN_FONTCENTER)
    }

    private fun setOfficial(viewGroup: ViewGroup):CustomImageSpan {
        var bm = iconBitmapCachePool["official"]
        if (bm == null) {
            val view = LayoutInflater.from(mContext)
                .inflate(R.layout.item_official_icon, viewGroup, false) as ConstraintLayout
            view.measure(
                View.MeasureSpec.makeMeasureSpec(
                    (1 shl 30) - 1,
                    View.MeasureSpec.AT_MOST
                ),
                View.MeasureSpec.makeMeasureSpec(
                    (1 shl 30) - 1,
                    View.MeasureSpec.AT_MOST
                )
            )
            bm = convertViewToBitmap(view)
            if (bm != null) {
                iconBitmapCachePool["official"] = bm
            }
        }
        return CustomImageSpan(mContext, bm, CustomImageSpan.ALIGN_FONTCENTER)
    }

    private fun setPrettyId(senderId: String, viewGroup: ViewGroup): CustomImageSpan {
        var bm = iconBitmapCachePool[senderId + "level"]
        if (bm == null) {
            val view = LayoutInflater.from(mContext)
                .inflate(R.layout.item_liang, viewGroup, false) as LiangView
            view.measure(
                View.MeasureSpec.makeMeasureSpec(
                    (1 shl 30) - 1,
                    View.MeasureSpec.AT_MOST
                ),
                View.MeasureSpec.makeMeasureSpec(
                    (1 shl 30) - 1,
                    View.MeasureSpec.AT_MOST
                )
            )
            view.setUserId(true,senderId)
            bm = convertViewToBitmap(view)
            if (bm != null) {
                iconBitmapCachePool[senderId + "level"] = bm
            }
        }
        return CustomImageSpan(mContext, bm, CustomImageSpan.ALIGN_FONTCENTER)
    }


    private fun setLevel(iSenderLevel: Int, viewGroup: ViewGroup): CustomImageSpan {
        var level = iSenderLevel.toString()
        if (level.isNullOrEmpty()) {
            level = "1"
        }
        var bm = iconBitmapCachePool[level + "level"]
        if (bm == null) {
            val view = LayoutInflater.from(mContext)
                .inflate(R.layout.item_chat_level, viewGroup, false) as SwagoLevelView
            view.measure(
                View.MeasureSpec.makeMeasureSpec(
                    (1 shl 30) - 1,
                    View.MeasureSpec.AT_MOST
                ),
                View.MeasureSpec.makeMeasureSpec(
                    (1 shl 30) - 1,
                    View.MeasureSpec.AT_MOST
                )
            )
            view.setUserLevel(level.toInt())
            bm = convertViewToBitmap(view)
            if (bm != null) {
                iconBitmapCachePool[level + "level"] = bm
            }
        }

        return CustomImageSpan(mContext, bm, CustomImageSpan.ALIGN_FONTCENTER)
    }


    private fun convertViewToBitmap(view: View): Bitmap? {
        view.measure(
            View.MeasureSpec.makeMeasureSpec(
                (1 shl 30) - 1,
                View.MeasureSpec.AT_MOST
            ),
            View.MeasureSpec.makeMeasureSpec(
                (1 shl 30) - 1,
                View.MeasureSpec.AT_MOST
            )
        )
        view.layout(0, 0, view.measuredWidth, view.measuredHeight)
        view.buildDrawingCache()
        return view.drawingCache
    }
}