package com.gh.gamecenter.gamedetail.rating

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.ColorDrawable
import android.net.Uri
import android.text.SpannableStringBuilder
import android.text.Spanned
import android.text.TextPaint
import android.text.method.LinkMovementMethod
import android.text.style.ClickableSpan
import android.text.style.LeadingMarginSpan
import android.view.LayoutInflater
import android.view.View
import android.widget.LinearLayout
import android.widget.PopupWindow
import android.widget.TextView
import androidx.core.content.ContextCompat
import com.gh.common.util.*
import com.gh.common.util.DialogUtils
import com.gh.common.util.NewFlatLogUtils
import com.gh.common.util.NewLogUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.WebActivity
import com.gh.gamecenter.common.base.BaseRecyclerViewHolder
import com.gh.gamecenter.common.base.activity.BaseActivity
import com.gh.gamecenter.common.callback.ConfirmListener
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.view.CustomLinkMovementMethod
import com.gh.gamecenter.common.view.DrawableView
import com.gh.gamecenter.core.utils.*
import com.gh.gamecenter.databinding.RatingCommentItemBinding
import com.gh.gamecenter.entity.RatingComment
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.gamedetail.rating.edit.RatingEditActivity
import com.gh.gamecenter.gamedetail.rating.edit.RatingEditActivity.Companion.LABEL_REGEX
import com.gh.gamecenter.gamedetail.rating.logs.CommentLogsActivity
import com.gh.gamecenter.login.user.UserManager
import com.squareup.picasso.Picasso
import io.reactivex.Single
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import java.util.regex.Pattern

class RatingCommentItemViewHolder(val binding: RatingCommentItemBinding) : BaseRecyclerViewHolder<Any>(binding.root) {

    fun setContent(
        commentData: RatingComment,
        viewModel: RatingViewModel,
        dataPosition: Int,
        entrance: String,
        path: String,
        deleteCallback: () -> Unit
    ) {
        initContentTv(commentData)
        initItemView(commentData)
        initTimeTv(commentData)
        initUserBadgeView(commentData)
        initReplyTv(commentData)
        initVersionTv(commentData, viewModel.game)
        initBadgeTv(commentData)
        initViewClickListener(commentData, viewModel, dataPosition, entrance, path, deleteCallback)
        initAuditTv(commentData, viewModel.game, dataPosition)
    }

    private fun initContentTv(commentData: RatingComment) {
        binding.run {
            val p = Pattern.compile(LABEL_REGEX)
            val m = p.matcher(commentData.content)
            if (m.find()) {
                val contents = TextHelper.getCommentLabelSpannableStringBuilder(commentData.content, R.color.theme_font)
                content.setTextWithHighlightedTextWrappedInsideWrapper(text = contents, copyClickedText = true)
            } else {
                content.setTextWithHighlightedTextWrappedInsideWrapper(
                    text = commentData.content,
                    copyClickedText = true
                )
            }
        }
    }

    private fun initItemView(commentData: RatingComment) {
        binding.run {
            val context = itemView.context
            commentItem.setBackgroundColor(R.color.background_white.toColor(context))
            commentItem.setPadding(
                0,
                0,
                0,
                if (!commentData.active || commentData.replyData != null) 16f.dip2px() else 0
            )
            userName.setTextColor(R.color.text_title.toColor(context))
            userName.text = commentData.user.name
            ratingStart.rating = commentData.star.toFloat()
            device.text = commentData.getDevice()
            device.goneIf(!commentData.active || commentData.getDevice().isEmpty())
            version.goneIf(!commentData.active || commentData.gameVersion.isEmpty())
            comment.setDrawableStart(R.drawable.community_comment_count, 20F.dip2px(), 20F.dip2px())
            comment.text = if (commentData.reply > 0) NumberUtils.transSimpleCount(commentData.reply) else ""
            vote.setDrawableStart(R.drawable.comment_vote_selector, 20F.dip2px(), 20F.dip2px())
            vote.isChecked = commentData.me.isVoted
            vote.text = if (commentData.vote > 0) NumberUtils.transSimpleCount(commentData.vote) else ""
            groupCl.goneIf(!commentData.active)
            audit.goneIf(commentData.active)
            line.goneIf(!(commentData.replyData != null && commentData.active))
            replyContainer.goneIf(!(commentData.replyData != null && commentData.active))
            replyMore.goneIf(commentData.reply <= 1)
            userIcon.display(commentData.user.border, commentData.user.icon, commentData.user.auth?.icon)
            ipRegionTv.goneIf(!(commentData.source != null && commentData.source.region.isNotEmpty()))
            ipRegionTv.text = " · ${commentData.source?.region}"
        }
    }

    private fun initTimeTv(commentData: RatingComment) {
        binding.run {
            val context = itemView.context
            when {
                commentData.isEditContent == null -> {
                    time.setTextColor(ContextCompat.getColor(context, R.color.text_subtitleDesc))
                    time.text = if (commentData.ignore) {
                        val s = "${NewsUtils.getFormattedTime(commentData.time)}    保护期评论不计入总分"
                        SpanBuilder(s).image(s.length - 12, s.length - 11, R.drawable.ic_ignore_rating_tips)
                            .color(context, s.length - 10, s.length, R.color.text_subtitle).build()
                    } else {
                        NewsUtils.getFormattedTime(commentData.time)
                    }
                }
                commentData.isEditContent!! -> {
                    time.setTextColor(ContextCompat.getColor(context, R.color.text_F56614))
                    time.text = if (commentData.ignore) {
                        "${NewsUtils.getFormattedTime(commentData.time)} 保护期间修改评论 >"
                    } else {
                        "${NewsUtils.getFormattedTime(commentData.time)} 已修改 >"
                    }
                }
                else -> {
                    time.setTextColor(ContextCompat.getColor(context, R.color.text_F56614))
                    time.text = if (commentData.ignore) {
                        "${NewsUtils.getFormattedTime(commentData.time)} 保护期间修改评论"
                    } else {
                        "${NewsUtils.getFormattedTime(commentData.time)} 已修改"
                    }

                }
            }
        }
    }

    private fun initUserBadgeView(commentData: RatingComment) {
        binding.run {
            if (commentData.user.badge != null) {
                sdvUserBadge.visibility = View.VISIBLE
                ImageUtils.display(sdvUserBadge, commentData.user.badge?.icon)
                tvBadgeName.text = commentData.user.badge?.name
            } else {
                sdvUserBadge.visibility = View.GONE
                tvBadgeName.visibility = View.GONE
            }
        }
    }

    @SuppressLint("CheckResult")
    private fun initReplyTv(commentData: RatingComment) {
        binding.run {
            val context = itemView.context
            if (commentData.replyData != null) {
                var name = "${commentData.replyData?.user?.name}    ：${commentData.replyData?.content}"
                var contentSpan = getSpan(context, name, commentData)
                contentBadge.visibleIf(commentData.replyData!!.isService)
                contentBadge.background = DrawableView.getCornerGradientDrawable(
                    ContextCompat.getColor(context, R.color.text_4BC7FF),
                    ContextCompat.getColor(context, R.color.theme),
                    5f
                )
                replyContent.movementMethod = CustomLinkMovementMethod.getInstance()
                replyContent.highlightColor = Color.TRANSPARENT

                if (commentData.replyData!!.user.badge != null) {
                    Single.just(commentData.replyData!!.user.badge?.icon)
                        .map {
                            //Target对象保存为弱引用，gc时对象被回收导致无法回调，因此改为同步方式获取bitmap
                            //https://github.com/square/picasso/issues/352
                            ImageUtils.picasso.load(Uri.parse(it)).priority(Picasso.Priority.HIGH).get()
                        }.subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe({
                            val bitmapDrawable = BitmapDrawable(context.resources, it)
                            bitmapDrawable.setBounds(0, 0, 16F.dip2px(), 16F.dip2px())
                            contentSpan.setSpan(
                                CenterImageSpan(bitmapDrawable),
                                commentData.replyData?.user?.name!!.length + 2,
                                commentData.replyData?.user?.name!!.length + 3,
                                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                            )
                            contentSpan.setSpan(
                                object : ClickableSpan() {
                                    override fun updateDrawState(ds: TextPaint) {
                                        super.updateDrawState(ds)
                                        ds.isUnderlineText = false
                                    }

                                    override fun onClick(widget: View) {
                                        DialogUtils.showViewBadgeDialog(
                                            context,
                                            commentData.replyData!!.user.badge
                                        ) {
                                            DirectUtils.directToBadgeWall(
                                                context,
                                                commentData.replyData!!.user.id,
                                                commentData.replyData!!.user.name,
                                                commentData.replyData!!.user.icon
                                            )
                                        }
                                    }

                                },
                                commentData.replyData?.user?.name!!.length + 2,
                                commentData.replyData?.user?.name!!.length + 3,
                                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                            )
                            replyContent.movementMethod = CustomLinkMovementMethod.getInstance()
                            replyContent.text = contentSpan
                        }, {
                            it.printStackTrace()
                        })
                } else {
                    name = "${commentData.replyData?.user?.name}：${commentData.replyData?.content}"
                    contentSpan = getSpan(context, name, commentData)
                    replyContent.text = contentSpan
                }

            }
        }
    }

    private fun initVersionTv(commentData: RatingComment, game: GameEntity) {
        binding.run {
            if (game.getApk().size > 0 && game.getApk()[0].version == commentData.gameVersion) {
                version.text = "当前版本"
            } else {
                version.text = ("版本：" + commentData.gameVersion)
            }
        }
    }

    private fun initBadgeTv(commentData: RatingComment) {
        binding.run {
            val context = itemView.context
            if (commentData.me.isCommented) {
                badge.visibility = View.VISIBLE
                badge.text = "我的评价"
                badge.background = DrawableView.getCornerGradientDrawable(
                    ContextCompat.getColor(context, R.color.text_4BC7FF),
                    ContextCompat.getColor(context, R.color.theme),
                    5f
                )
            } else if (commentData.order > 0 && commentData.isWonderful) {
                badge.visibility = View.VISIBLE
                badge.text = "精彩评价"
                badge.background = DrawableView.getCornerGradientDrawable(
                    ContextCompat.getColor(context, R.color.text_FFB749),
                    ContextCompat.getColor(context, R.color.text_FF6D3C),
                    5f
                )
            } else if (commentData.isServiceComment) {
                badge.visibility = View.VISIBLE
                badge.text = "客服"
                badge.background = DrawableView.getCornerGradientDrawable(
                    ContextCompat.getColor(context, R.color.text_4BC7FF),
                    ContextCompat.getColor(context, R.color.theme),
                    5f
                )
            } else {
                badge.visibility = View.GONE
            }
        }
    }

    private fun initViewClickListener(
        commentData: RatingComment,
        viewModel: RatingViewModel,
        dataPosition: Int,
        entrance: String,
        path: String,
        deleteCallback: () -> Unit
    ) {
        binding.run {
            val game = viewModel.game
            val context = itemView.context
            val location = when {
                commentData.me.isCommented -> "我的评价"
                commentData.isServiceComment -> "小编评价"
                else -> "全部评价"
            }
            val isCommentListItem = !commentData.me.isCommented && !commentData.isServiceComment
            val tag = if (isCommentListItem) viewModel.sort else ""
            val filter = if (isCommentListItem) viewModel.filter else ""

            userIcon.setOnClickListener {
                if (path == "评论详情") {
                    NewLogUtils.logCommentTabOrCommentDetailClick(
                        "click_game_comment_detail_commet_profile_photo",
                        game.id,
                        game.gameType,
                        commentData.user.id ?: ""
                    )
                }
                if (path == "游戏详情：评分") {
                    NewLogUtils.logCommentTabOrCommentDetailClick(
                        "click_allcomment_profile_photo",
                        game.id,
                        game.gameType,
                        commentData.user.id ?: ""
                    )
                }

                NewFlatLogUtils.logGameDetailCommentTabCommentClick(
                    location,
                    tag,
                    filter,
                    "用户信息",
                    game.name ?: "",
                    game.id,
                    commentData.id
                )
                DirectUtils.directToHomeActivity(context, commentData.user.id, entrance, getKey(path))
            }
            userName.setOnClickListener {
                if (path == "评论详情") {
                    NewLogUtils.logCommentTabOrCommentDetailClick(
                        "click_game_comment_detail_commet_nickname",
                        game.id,
                        game.gameType,
                        commentData.user.id ?: ""
                    )
                }
                if (path == "游戏详情：评分") {
                    NewLogUtils.logCommentTabOrCommentDetailClick(
                        "click_allcomment_nickname",
                        game.id,
                        game.gameType,
                        commentData.user.id ?: ""
                    )
                }

                NewFlatLogUtils.logGameDetailCommentTabCommentClick(
                    location,
                    tag,
                    filter,
                    "用户信息",
                    game.name ?: "",
                    game.id,
                    commentData.id
                )
                DirectUtils.directToHomeActivity(context, commentData.user.id, entrance, getKey(path))
            }

            sdvUserBadge.setOnClickListener {
                DialogUtils.showViewBadgeDialog(context, commentData.user.badge, object : ConfirmListener {
                    override fun onConfirm() {
                        DirectUtils.directToBadgeWall(
                            context,
                            commentData.user.id,
                            commentData.user.name,
                            commentData.user.icon
                        )
                    }
                })
            }
            tvBadgeName.setOnClickListener { sdvUserBadge.performClick() }

            more.setOnClickListener {
                NewFlatLogUtils.logGameDetailCommentTabCommentClick(
                    location,
                    tag,
                    filter,
                    "展开右上角",
                    game.name ?: "",
                    game.id,
                    commentData.id
                )
                showMorePopWindow(it, commentData.user.id == UserManager.getInstance().userId) { text ->
                    initMorePopWindowClickCallback(
                        text,
                        commentData,
                        viewModel,
                        dataPosition,
                        entrance,
                        path,
                        deleteCallback
                    )
                }
            }

            time.setOnClickListener {
                initTimeTvClickCallback(commentData, viewModel.game)
            }
        }
    }

    private fun initMorePopWindowClickCallback(
        text: String,
        commentData: RatingComment,
        viewModel: RatingViewModel,
        dataPosition: Int,
        entrance: String,
        path: String,
        deleteCallback: () -> Unit
    ) {
        val game = viewModel.game
        val context = itemView.context
        val location = when {
            commentData.me.isCommented -> "我的评价"
            commentData.isServiceComment -> "小编评价"
            else -> "全部评价"
        }
        val isCommentListItem = !commentData.me.isCommented && !commentData.isServiceComment
        val tag = if (isCommentListItem) viewModel.sort else ""
        val filter = if (isCommentListItem) viewModel.filter else ""
        when (text) {
            "复制" -> {
                NewLogUtils.logCommentTabOrCommentDetailClick(
                    "click_allcomment_copy",
                    game.id,
                    game.gameType
                )
                NewFlatLogUtils.logGameDetailCommentTabCommentClick(
                    location,
                    tag,
                    filter,
                    "右上角-复制",
                    game.name ?: "",
                    game.id,
                    commentData.id
                )
                commentData.content.replace(RatingEditActivity.LABEL_REPLACE_REGEX.toRegex(), "")
                    .copyTextAndToast()
            }
            "修改" -> {
                NewFlatLogUtils.logGameDetailCommentTabCommentClick(
                    location,
                    tag,
                    filter,
                    "右上角-修改",
                    game.name ?: "",
                    game.id,
                    commentData.id
                )
                val intent = RatingEditActivity.getPatchIntent(context, game, commentData)
                SyncDataBetweenPageHelper.startActivityForResult(
                    context,
                    intent,
                    RatingFragment.RATING_PATCH_REQUEST,
                    dataPosition
                )
            }
            "投诉" -> {
                NewLogUtils.logCommentTabOrCommentDetailClick(
                    "click_allcomment_report",
                    game.id,
                    game.gameType
                )
                NewFlatLogUtils.logGameDetailCommentTabCommentClick(
                    location,
                    tag,
                    filter,
                    "右上角-投诉",
                    game.name ?: "",
                    game.id,
                    commentData.id
                )
                context.ifLogin(BaseActivity.mergeEntranceAndPath(entrance, path)) {
                    DialogUtils.showReportReasonDialog(
                        context,
                        Constants.REPORT_LIST.toList() as ArrayList<String>
                    ) { reason, desc ->
                        SimpleRequestHelper.reportGameComment(
                            game.id,
                            commentData.id,
                            if (reason != "其他原因") reason else desc
                        )
                    }
                }
            }
            "删除" -> {
                NewFlatLogUtils.logGameDetailCommentTabCommentClick(
                    location,
                    tag,
                    filter,
                    "右上角-删除",
                    game.name ?: "",
                    game.id,
                    commentData.id
                )
                DialogHelper.showDeleteGameCommentDialog(
                    context,
                    R.string.delete_game_comment.toResString()
                ) {
                    SimpleRequestHelper.deleteGameComment(game.id, commentData.id) {
                        deleteCallback.invoke()
                    }
                }
            }
        }
    }

    private fun initTimeTvClickCallback(commentData: RatingComment, game: GameEntity) {
        val context = itemView.context
        if (commentData.isEditContent == null && commentData.ignore) {
            DialogUtils.showStopServerExplanationDialog(
                context,
                game.commentDescription.ifEmpty { context.getString(R.string.rating_protection) },
                game.name ?: ""
            )
        } else if (commentData.isEditContent == true) {
            val intent = CommentLogsActivity.getIntent(context, game.id, commentData.id)
            context.startActivity(intent)
        }
    }

    private fun initAuditTv(commentData: RatingComment, game: GameEntity, dataPosition: Int) {
        binding.run {
            val context = itemView.context
            if (!commentData.active) {
                if (commentData.audit) {
                    audit.text = "您修改后的评价已提交，小助手将尽快审核~"
                } else {
                    val auditText = SpannableStringBuilder("您的评价因违反了《光环助手评论规则》暂时被隐藏~ 去修改")
                    auditText.setSpan(object : ClickableSpan() {
                        override fun updateDrawState(ds: TextPaint) {
                            super.updateDrawState(ds)
                            ds.color = R.color.theme_font.toColor(context)
                        }

                        override fun onClick(widget: View) {
                            context.startActivity(
                                WebActivity.getWebIntent(
                                    context,
                                    context.getString(R.string.comment_rules_title),
                                    context.getString(R.string.comment_rules_url)
                                )
                            )
                        }
                    }, 8, 18, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)

                    auditText.setSpan(object : ClickableSpan() {
                        override fun updateDrawState(ds: TextPaint) {
                            super.updateDrawState(ds)
                            ds.color = R.color.theme_font.toColor(context)
                        }

                        override fun onClick(widget: View) {
                            val intent = RatingEditActivity.getPatchIntent(context, game, commentData)
                            SyncDataBetweenPageHelper.startActivityForResult(
                                context,
                                intent,
                                RatingFragment.RATING_PATCH_REQUEST,
                                dataPosition
                            )
                        }
                    }, auditText.length - 3, auditText.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
                    audit.text = auditText
                    audit.movementMethod = LinkMovementMethod()
                }

                comment.post {
                    comment.visibility = View.INVISIBLE
                    vote.visibility = View.INVISIBLE
                }
            }
        }
    }

    private fun getKey(path: String): String {
        return when (path) {
            "游戏详情：介绍" -> "游戏详情-玩家评论"
            "游戏详情：评分" -> "游戏详情-评论列表"
            "评论详情" -> "游戏评论详情"
            "折叠评论" -> "折叠评论"
            else -> ""
        }
    }

    private fun getSpan(context: Context, name: String, commentData: RatingComment): SpannableStringBuilder {
        val spanned = SpanBuilder(name)
            .color(context, 0, commentData.replyData?.user?.name!!.length, R.color.text_title)
            .bold(0, commentData.replyData?.user?.name!!.length)
            .size(0, commentData.replyData?.user?.name!!.length, 13)
            .build()

        val contentSpan = TextHelper.getHighlightedSpannableStringThatIsWrappedInsideWrapper(context, spanned)
        if (commentData.replyData!!.isService) {
            contentSpan.setSpan(LeadingMarginSpan.Standard(34F.dip2px(), 0), 0, contentSpan.length, 0)
        } else {
            contentSpan.setSpan(LeadingMarginSpan.Standard(0, 0), 0, contentSpan.length, 0)
        }
        return contentSpan
    }

    private fun showMorePopWindow(v: View, isMyRating: Boolean, clickListener: (String) -> Unit) {
        val contentList = if (isMyRating) arrayListOf("复制", "修改", "删除")
        else arrayListOf("复制", "投诉")

        val inflater = LayoutInflater.from(v.context)
        val layout = inflater.inflate(R.layout.layout_popup_container, null)
        val popupWindow = PopupWindow(
            layout,
            LinearLayout.LayoutParams.WRAP_CONTENT,
            LinearLayout.LayoutParams.WRAP_CONTENT
        )
        popupWindow.apply {
            setBackgroundDrawable(ColorDrawable(0))
            isTouchable = true
            isFocusable = true
            isOutsideTouchable = true
        }

        val container = layout.findViewById<LinearLayout>(R.id.container)
        for (text in contentList) {
            val item = inflater.inflate(R.layout.layout_popup_option_item, container, false)
            container.addView(item)

            val hitText = item.findViewById<TextView>(R.id.hint_text)
            hitText.text = text

            item.setOnClickListener {
                clickListener.invoke(text)
                popupWindow.dismiss()
            }
        }

        popupWindow.showAutoOrientation(v)
    }
}