package com.gh.gamecenter.gamedetail.desc

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Build
import android.os.Handler
import android.os.HandlerThread
import android.text.TextUtils
import android.util.SparseBooleanArray
import android.util.SparseIntArray
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.text.HtmlCompat
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.DefaultUrlHandler
import com.gh.common.databind.BindingAdapters
import com.gh.common.exposure.ExposureManager
import com.gh.common.util.*
import com.gh.common.util.LogUtils
import com.gh.common.util.NewFlatLogUtils
import com.gh.common.util.NewLogUtils
import com.gh.gamecenter.GameNewsActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.common.callback.OnListClickListener
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.entity.CommunityEntity
import com.gh.gamecenter.common.entity.LinkEntity
import com.gh.gamecenter.common.entity.SuggestType
import com.gh.gamecenter.common.eventbus.EBReuse
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.view.divider.HorizontalDividerItemDecoration
import com.gh.gamecenter.common.view.divider.VerticalDividerItemDecoration
import com.gh.gamecenter.common.viewholder.FooterViewHolder
import com.gh.gamecenter.core.utils.*
import com.gh.gamecenter.databinding.*
import com.gh.gamecenter.entity.SubjectEntity
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.exposure.ExposureSource
import com.gh.gamecenter.game.horizontal.GameHorizontalAdapter
import com.gh.gamecenter.game.horizontal.GameHorizontalListType
import com.gh.gamecenter.game.vertical.SpanCountPagerSnapHelper
import com.gh.gamecenter.gamedetail.GameDetailFragment
import com.gh.gamecenter.gamedetail.entity.CustomColumn
import com.gh.gamecenter.gamedetail.entity.DetailEntity
import com.gh.gamecenter.gamedetail.entity.NewGameDetailEntity
import com.gh.gamecenter.gamedetail.fuli.kaifu.ServersCalendarActivity
import com.gh.gamecenter.gamedetail.history.HistoryApkListActivity
import com.gh.gamecenter.help.HelpAndFeedbackBridge
import com.lightgame.adapter.BaseRecyclerAdapter
import org.greenrobot.eventbus.EventBus

class DescAdapter(
    context: Context,
    private val mEntrance: String,
    private val mViewModel: DescViewModel,
    private val mNewGameDetailEntity: NewGameDetailEntity?
) : BaseRecyclerAdapter<RecyclerView.ViewHolder>(context) {

    var descItemList = arrayListOf<DetailEntity>()

    private val mGameName = mViewModel.game?.name ?: "unknown"
    private val mExpandableTextViewMaxLinesSparseIntArray = SparseIntArray()
    private val mExpandableTextExpandStatusSparseBooleanArray = SparseBooleanArray()
    private val mCustomColumnTagsExpandStatusSparseBooleanArray = SparseBooleanArray()

    private val mDefaultHorizontalPadding by lazy { R.dimen.game_detail_item_horizontal_padding.toPx() }
    private var mHandlerThread: HandlerThread = HandlerThread("GH_EXPOSURE_LOG_THREAD")
    private var mHandler: Handler

    init {
        mHandlerThread.start()
        mHandler = Handler(mHandlerThread.looper)
    }

    fun stopHandlerThread() {
        if (mHandlerThread.isAlive) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
                mHandlerThread.quit()
            } else {
                mHandler.removeCallbacksAndMessages(null)
            }
        }
    }

    @SuppressLint("NotifyDataSetChanged")
    fun updateDescItemList(descItemList: ArrayList<DetailEntity>) {
        this.descItemList = descItemList
        notifyDataSetChanged()
    }

    override fun getItemViewType(position: Int): Int {
        val itemData = descItemList[position]
        return when (itemData.type) {
            DetailEntity.Type.IMAGE_GALLERY.value -> IMAGE_GALLERY
            DetailEntity.Type.VIDEOS.value -> VIDEOS
            DetailEntity.Type.COMMENTS.value -> COMMENTS
            DetailEntity.Type.GAME_INFO.value -> GAME_DETAIL
            DetailEntity.Type.UPDATE_CONTENT.value -> UPDATE_CONTENT
            DetailEntity.Type.LATEST_SERVER.value -> LATEST_SERVICE
            DetailEntity.Type.RELATED_VERSION.value -> RELATED_VERSION
            DetailEntity.Type.IMAGE.value -> IMAGE
            DetailEntity.Type.LIBAO.value -> LIBAO
            DetailEntity.Type.INFO_GUIDE.value -> INFO_RAIDERS
            DetailEntity.Type.RECOMMENDED_GAMES.value -> RECOMMENDED_GAMES
            DetailEntity.Type.CUSTOM_COLUMN.value -> CUSTOM_COLUMN
            DetailEntity.Type.NOTICE.value -> NOTICE
            DetailEntity.Type.RECOMMEND_GAME_LIST.value -> RECOMMEND_GAME_LIST
            DetailEntity.Type.COLUMN_RECOMMEND.value -> COLUMN_RECOMMEND
            else -> FOOTER
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        return when (viewType) {
            COMMENTS -> GameDetailCommentsViewHolder(parent.toBinding(), mHandler)
            CUSTOM_COLUMN -> GameDetailCustomColumnViewHolder(parent.toBinding(), mHandler)
            IMAGE -> GameDetailRecommendImageViewHolder(parent.toBinding(), mHandler)
            VIDEOS -> GameVideoGalleryViewHolder(parent.toBinding(), mHandler)
            IMAGE_GALLERY -> GameImageGalleryViewHolder(parent.toBinding(), mHandler)
            UPDATE_CONTENT -> GameUpdateContentViewHolder(parent.toBinding(), mHandler)
            LATEST_SERVICE -> GameLatestServiceViewHolder(parent.toBinding(), mHandler)
            INFO_RAIDERS -> GameRaidersGalleryViewHolder(parent.toBinding(), mHandler)
            LIBAO -> GameLibaoGalleryViewHolder(parent.toBinding(), mHandler)
            RELATED_VERSION -> GameDetailRelatedVersionViewHolder(parent.toBinding(), mHandler)
            GAME_DETAIL -> GameDetailInfoViewHolder(parent.toBinding(), mHandler)
            RECOMMENDED_GAMES -> GamesRecommendedGalleryViewHolder(parent.toBinding(), mHandler)
            NOTICE -> GameDetailNoticeViewHolder(parent.toBinding(), mHandler)
            RECOMMEND_GAME_LIST -> GameCollectionViewHolder(parent.toBinding(), mHandler)
            COLUMN_RECOMMEND -> ColumnRecommendViewHolder(parent.toBinding(), mHandler)
            else -> {
                val view = mLayoutInflater.inflate(R.layout.refresh_footerview, parent, false)
                FooterViewHolder(view)
            }
        }
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        val itemData = descItemList[position]
        when (holder) {
            is GameDetailNoticeViewHolder -> bindNoticeViewHolder(holder, itemData)
            is GameDetailCustomColumnViewHolder -> bindCustomColumnViewHolder(holder, itemData)
            is GamesRecommendedGalleryViewHolder -> bindGamesRecommendedGalleryViewHolder(holder, itemData)
            is GameDetailRecommendImageViewHolder -> bindImageViewHolder(holder, itemData)
            is GameDetailCommentsViewHolder -> bindCommentsViewHolder(holder, itemData)
            is GameDetailRelatedVersionViewHolder -> bindRelatedVersion(holder, itemData)
            is GameVideoGalleryViewHolder -> bindVideosViewHolder(holder, itemData, itemData.videoCount)
            is GameImageGalleryViewHolder -> bindImageGalleryViewHolder(holder, itemData)
            is GameUpdateContentViewHolder -> bindUpdateContentViewHolder(holder, itemData)
            is GameLatestServiceViewHolder -> bindLatestServiceViewHolder(holder, itemData)
            is GameDetailInfoViewHolder -> bindGameDetailInfoViewHolder(holder, itemData)
            is GameLibaoGalleryViewHolder -> bindLibaoViewHolder(holder, itemData)
            is GameRaidersGalleryViewHolder -> bindRaidersViewHolder(holder, itemData)
            is GameCollectionViewHolder -> bindGameCollectionViewHolder(holder, itemData)
            is ColumnRecommendViewHolder -> bindColumnRecommendViewHolder(holder, itemData)
            is FooterViewHolder -> {
                holder.loading.visibility = View.GONE
                holder.hint.setText(R.string.game_suggestion_hint)

                holder.itemView.setOnClickListener {
                    HelpAndFeedbackBridge.startSuggestionActivity(mContext, SuggestType.gameQuestion, "game", mGameName)
                    MtaHelper.onEvent(MTA_KEY_GAME_NEW, "此游戏有问题_点击反馈", mGameName)
                }
            }
        }
    }

    override fun getItemCount() = descItemList.size

    // 绑定公告
    private fun bindNoticeViewHolder(viewHolder: GameDetailNoticeViewHolder, itemData: DetailEntity) {
        val noticeList = itemData.noticeList!!
        val list = arrayListOf<String>()

        for (newsEntity in noticeList) {
            list.add(newsEntity.title)
        }

        viewHolder.binding.run {
            val paddingTop = if (itemData.shouldBoundWithPreviousItem) 0 else itemData.paddingTop
            val paddingBottom = if (itemData.shouldBoundWithNextItem) 0 else itemData.paddingBottom
            containerWrapper.setPadding(0, paddingTop, 0, paddingBottom)

            divider.goneIf(!itemData.shouldBoundWithPreviousItem)

            updateBoundableContainerBackground(
                container,
                itemData.shouldBoundWithPreviousItem,
                itemData.shouldBoundWithNextItem
            )

            gamedetailItemNotice.startWithList(list)
            gamedetailItemNotice.enableSingleLineText()
            gamedetailItemNotice.setOnClickListener {
                val index = gamedetailItemNotice.displayedChild
                DirectUtils.directToArticle(
                    mContext,
                    noticeList[index].id,
                    StringUtils.buildString(mEntrance, "游戏详情[", mGameName, "]:公告")
                )
                MtaHelper.onEvent(MTA_KEY_GAME_NEW, "详情_公告", "${mGameName}+${gamedetailItemNotice.notices[index]}")
            }
        }
    }

    // 绑定自定义栏目
    private fun bindCustomColumnViewHolder(viewHolder: GameDetailCustomColumnViewHolder, itemData: DetailEntity) {
        val customColumn = itemData.customColumn!!

        viewHolder.binding.run {
            titleTv.setTextColor(R.color.text_title.toColor(mContext))
            titleHintTv.setTextColor(R.color.theme_font.toColor(mContext))

            val paddingTop = if (itemData.shouldBoundWithPreviousItem) 0 else itemData.paddingTop
            val paddingBottom = if (itemData.shouldBoundWithNextItem) 0 else itemData.paddingBottom
            containerWrapper.setPadding(mDefaultHorizontalPadding, paddingTop, mDefaultHorizontalPadding, paddingBottom)

            divider.goneIf(!itemData.shouldBoundWithPreviousItem)

            updateCommonCustomView(
                customColumn = customColumn,
                position = viewHolder.bindingAdapterPosition,
                binding = this
            )

            updateBoundableContainerBackground(
                container,
                itemData.shouldBoundWithPreviousItem,
                itemData.shouldBoundWithNextItem
            )
        }
    }

    // 绑定大家都在玩
    private fun bindGamesRecommendedGalleryViewHolder(
        viewHolder: GamesRecommendedGalleryViewHolder,
        itemData: DetailEntity
    ) {
        val subjectEntity = itemData.recommendedGames

        viewHolder.binding.run {
            titleTv.setTextColor(R.color.text_title.toColor(mContext))
            moreTv.setTextColor(R.color.text_subtitleDesc.toColor(mContext))
            moreTv.setDrawableEnd(R.drawable.ic_right_arrow_darker)

            galleryRv.isNestedScrollingEnabled = false

            galleryRv.layoutParams =
                (galleryRv.layoutParams as ViewGroup.MarginLayoutParams).apply {
                    topMargin = 6F.dip2px()
                    leftMargin = 0
                    rightMargin = 0
                }

            if (subjectEntity != null) {
                var subjectAdapter = galleryRv.adapter
                if (subjectAdapter == null) {
                    val exposureEventList = arrayListOf<ExposureEvent>()
                    val itemDecoration = VerticalDividerItemDecoration.Builder(mContext)
                        .size(8F.dip2px())
                        .color(R.color.transparent.toColor(mContext))
                        .build()

                    for ((index, game) in subjectEntity.data!!.withIndex()) {
                        game.sequence = index
                        val event = ExposureEvent.createEvent(
                            gameEntity = game,
                            source = listOf(
                                ExposureSource("游戏详情", mGameName),
                                ExposureSource("大家都在玩", game.recommendType)
                            )
                        )
                        exposureEventList.add(event)
                        ExposureManager.log(event)
                    }

                    galleryRv.layoutManager = LinearLayoutManager(mContext, RecyclerView.HORIZONTAL, false)
                    subjectAdapter =
                        GameHorizontalAdapter(mContext, subjectEntity, GameHorizontalListType.GameDetailHorizontalType)
                    subjectAdapter.gameName = mGameName
                    subjectAdapter.gameId = mViewModel.gameId ?: ""
                    subjectAdapter.entrance = mEntrance
                    subjectAdapter.path = "大家都在玩"
                    subjectAdapter.exposureEventList = exposureEventList
                    (galleryRv.itemAnimator as DefaultItemAnimator).supportsChangeAnimations = false
                    galleryRv.addItemDecoration(itemDecoration)
                    galleryRv.adapter = subjectAdapter
                } else {
                    (subjectAdapter as GameHorizontalAdapter).checkResetData(subjectEntity)
                }
            }
            titleTv.text = "大家都在玩"
            moreTv.visibility = View.GONE
        }
    }

    // 绑定评论
    @SuppressLint("NotifyDataSetChanged")
    private fun bindCommentsViewHolder(viewHolder: GameDetailCommentsViewHolder, itemData: DetailEntity) {
        val comments = itemData.comment!!
        val commentsAdapter = viewHolder.binding.recyclerview.adapter as DescCommentsAdapter?
            ?: DescCommentsAdapter(mContext, mViewModel, mEntrance, mGameName)

        val itemDecoration = HorizontalDividerItemDecoration.Builder(mContext)
            .size(0.5F.dip2px())
            .margin(16F.dip2px())
            .color(R.color.divider.toColor(mContext))
            .build()

        viewHolder.binding.run {
            titleTv.setTextColor(R.color.text_title.toColor(mContext))
            tvAll.setTextColor(R.color.text_subtitleDesc.toColor(mContext))
            containerWrapper.setPadding(0, itemData.paddingTop, 0, itemData.paddingBottom)

            recyclerview.background = R.drawable.background_shape_white_radius_5.toDrawable(mContext)
            recyclerview.isNestedScrollingEnabled = false
            recyclerview.adapter = commentsAdapter
            recyclerview.layoutManager = LinearLayoutManager(mContext)
            recyclerview.addItemDecoration(itemDecoration)
            tvAll.setOnClickListener {
                EventBus.getDefault().post(EBReuse(GameDetailFragment.SKIP_RATING))
                MtaHelper.onEvent(MTA_KEY_GAME_NEW, "玩家评论_点击全部", mGameName)
                MtaHelper.onEvent(MTA_KEY_GAME_NEW, "玩家评论_更多按钮", mGameName)
                NewLogUtils.logGameDetailCommentClick(mViewModel.game?.name ?: "", mViewModel.game?.id ?: "", "更多")
            }

        }

        commentsAdapter.comments = comments
        commentsAdapter.notifyDataSetChanged()
    }

    // 绑定其他相关版本
    private fun bindRelatedVersion(viewHolder: GameDetailRelatedVersionViewHolder, itemData: DetailEntity) {
        val relatedVersion = itemData.relatedVersion!!
        itemData.paddingBottom = 16F.dip2px()

        viewHolder.binding.run {
            titleTv.setTextColor(R.color.text_title.toColor(mContext))
            moreTv.setTextColor(R.color.text_subtitleDesc.toColor(mContext))
            moreTv.setDrawableEnd(R.drawable.ic_right_arrow_darker)
            containerWrapper.setPadding(0, itemData.paddingTop, 0, itemData.paddingBottom)
            galleryRv.isNestedScrollingEnabled = false
            if (galleryRv.adapter == null) {
                val relatedVersionAdapter = GameRelatedVersionAdapter(mContext, mGameName, relatedVersion, mEntrance)
                galleryRv.run {
                    background = R.drawable.background_shape_white_radius_5.toDrawable(mContext)
                    setPadding(0F.dip2px(), 8F.dip2px(), 0F.dip2px(), 8F.dip2px())
                    if (relatedVersion.size > 3) {
                        layoutManager = GridLayoutManager(mContext, 3, RecyclerView.HORIZONTAL, false)
                        clearOnScrollListeners()
                        (itemAnimator as DefaultItemAnimator).supportsChangeAnimations = false
                        onFlingListener = null
                        val snapHelper = SpanCountPagerSnapHelper(3, true)
                        snapHelper.attachToRecyclerView(this)
                    } else {
                        layoutManager = LinearLayoutManager(mContext)
                    }
                    adapter = relatedVersionAdapter
                }

                // 曝光相关
                for ((index, simpleGame) in relatedVersion.withIndex()) {
                    val game = simpleGame.game
                    game?.sequence = index
                    val event = ExposureEvent.createEvent(
                        gameEntity = game,
                        source = listOf(
                            ExposureSource("游戏详情", mGameName),
                            ExposureSource("相关游戏")
                        )
                    )
                    relatedVersionAdapter.exposureEventList.add(event)
                    ExposureManager.log(event)
                }
            } else {
                galleryRv.background = R.drawable.background_shape_white_radius_5.toDrawable(mContext)
                galleryRv.adapter?.run { notifyItemRangeChanged(0, itemCount) }
            }
            titleTv.text = "相关游戏"
            moreTv.visibility = View.GONE
        }
    }

    // 绑定图片推荐
    private fun bindImageViewHolder(viewHolder: GameDetailRecommendImageViewHolder, itemData: DetailEntity) {
        val recommendedImage = itemData.imageRecommend!!

        viewHolder.binding.run {
            titleTv.setTextColor(R.color.text_title.toColor(mContext))
            containerWrapper.setPadding(mDefaultHorizontalPadding, 0, mDefaultHorizontalPadding, itemData.paddingBottom)
            containerWrapper.setBackgroundColor(R.color.background.toColor(mContext))
            titleTv.setPadding(0, itemData.paddingTop, 0, 11F.dip2px())
            titleTv.text = recommendedImage.title
            imageIv.display(recommendedImage.image)

            root.setOnClickListener {
                MtaHelper.onEvent(MTA_KEY_GAME_NEW, "图片推荐", mGameName + "+${recommendedImage.title}")
                if (!TextUtils.isEmpty(recommendedImage.communityId)) {
                    recommendedImage.community = CommunityEntity(recommendedImage.communityId!!, "")
                }
                DirectUtils.directToLinkPage(
                    context = mContext,
                    linkEntity = recommendedImage,
                    entrance = mEntrance,
                    path = "游戏详情"
                )
            }
        }
    }

    // 绑定视频
    @SuppressLint("SetTextI18n")
    private fun bindVideosViewHolder(viewHolder: GameVideoGalleryViewHolder, itemData: DetailEntity, videoCount: Int) {
        val videos = itemData.video

        viewHolder.binding.run {
            titleTv.setTextColor(R.color.text_title.toColor(mContext))
            moreTv.setTextColor(R.color.text_subtitleDesc.toColor(mContext))
            moreTv.setDrawableEnd(R.drawable.ic_right_arrow_darker)
            containerWrapper.setPadding(0, itemData.paddingTop, 0, itemData.paddingBottom)

            galleryRv.isNestedScrollingEnabled = false
            if (galleryRv.adapter == null) {
                galleryRv.layoutParams = (galleryRv.layoutParams as ViewGroup.MarginLayoutParams)
                    .apply {
                        leftMargin = 0
                        rightMargin = 0
                    }
                galleryRv.layoutManager = LinearLayoutManager(mContext, RecyclerView.HORIZONTAL, false)
                galleryRv.adapter = GameGalleryAdapter(
                    mContext,
                    videos,
                    null,
                    mViewModel.game!!,
                    StringUtils.buildString(mEntrance, "+(游戏详情[", mGameName, "]:视频)")
                )
            } else {
                galleryRv.adapter?.run { notifyItemRangeChanged(0, itemCount) }
            }
            galleryRv.addOnScrollListener(object : RecyclerView.OnScrollListener() {
                override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
                    super.onScrollStateChanged(recyclerView, newState)
                    if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                        MtaHelper.onEvent(MTA_KEY_GAME_NEW, "视频_滑动", mGameName)
                    }
                }
            })
            titleTv.text = "视频(${videoCount})"
            moreTv.visibleIf(videoCount >= 3)
            moreTv.setOnClickListener {
                MtaHelper.onEvent(MTA_KEY_GAME_NEW, "视频_更多", mGameName)
                DirectUtils.directToGameVideo(mContext, mViewModel.gameId ?: "", mEntrance, "游戏详情")
            }
        }
    }

    // 绑定图片
    private fun bindImageGalleryViewHolder(viewHolder: GameImageGalleryViewHolder, itemData: DetailEntity) {
        val gallery = itemData.gallery

        viewHolder.binding.run {
            titleTv.setTextColor(R.color.text_title.toColor(mContext))
            moreTv.setTextColor(R.color.text_subtitleDesc.toColor(mContext))
            moreTv.setDrawableEnd(R.drawable.ic_right_arrow_darker)
            galleryRv.isNestedScrollingEnabled = false
            containerWrapper.setPadding(0, itemData.paddingTop, 0, itemData.paddingBottom)

            if (galleryRv.adapter == null) {
                galleryRv.layoutParams = (galleryRv.layoutParams as ViewGroup.MarginLayoutParams)
                    .apply {
                        leftMargin = 0
                        rightMargin = 0
                    }
                galleryRv.layoutManager = LinearLayoutManager(mContext, RecyclerView.HORIZONTAL, false)
                galleryRv.adapter = GameGalleryAdapter(
                    mContext,
                    null,
                    gallery,
                    mViewModel.game!!,
                    StringUtils.buildString(mEntrance, "+(游戏详情[", mGameName, "]:图片)")
                )
            }
            titleTv.text = "图片"
            moreTv.visibility = View.GONE
        }
    }

    // 绑定更新内容
    private fun bindUpdateContentViewHolder(holder: GameUpdateContentViewHolder, itemData: DetailEntity) {
        val updateContent = itemData.update!!

        holder.binding.run {
            containerWrapper.setPadding(
                mDefaultHorizontalPadding,
                itemData.paddingTop,
                mDefaultHorizontalPadding,
                itemData.paddingBottom
            )
            containerWrapper.setBackgroundColor(R.color.background.toColor(mContext))

            titleTv.setTextColor(R.color.text_title.toColor(mContext))
            contentTv.text = updateContent.updateDes
            contentTv.setTextColor(R.color.text_subtitle.toColor(mContext))
            val maxDesLines =
                if (mExpandableTextExpandStatusSparseBooleanArray.get(holder.bindingAdapterPosition)) Int.MAX_VALUE else 4
            contentTv.setExpandMaxLines(maxDesLines)
            contentTv.setIsExpanded(Int.MAX_VALUE == maxDesLines)
            contentTv.setExpandCallback {
                mExpandableTextExpandStatusSparseBooleanArray.put(holder.bindingAdapterPosition, true)
                MtaHelper.onEvent(MTA_KEY_GAME_NEW, "展开更新内容", mGameName)
                NewLogUtils.logGameDetailUpdatedClick(mViewModel.game?.name ?: "", mViewModel.game?.id ?: "", "全部")
            }
            historyVersionTv.setTextColor(R.color.theme_font.toColor(mContext))
            historyVersionTv.setOnClickListener {
                MtaHelper.onEvent("历史版本", "进入", mGameName)
                MtaHelper.onEvent(MTA_KEY_GAME_NEW, "更新内容_历史版本", mGameName)
                val intent = HistoryApkListActivity.getIntent(
                    mContext,
                    mViewModel.game ?: GameEntity(),
                    mEntrance,
                    "游戏详情[${mGameName}]:更新内容"
                )
                mContext.startActivity(intent)
                NewLogUtils.logGameDetailUpdatedClick(
                    mViewModel.game?.name ?: "",
                    mViewModel.game?.id ?: "",
                    "历史版本"
                )
            }
            historyVersionTv.visibility =
                if (updateContent.historyApkStatus == "on" && updateContent.historyApkCount >= 1) View.VISIBLE else View.GONE
        }
    }

    // 绑定最近开服
    private fun bindLatestServiceViewHolder(viewHolder: GameLatestServiceViewHolder, itemData: DetailEntity) {
        val server = itemData.server!!

        viewHolder.binding.run {
            titleTv.setTextColor(R.color.text_title.toColor(mContext))
            moreTv.setTextColor(R.color.text_subtitleDesc.toColor(mContext))
            tipsTv.setTextColor(R.color.text_subtitleDesc.toColor(mContext))
            moreTv.setDrawableEnd(R.drawable.ic_right_arrow_darker)
            tipsTv.setDrawableStart(R.drawable.servers_calendar_hint)
            serviceRv.isNestedScrollingEnabled = false
            containerWrapper.setPadding(
                mDefaultHorizontalPadding,
                itemData.paddingTop,
                mDefaultHorizontalPadding,
                itemData.paddingBottom
            )
            containerWrapper.setBackgroundColor(R.color.background.toColor(mContext))
            if (!server.calendar.isNullOrEmpty()) {
                serviceRv.visibility = View.VISIBLE
                if (serviceRv.adapter == null) {
                    val serviceAdapter = GameLatestServiceAdapter(mContext, mViewModel.game, server.calendar)
                    val itemDecoration = HorizontalDividerItemDecoration.Builder(mContext)
                        .size(12F.dip2px())
                        .color(R.color.transparent.toColor(mContext))
                        .build()
                    serviceRv.layoutManager = LinearLayoutManager(mContext)
                    serviceRv.adapter = serviceAdapter
                    serviceRv.addItemDecoration(itemDecoration)
                }
            } else {
                // 当天没有、未来没有、历史30天之前有
                moreTv.visibility = View.GONE
                tipsTv.visibleIf(server.total > 0)
            }

            moreTv.setOnClickListener {
                MtaHelper.onEvent("开服日历表", "进入", mGameName)
                MtaHelper.onEvent(MTA_KEY_GAME_NEW, "最新开服_更多", mGameName)
                val intent = ServersCalendarActivity.getIntent(
                    mContext,
                    mViewModel.game!!,
                    server,
                    mNewGameDetailEntity?.me
                )
                mContext.startActivity(intent)
                mViewModel.game?.let {
                    NewLogUtils.logGameDetailOpenListClick(it.name ?: "", it.id, "更多")
                }
            }
            if (server.showDes && server.des.isNotEmpty()) {
                tipsIv.visibility = View.VISIBLE
                tipsIv.setOnClickListener {
                    MtaHelper.onEvent(MTA_KEY_GAME_NEW, "最新开服_开服说明", mGameName)
                    DialogUtils.showKaifuRemindDialog(mContext, server.des, mGameName)
                }
            }
        }
    }

    // 绑定攻略文章
    private fun bindRaidersViewHolder(viewHolder: GameRaidersGalleryViewHolder, itemData: DetailEntity) {
        val article = itemData.article!!

        viewHolder.binding.run {
            titleTv.setTextColor(R.color.text_title.toColor(mContext))
            moreTv.setTextColor(R.color.text_subtitleDesc.toColor(mContext))
            moreTv.setDrawableEnd(R.drawable.ic_right_arrow_darker)
            galleryRv.isNestedScrollingEnabled = false
            containerWrapper.setPadding(0, itemData.paddingTop, 0, itemData.paddingBottom)

            if (galleryRv.adapter == null) {
                galleryRv.layoutParams = (galleryRv.layoutParams as ConstraintLayout.LayoutParams)
                    .apply {
                        leftMargin = 0
                        rightMargin = 0
                    }
                galleryRv.layoutManager =
                    LinearLayoutManager(mContext, RecyclerView.HORIZONTAL, false)
                galleryRv.adapter =
                    GameRaidersAdapter(mContext, article, mEntrance, mViewModel.game)
            } else {
                galleryRv.adapter?.run { notifyItemRangeChanged(0, itemCount) }
            }
            titleTv.text = "新手攻略"
            if (mViewModel.game?.zone?.status != "off"
                && mViewModel.game?.zone?.style == "link"
            ) {
                moreTv.text = "进入攻略专区"
                moreTv.visibility = View.VISIBLE
            } else {
                moreTv.text = "更多"
                moreTv.goneIf((article.size) < 3)
            }

            moreTv.setOnClickListener {
                MtaHelper.onEvent(MTA_KEY_GAME_NEW, "新手攻略卡片_更多", mGameName)

                if (moreTv.text == "更多") {
                    val intent = GameNewsActivity.getIntent(
                        mContext,
                        mViewModel.game?.name,
                        mViewModel.game?.id,
                        mEntrance + "+(游戏详情[" + mViewModel.game?.name + "]:新手攻略-全部)"
                    )
                    mContext.startActivity(intent)
                } else {
                    EventBus.getDefault().post(EBReuse(GameDetailFragment.SKIP_FULI))
                }
                LogUtils.logGameDetailStrategyButtonEvent(mViewModel.gameId, mGameName, moreTv.text.toString())
            }
        }

    }

    //绑定礼包
    private fun bindLibaoViewHolder(viewHolder: GameLibaoGalleryViewHolder, itemData: DetailEntity) {
        val libao = itemData.libao!!

        viewHolder.binding.run {
            titleTv.setTextColor(R.color.text_title.toColor(mContext))
            moreTv.setTextColor(R.color.text_subtitleDesc.toColor(mContext))
            moreTv.setDrawableEnd(R.drawable.ic_right_arrow_darker)
            containerWrapper.setPadding(0, itemData.paddingTop, 0, itemData.paddingBottom)

            galleryRv.isNestedScrollingEnabled = false
            galleryRv.apply {
                background = R.drawable.background_shape_white_radius_5.toDrawable(mContext)
                layoutManager = LinearLayoutManager(mContext)
                adapter = adapter ?: GameLibaoAdapter(mContext, libao, mGameName, mViewModel.game?.id ?: "")
                val itemDecoration = HorizontalDividerItemDecoration.Builder(mContext)
                    .size(0.5F.dip2px())
                    .margin(16F.dip2px())
                    .color(R.color.divider.toColor(mContext))
                    .build()
                if (itemDecorationCount != 0) {
                    removeItemDecorationAt(0)
                }
                addItemDecoration(itemDecoration)
            }
            titleTv.text = "游戏礼包"
            moreTv.visibility = View.GONE
        }
    }

    // 绑定游戏信息
    private fun bindGameDetailInfoViewHolder(viewHolder: GameDetailInfoViewHolder, itemData: DetailEntity) {
        val info = itemData.info!!

        viewHolder.binding.run {
            titleTv.setTextColor(R.color.text_title.toColor(mContext))
            tipsTv.setTextColor(R.color.text_subtitle.toColor(mContext))

            val paddingBottom = if (itemData.shouldBoundWithNextItem) 0 else itemData.paddingBottom
            containerWrapper.setPadding(
                mDefaultHorizontalPadding,
                itemData.paddingTop,
                mDefaultHorizontalPadding,
                paddingBottom
            )
            containerWrapper.setBackgroundColor(R.color.background.toColor(mContext))
            if (!info.topTags.isNullOrEmpty()) {
                labelsLl.visibility = View.VISIBLE
                labelsLl.removeAllViews()
                info.topTags.take(4).forEachIndexed { index, tag ->
                    labelsLl.addView(createGameInfoLabel(tag.name, index != 0))
                }
            }
            gameInfoRv.isNestedScrollingEnabled = false
            updateBoundableContainerBackground(container, false, itemData.shouldBoundWithNextItem)
            if (gameInfoRv.adapter == null) {
                gameInfoRv.apply {
                    val infoAdapter = GameDetailInfoItemAdapter(mContext, info, mViewModel, mGameName)
                    adapter = infoAdapter
                    layoutManager = LinearLayoutManager(context)
                    dividerView.goneIf(info.topTags.isEmpty() || infoAdapter.datas.size == 0)
                }
            } else {
                gameInfoRv.adapter?.run { notifyItemRangeChanged(0, itemCount) }
            }
        }
    }

    // 绑定游戏单推荐
    private fun bindGameCollectionViewHolder(holder: GameCollectionViewHolder, itemData: DetailEntity) {
        val recommendGameList = itemData.recommendGameList ?: return
        holder.binding.run {
            titleTv.text = "游戏单推荐"
            titleTv.setTextColor(R.color.text_title.toColor(mContext))
            moreTv.run {
                text = "游戏单广场"
                setTextColor(R.color.text_subtitleDesc.toColor(mContext))
                visibility = View.VISIBLE
                setDrawableEnd(R.drawable.ic_right_arrow_darker)
                setOnClickListener {
                    NewFlatLogUtils.logGameDetailGameListRecommendSquareJump(mGameName, mViewModel.gameId ?: "")
                    DirectUtils.directToGameCollectionSquare(it.context, mEntrance)
                }
            }
            galleryRv.run {
                isNestedScrollingEnabled = false
                layoutParams = (galleryRv.layoutParams as ConstraintLayout.LayoutParams).apply {
                    leftMargin = 0
                    rightMargin = 0
                }
                containerWrapper.setPadding(0, itemData.paddingTop, 0, itemData.paddingBottom)
                val exposureEventList = arrayListOf<ExposureEvent>()
                recommendGameList.forEachIndexed { index, entity ->
                    val event = ExposureEvent.createEvent(
                        gameEntity = GameEntity().apply {
                            sequence = index
                        },
                        source = listOf(
                            ExposureSource("游戏详情", mGameName),
                            ExposureSource("游戏单推荐", entity.id)
                        )
                    )
                    exposureEventList.add(event)
                    ExposureManager.log(event)
                }

                layoutManager = LinearLayoutManager(mContext, RecyclerView.HORIZONTAL, false)
                if (adapter == null) {
                    adapter = GameCollectionAdapter(recommendGameList, mEntrance, "游戏详情[${mGameName}]:游戏单推荐")
                } else {
                    adapter?.notifyItemRangeChanged(0, itemCount)
                }
            }
        }
    }

    // 绑定专题游戏单推荐
    private fun bindColumnRecommendViewHolder(holder: ColumnRecommendViewHolder, itemData: DetailEntity) {
        val columnGames = itemData.columnGames ?: return
        holder.binding.run {
            titleTv.text = itemData.columnTitle
            titleTv.setTextColor(R.color.text_title.toColor(mContext))
            moreTv.run {
                goneIf(itemData.displayHome.isEmpty()) {
                    text = itemData.displayHome
                    setTextColor(R.color.text_subtitleDesc.toColor(mContext))
                    setDrawableEnd(R.drawable.ic_right_arrow_darker)
                    setOnClickListener {
                        NewFlatLogUtils.logGameDetailColumnRecommendUpperRightClick(
                            mGameName,
                            mViewModel.gameId ?: "",
                            itemData.displayHome,
                            itemData.columnTitle,
                            itemData.columnId,
                            itemData.moreLink?.text ?: "",
                            itemData.moreLink?.type ?: "",
                            itemData.moreLink?.link ?: ""
                        )
                        if (itemData.displayHome == "换一批") {
                            headPb.visibility = View.VISIBLE
                            moreTv.isEnabled = false
                            mViewModel.changeSubjectGame(itemData.columnId, itemData.gameCount)
                        } else {
                            itemData.moreLink?.let {
                                DirectUtils.directToLinkPage(
                                    mContext,
                                    it,
                                    mEntrance,
                                    "游戏详情[${mGameName}]:专题游戏单推荐"
                                )
                            }
                        }
                    }
                }
            }
            galleryRv.run {
                isNestedScrollingEnabled = false
                layoutParams = (galleryRv.layoutParams as ConstraintLayout.LayoutParams).apply {
                    leftMargin = 0
                    rightMargin = 0
                    topMargin = 6F.dip2px()
                }
                containerWrapper.setPadding(0, itemData.paddingTop, 0, itemData.paddingBottom)
                layoutManager = LinearLayoutManager(mContext, RecyclerView.HORIZONTAL, false)
                if (adapter == null) {
                    val subjectEntity = SubjectEntity().apply {
                        data = columnGames
                    }
                    val exposureEventList = arrayListOf<ExposureEvent>()
                    for ((index, game) in subjectEntity.data!!.withIndex()) {
                        game.sequence = index
                        val event = ExposureEvent.createEvent(
                            gameEntity = game,
                            source = listOf(
                                ExposureSource("游戏详情", mGameName),
                                ExposureSource("专题推荐", itemData.columnTitle)
                            )
                        )
                        exposureEventList.add(event)
                        ExposureManager.log(event)
                    }
                    val subjectAdapter =
                        GameHorizontalAdapter(mContext, subjectEntity, GameHorizontalListType.GameDetailHorizontalType)
                    subjectAdapter.gameName = mGameName
                    subjectAdapter.gameId = mViewModel.gameId ?: ""
                    subjectAdapter.entrance = mEntrance
                    subjectAdapter.path = "专题游戏单推荐"
                    subjectAdapter.exposureEventList = exposureEventList
                    (itemAnimator as DefaultItemAnimator).supportsChangeAnimations = false
                    val itemDecoration = VerticalDividerItemDecoration.Builder(mContext)
                        .size(8F.dip2px())
                        .color(R.color.transparent.toColor(mContext))
                        .build()
                    addItemDecoration(itemDecoration)
                    adapter = subjectAdapter
                } else {
                    adapter?.notifyItemRangeChanged(0, itemCount)
                }
            }
        }
    }

    private fun updateBoundableContainerBackground(
        container: View,
        shouldBoundTogetherWithPreviousItem: Boolean,
        shouldBoundTogetherWithNextItem: Boolean
    ) {
        container.background =
            if (shouldBoundTogetherWithPreviousItem && shouldBoundTogetherWithNextItem) {
                R.drawable.background_shape_white.toDrawable(mContext)
            } else if (shouldBoundTogetherWithPreviousItem) {
                R.drawable.background_shape_white_radius_5_bottm_only.toDrawable(mContext)
            } else if (shouldBoundTogetherWithNextItem) {
                R.drawable.background_shape_white_radius_5_top_only.toDrawable(mContext)
            } else {
                R.drawable.background_shape_white_radius_5.toDrawable(mContext)
            }
    }

    private fun updateCommonCustomView(
        customColumn: CustomColumn,
        position: Int,
        binding: GamedetailItemCustomColumnBinding
    ) {
        val shrankSpanned: CharSequence
        val expandedSpanned: CharSequence
        val tags = if (customColumn.showInfoTag == true) customColumn.infoTag else arrayListOf()
        val maxDesLines = if (mExpandableTextExpandStatusSparseBooleanArray.get(position)) {
            Int.MAX_VALUE
        } else {
            when {
                customColumn.showDesType == "all" || customColumn.showDesRowNum == 0 -> Int.MAX_VALUE
                else -> mExpandableTextViewMaxLinesSparseIntArray.get(position, customColumn.showDesRowNum!!)
            }
        }
        val layoutManager =
            if (customColumn.showInfoTagDesType == "expand" || mCustomColumnTagsExpandStatusSparseBooleanArray.get(
                    position
                )
            ) {
                if (customColumn.showInfoTagDes == false) {
                    GridLayoutManager(mContext, 3)
                } else {
                    mCustomColumnTagsExpandStatusSparseBooleanArray.put(position, true)
                    LinearLayoutManager(mContext)
                }
            } else {
                GridLayoutManager(mContext, 3)
            }

        binding.run {
            linkTextContainer.goneIf(!(customColumn.showName ?: true))

            titleTv.text = customColumn.name

            contentHintContainer.goneIf(customColumn.title == null || TextUtils.isEmpty(customColumn.title?.value))

            contentTv.run {
                setTextColor(R.color.text_subtitle.toColor(mContext))
                val goneMarginTop = if (linkTextContainer.visibility == View.GONE
                    && contentHintContainer.visibility == View.GONE
                ) {
                    16F.dip2px()
                } else {
                    10F.dip2px()
                }

                contentTv.layoutParams = (contentTv.layoutParams as ConstraintLayout.LayoutParams).apply {
                    this.goneTopMargin = goneMarginTop
                }

                setExpandMaxLines(maxDesLines)
                setIsExpanded(Int.MAX_VALUE == maxDesLines)
                if (customColumn.isHtmlDes == true) {
                    shrankSpanned = HtmlCompat.fromHtml(
                        customColumn.desBrief ?: "",
                        HtmlCompat.FROM_HTML_MODE_COMPACT,
                        PicassoImageGetter(contentTv),
                        ExtraTagHandler()
                    )
                    expandedSpanned = HtmlCompat.fromHtml(
                        customColumn.des ?: "",
                        HtmlCompat.FROM_HTML_MODE_COMPACT,
                        PicassoImageGetter(contentTv),
                        ExtraTagHandler()
                    )
                    setTextWithInterceptingInternalUrl(shrankText = shrankSpanned, expandedText = expandedSpanned) {
                        val linkEntity = DefaultUrlHandler.urlToLinkEntity(it)
                        logCustomColumnLinkClicked(title = customColumn.name, linkEntity, "正文说明")
                    }
                } else {
                    shrankSpanned = TextHelper.getHighlightedSpannableStringThatIsWrappedInsideWrapper(
                        mContext,
                        customColumn.desBrief ?: ""
                    )
                    expandedSpanned = TextHelper.getHighlightedSpannableStringThatIsWrappedInsideWrapper(
                        mContext,
                        customColumn.des ?: ""
                    )
                    setShrankTextAndExpandedText(shrankSpanned, expandedSpanned)
                }
                goneIf(TextUtils.isEmpty(customColumn.des))
                setSelfCalculateMaxLinesCallback {
                    mExpandableTextViewMaxLinesSparseIntArray.put(position, it)
                    if (maxDesLines != it) {
                        post { notifyItemChanged(position) }
                    }
                }
                setExpandCallback {
                    mExpandableTextExpandStatusSparseBooleanArray.put(position, true)
                    if (customColumn.name == "游戏简介") {
                        MtaHelper.onEvent(MTA_KEY_GAME_NEW, "展开游戏介绍", mGameName)
                    } else {
                        MtaHelper.onEvent(MTA_KEY_GAME_NEW, "自定义栏目正文_全部", "${mGameName}-${customColumn.name}")
                    }
                }
            }

            recyclerview.run {
                goneIf(customColumn.infoTag == null || customColumn.infoTag?.size == 0)
                isNestedScrollingEnabled = false
                this.layoutManager = layoutManager
                setOnClickListener {
                    if (customColumn.showInfoTagDes == true) {
                        customColumn.showExpandTagsHint = false
                        SPUtils.setBoolean(Constants.SP_HAS_SHOWN_EXPANDED_GAME_DETAIL_TAGS_HINT, true)
                        mCustomColumnTagsExpandStatusSparseBooleanArray.put(position, true)
                        notifyItemChanged(position)
                    }
                }
                if (adapter == null) {
                    adapter = GameDetailCustomColumnAdapter(mContext)
                }

                (adapter as GameDetailCustomColumnAdapter)
                    .updateData(ArrayList(tags!!), mCustomColumnTagsExpandStatusSparseBooleanArray.get(position))
            }

            contentHintIv.display(customColumn.title?.icon, true)

            BindingAdapters.textColorFromString(contentHintTv, customColumn.title?.color)
            contentHintTv.text = customColumn.title?.value

            expandTagsHint.goneIf(customColumn.showExpandTagsHint == false)

            val linkClosure: (LinkEntity) -> Unit = {
                // 当配置的是不需要 id 也能跳转的时候直接跳转，否则都得根据是否有 ID 判断跳不跳
                if (it.type == "top_game_comment"
                    || it.type == "server"
                    || it.type == "feedback"
                ) {
                    it.name = mGameName
                    it.text = mViewModel.game?.getGameCategory().toString()
                    DirectUtils.directToLinkPage(
                        mContext,
                        it,
                        StringUtils.buildString(mEntrance, "游戏详情[", mGameName, "]:自定义栏目"),
                        ""
                    )
                } else {
                    PageSwitchDataHelper.pushCurrentPageData(
                        hashMapOf(
                            Pair(PageSwitchDataHelper.PAGE_BUSINESS_TYPE, "游戏详情-自定义栏目"),
                            Pair(PageSwitchDataHelper.PAGE_BUSINESS_NAME, mGameName)
                        )
                    )
                    DirectUtils.directToLinkPage(
                        mContext,
                        it,
                        StringUtils.buildString(mEntrance, "游戏详情[", mGameName, "]:自定义栏目"),
                        ""
                    )
                }
            }

            linkImageIv.display(customColumn.nameLink?.image, true)
            linkImageIv.setOnClickListener {
                logCustomColumnLinkClicked(customColumn.name, customColumn.nameLink, "图片")

                linkClosure(customColumn.nameLink ?: LinkEntity())
            }

            titleHintTv.paint?.isUnderlineText = true
            titleHintTv.text = customColumn.nameLink?.value
            titleHintTv.setOnClickListener {
                logCustomColumnLinkClicked(customColumn.name, customColumn.nameLink, "栏目标题后文案")

                linkClosure(customColumn.nameLink ?: LinkEntity())
            }

            var titleIconIvSize = 14F.dip2px()

            if (customColumn.link?.style == "button") {
                // 当类型为游戏时显示游戏图标并改变大小
                if (customColumn.link?.type == "game") {
                    titleIconIv.displayGameIcon(customColumn.link?.gameIcon, customColumn.link?.gameIconSubscript, true)
                    titleIconIvSize = 24F.dip2px()
                } else {
                    titleIconIv.displayGameIcon(customColumn.nameIcon, null, true)
                }

                linkHintArrowIv.visibility = View.GONE
                linkHintIv.visibility = View.GONE
                linkHintTv.layoutParams = (linkHintTv.layoutParams as ViewGroup.MarginLayoutParams).apply {
                    width = ViewGroup.LayoutParams.WRAP_CONTENT
                    height = 24F.dip2px()
                    rightMargin = 0
                }
                linkHintTv.maxWidth = Int.MAX_VALUE
                linkHintTv.setPadding(12F.dip2px(), 0, 12F.dip2px(), 0)
                linkHintTv.background = R.drawable.download_button_normal_style.toDrawable()
                linkHintTv.text = customColumn.link?.value
                linkHintTv.setTextColor(Color.WHITE)
                linkHintTv.gravity = Gravity.CENTER
            } else {
                titleIconIv.displayGameIcon(customColumn.nameIcon, null, true)
                linkHintArrowIv.goneIf(customColumn.link == null)
                linkHintArrowIv.setOnClickListener { linkHintTv.performClick() }
                linkHintTv.text = customColumn.link?.value
                linkHintTv.setPadding(0, 0, 0, 0)
                linkHintTv.layoutParams = linkHintTv.layoutParams.apply {
                    width = ViewGroup.LayoutParams.WRAP_CONTENT
                    height = ViewGroup.LayoutParams.WRAP_CONTENT
                }
                linkHintTv.maxWidth = 74F.dip2px()
                linkHintIv.setOnClickListener {
                    logCustomColumnLinkClicked(customColumn.name, customColumn.link!!, "右上角图标")
                    linkClosure(customColumn.link ?: LinkEntity())
                }
                linkHintIv.display(customColumn.link?.icon, true)
                linkHintTv.background = ColorDrawable(Color.TRANSPARENT)
                linkHintTv.setTextColor(R.color.theme_font.toColor(mContext))
            }

            linkHintTv.setOnClickListener {
                logCustomColumnLinkClicked(customColumn.name, customColumn.link!!, "右上角文案")
                linkClosure(customColumn.link ?: LinkEntity())
            }

            if (titleIconIv.visibility == View.VISIBLE) {
                titleIconIv.layoutParams = titleIconIv.layoutParams.apply {
                    width = titleIconIvSize
                    height = titleIconIvSize
                }
            }
        }
    }

    private fun logCustomColumnLinkClicked(title: String, link: LinkEntity?, entrance: String) {
        NewLogUtils.logCustomColumnClicked(
            gameId = mViewModel.gameId,
            gameName = mGameName,
            title = title,
            entrance = entrance,
            linkType = link?.type,
            linkTitle = link?.text
        )
    }

    private fun createGameInfoLabel(label: String, hasDividingLine: Boolean = false): TextView {
        return TextView(mContext).apply {
            val params = LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT)
            params.weight = 1F
            layoutParams = params
            textSize = 13F
            setTextColor(R.color.text_subtitle.toColor(mContext))
            text = label
            if (hasDividingLine) {
                compoundDrawablePadding = 12F.dip2px()
                setDrawableStart(R.drawable.game_detail_info_dividing_line)
            }
        }
    }

    companion object {
        const val CUSTOM_COLUMN = 64 // 自定义栏目
        const val RELATED_VERSION = 128//其他相关版本
        const val COMMENTS = 8//评论
        const val IMAGE = 3//图片推荐
        const val RECOMMENDED_GAMES = 100//大家都在玩
        const val VIDEOS = 129//视频
        const val IMAGE_GALLERY = 130//图片
        const val UPDATE_CONTENT = 131//更新内容
        const val LATEST_SERVICE = 132//最新开服
        const val INFO_RAIDERS = 133//新手攻略
        const val LIBAO = 134//游戏礼包
        const val GAME_DETAIL = 135//游戏详细信息
        const val NOTICE = 136 //公告
        const val RECOMMEND_GAME_LIST = 137 //游戏单推荐
        const val COLUMN_RECOMMEND = 138 //专题游戏推荐
        const val FOOTER = 101

        const val MTA_KEY_GAME_NEW = "游戏详情_新" // 保留已弃用的 MTA 事件是为了以后加自有日志的时候不用再痛苦地找代码，实际上 MTA 的相关代码会在编译期移除，所以不用担心
    }

    class GameDetailNoticeViewHolder(var binding: GamedetailItemDescNoticeBinding, handler: Handler) :
        ExposureViewHolder(binding.root, handler)

    class GameDetailRecommendImageViewHolder(var binding: GamedetailItemImageBinding, handler: Handler) :
        ExposureViewHolder(binding.root, handler)

    inner class GameDetailCommentsViewHolder(var binding: GamedetailItemCommentsBinding, handler: Handler) :
        ExposureViewHolder(binding.root, handler) {
        override fun exposureLog() {
            NewLogUtils.logGameDetailCommentView(mViewModel.game?.name ?: "", mViewModel.game?.id ?: "")
        }
    }

    inner class GameDetailCustomColumnViewHolder(var binding: GamedetailItemCustomColumnBinding, handler: Handler) :
        ExposureViewHolder(binding.root, handler) {
        override fun exposureLog() {
            NewFlatLogUtils.logGameDetailColumnOrderingView(
                binding.titleTv.text.toString(),
                mViewModel.game?.name ?: "",
                mViewModel.game?.id ?: ""
            )
        }
    }

    class GameDetailRelatedVersionViewHolder(var binding: GameGalleryListBinding, handler: Handler) :
        ExposureViewHolder(binding.root, handler)

    class GameVideoGalleryViewHolder(var binding: GameGalleryListBinding, handler: Handler) :
        ExposureViewHolder(binding.root, handler)

    class GameImageGalleryViewHolder(var binding: GameGalleryListBinding, handler: Handler) :
        ExposureViewHolder(binding.root, handler)

    inner class GameUpdateContentViewHolder(var binding: GameUpdateContentBinding, handler: Handler) :
        ExposureViewHolder(binding.root, handler) {
        override fun exposureLog() {
            NewLogUtils.logGameDetailUpdatedView(mViewModel.game?.name ?: "", mViewModel.game?.id ?: "")
        }
    }

    inner class GameLatestServiceViewHolder(var binding: GameLatestServiceListBinding, handler: Handler) :
        ExposureViewHolder(binding.root, handler) {
        override fun exposureLog() {
            NewLogUtils.logGameDetailOpenListView(mViewModel.game?.name ?: "", mViewModel.game?.id ?: "")
        }
    }

    class GameRaidersGalleryViewHolder(var binding: GameGalleryListBinding, handler: Handler) :
        ExposureViewHolder(binding.root, handler)

    inner class GameLibaoGalleryViewHolder(var binding: GameGalleryListBinding, handler: Handler) :
        ExposureViewHolder(binding.root, handler) {
        override fun exposureLog() {
            NewLogUtils.logGameDetailGiftView(mViewModel.game?.name ?: "", mViewModel.game?.id ?: "")
        }
    }

    class GameDetailInfoViewHolder(var binding: GameDetailInfoBinding, handler: Handler) :
        ExposureViewHolder(binding.root, handler)

    inner class GamesRecommendedGalleryViewHolder(var binding: GameGalleryListBinding, handler: Handler) :
        ExposureViewHolder(binding.root, handler) {
        override fun exposureLog() {
            NewLogUtils.logGameDetailPopularView(mViewModel.game?.name ?: "", mViewModel.game?.id ?: "")
        }
    }

    class GameCollectionViewHolder(var binding: GameGalleryListBinding, handler: Handler) :
        ExposureViewHolder(binding.root, handler)

    class ColumnRecommendViewHolder(var binding: GameGalleryListBinding, handler: Handler) :
        ExposureViewHolder(binding.root, handler)
}