package com.gh.gamecenter.adapter.viewholder

import android.content.Context
import android.content.Intent
import android.text.TextUtils
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.Group
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.FragmentActivity
import com.airbnb.lottie.LottieAnimationView
import com.gh.common.chain.*
import com.gh.common.constant.Config
import com.gh.common.dialog.DeviceRemindDialog
import com.gh.common.dialog.GameOffServiceDialogFragment
import com.gh.common.dialog.PackageCheckDialogFragment
import com.gh.common.filter.RegionSettingHelper
import com.gh.common.history.HistoryHelper
import com.gh.common.simulator.NewSimulatorGameManager
import com.gh.common.simulator.SimulatorDownloadManager
import com.gh.common.simulator.SimulatorGameManager
import com.gh.common.util.*
import com.gh.common.util.GameUtils.getDownloadBtnText
import com.gh.common.util.LogUtils
import com.gh.common.xapk.XapkInstaller
import com.gh.common.xapk.XapkUnzipStatus
import com.gh.download.DownloadManager
import com.gh.download.dialog.DownloadDialog
import com.gh.gamecenter.DownloadManagerActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.WebActivity
import com.gh.gamecenter.common.base.GlobalActivityManager.getCurrentPageEntity
import com.gh.gamecenter.common.base.GlobalActivityManager.getLastPageEntity
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.utils.NewFlatLogUtils
import com.gh.gamecenter.core.runOnIoThread
import com.gh.gamecenter.core.runOnUiThread
import com.gh.gamecenter.core.utils.PageSwitchDataHelper
import com.gh.gamecenter.core.utils.StringUtils
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.eventbus.EBScroll
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.entity.PluginLocation
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.view.DownloadButton
import com.gh.gamecenter.feature.view.DownloadButton.ButtonStyle
import com.gh.gamecenter.gamedetail.GameDetailViewModel
import com.gh.gamecenter.gamedetail.accelerator.GameDetailAcceleratorUiHelper
import com.gh.gamecenter.gamedetail.dialog.GamePermissionDialogFragment
import com.gh.gamecenter.gamedetail.entity.GameDetailTabEntity
import com.gh.gamecenter.teenagermode.TeenagerModeActivity.Companion.getIntent
import com.gh.vspace.VHelper
import com.lightgame.download.DownloadEntity
import com.lightgame.download.DownloadStatus
import org.greenrobot.eventbus.EventBus
import java.io.File

// 虽然叫 ViewHolder，但其实就是一个用来临时放 View 和相关操作的包裹类
class DetailViewHolder(
    view: View,
    val viewModel: GameDetailViewModel?,
    val gameEntity: GameEntity,
    val isNewsDetail: Boolean, // 新闻详情不显示下载的游戏名, 只显示下载状态
    entrance: String?,
    name: String?,
    title: String?,
    val traceEvent: ExposureEvent?,
    val isSupportDualButton: Boolean = false, // 是否支持双下载按钮，不支持的时候跟普通列表意义选用优先级高的那个来显示,
    val acceleratorUiHelper: GameDetailAcceleratorUiHelper? = null,  // 网速加速，只有游戏详情才有
    onDownloadClickAction: ((Boolean) -> Unit)? = null
) {
    var context: Context
    var downloadBottom: View

    // 本地下载的占位下载按钮
    val localDownloadButton: DownloadButton?

    // 本地下载的尺寸 TV
    val localDownloadSizeTv: TextView?

    // 本地下载的标题 TV
    val localDownloadTitleTv: TextView?

    // 本地下载的外层包裹 View
    val localDownloadContainer: View?

    // 额外的文字 (用于一些含图片的情况)
    val overlayTv: TextView?
    val overlayContainer: View?
    val extraOverlayTv: TextView?

    var downloadPb: DownloadButton
    var downloadTips: LottieAnimationView

    // 多版本下载文字
    var multiVersionDownloadTv: TextView?

    // 加速按钮
    val speedContainer: ConstraintLayout?
    private val ivFreeVipTag: ImageView?
    private val gMoreZone: Group?
    private val gUpdate: Group?
    private val ivUpdate: ImageView?
    private val tvSize: TextView?
    private val vUpdate: View?
    private val tvUpdate: TextView?

    private var isShowVaUpdate = true

    // 注意 View 的命名
    init {
        downloadBottom = view.findViewById(R.id.detail_ll_bottom)
        downloadPb = downloadBottom.findViewById(R.id.detail_progressbar)
        downloadTips = downloadBottom.findViewById(R.id.downloadTipsLottie)
        overlayTv = view.findViewById(R.id.overlayTv)
        overlayContainer = view.findViewById(R.id.overlayContainer)
        extraOverlayTv = view.findViewById(R.id.extraOverlayTv)
        multiVersionDownloadTv = downloadBottom.findViewById(R.id.multiVersionDownloadTv)
        localDownloadContainer = view.findViewById(R.id.localDownloadContainer)
        localDownloadSizeTv = view.findViewById(R.id.localDownloadSizeTv)
        localDownloadTitleTv = view.findViewById(R.id.localDownloadTitleTv)
        localDownloadButton = view.findViewById(R.id.localDownloadButton)

        speedContainer = view.findViewById(R.id.cl_speed_container)
        ivFreeVipTag = view.findViewById(R.id.iv_free_vip_tag)
        gMoreZone = view.findViewById(R.id.g_more_zone)
        gUpdate = view.findViewById(R.id.g_update)
        ivUpdate = view.findViewById(R.id.iv_update)
        tvSize = view.findViewById(R.id.tv_size)
        vUpdate = view.findViewById(R.id.v_update)
        tvUpdate = view.findViewById(R.id.tv_update)

        context = view.context.getActivity() ?: view.context
        com.gh.gamecenter.common.R.color.text_aw_primary.toColor()

        var gameDownloadMode = gameEntity.getGameDownloadButtonMode()

        val localDownloadListener = OnDetailDownloadClickListener(
            mViewHolder = this,
            mEntrance = entrance,
            mName = name ?: "",
            mTitle = title ?: "",
            mAsVGame = false,
            mShowDualDownloadButton = gameDownloadMode == GameEntity.GAME_DOWNLOAD_BUTTON_MODE_DUAL,
            mTraceEvent = traceEvent,
            onDownloadClickAction = onDownloadClickAction
        )

        val vGameDownloadListener = OnDetailDownloadClickListener(
            mViewHolder = this,
            mEntrance = entrance,
            mName = name ?: "",
            mTitle = title ?: "",
            mAsVGame = true,
            mShowDualDownloadButton = gameDownloadMode == GameEntity.GAME_DOWNLOAD_BUTTON_MODE_DUAL,
            mTraceEvent = traceEvent,
            onDownloadClickAction = onDownloadClickAction
        )

        // 不支持双下载按钮的情况时，优选一个下载方式显示
        if (!isSupportDualButton) {
            val performAsVGame = GameUtils.shouldPerformAsVGame(gameEntity)
            gameDownloadMode = if (performAsVGame) {
                GameEntity.GAME_DOWNLOAD_BUTTON_MODE_VGAME
            } else {
                GameEntity.GAME_DOWNLOAD_BUTTON_MODE_DOWNLOAD
            }
        }

        when (gameDownloadMode) {
            GameEntity.GAME_DOWNLOAD_BUTTON_MODE_DOWNLOAD -> {
                // 仅显示下载按钮
                downloadPb.setOnClickListener(localDownloadListener)
                localDownloadButton?.setOnClickListener(null)
            }

            GameEntity.GAME_DOWNLOAD_BUTTON_MODE_VGAME -> {
                // 仅显示畅玩按钮
                downloadPb.setOnClickListener(vGameDownloadListener)
                localDownloadButton?.setOnClickListener(null)
            }

            GameEntity.GAME_DOWNLOAD_BUTTON_MODE_DUAL -> {
                // 显示双按钮
                downloadPb.setOnClickListener(vGameDownloadListener)
                localDownloadButton?.setOnClickListener(localDownloadListener)
                localDownloadButton?.putObject(gameEntity)
                localDownloadButton?.setTag(
                    com.gh.gamecenter.feature.R.string.download, context.getString(
                        com.gh.gamecenter.feature.R.string.download_local
                    )
                )

                vUpdate?.setOnClickListener {
                    if (isShowVaUpdate) {
                        vGameDownloadListener.onClick(vUpdate)
                    } else {
                        localDownloadListener.onClick(vUpdate)
                    }
                }
            }
        }



        downloadPb.putWidgetBusinessName("游戏详情页")
        // "DownLoadbuttonClick" 埋点需要上报traceEvent信息

        gameEntity.exposureEvent = traceEvent
        downloadPb.putObject(gameEntity)
        restoreDialogFragment()
    }

    private fun restoreDialogFragment() {
        val gamePermissionDialogFragment = (context.getActivity() as? AppCompatActivity)?.supportFragmentManager?.findFragmentByTag(
            GamePermissionDialogFragment::class.java.name
        ) as DialogFragment?
        gamePermissionDialogFragment?.dismissAllowingStateLoss()
    }


    fun checkIfShowSpeedUi(showVGame: Boolean, showDualDownloadButton: Boolean) {
        acceleratorUiHelper?.let {
            val showSpeedUi = when {
                gameEntity.canSpeed && showDualDownloadButton -> {  // 双按钮
                    val localText = getDownloadBtnText(context, gameEntity, false, false, PluginLocation.only_game);
                    val downloadText =
                        getDownloadBtnText(context, gameEntity, false, true, PluginLocation.only_game)
                    when {
                        localText.contains(com.gh.gamecenter.feature.R.string.update.toResString()) -> {  // 本地游戏需要更新
                            localDownloadContainer?.goneIf(true)
                            downloadPb.goneIf(true)
                            overlayTv?.goneIf(true)

                            gUpdate?.visibility = View.VISIBLE
                            ivUpdate?.goneIf(true)
                            tvSize?.goneIf(false)
                            tvSize?.text =
                                DetailDownloadUtils.convertSizeString(gameEntity.getApk().firstOrNull()?.size ?: "")
                            tvUpdate?.setText(R.string.update)
                            isShowVaUpdate = false
                            true
                        }

                        localText.contains(com.gh.gamecenter.feature.R.string.launch.toResString()) && downloadText == "更新" -> {    // 畅玩游戏需要更新:显示 加速/更新
                            localDownloadContainer?.goneIf(true)
                            downloadPb.goneIf(true)
                            overlayTv?.goneIf(true)

                            gUpdate?.visibility = View.VISIBLE
                            ivUpdate?.goneIf(false)
                            tvSize?.goneIf(true)
                            tvUpdate?.setText(R.string.update)
                            isShowVaUpdate = true
                            true
                        }

                        localText.contains(com.gh.gamecenter.feature.R.string.launch.toResString()) -> {  // 本地游戏为启动状态：显示 加速/畅玩
                            localDownloadContainer?.goneIf(true)
                            downloadPb.goneIf(true)
                            overlayTv?.goneIf(true)

                            gUpdate?.visibility = View.VISIBLE
                            tvUpdate?.setText(R.string.v_play)
                            tvSize?.goneIf(true)
                            isShowVaUpdate = true
                            true
                        }

                        else -> {
                            gUpdate?.visibility = View.GONE
                            tvSize?.goneIf(true)
                            false
                        }
                    }
                }

                gameEntity.canSpeed && !showVGame -> {
                    gUpdate?.visibility = View.GONE
                    val downloadText = getDownloadBtnText(context, gameEntity, false, false, PluginLocation.only_game)
                    when {
                        downloadText.contains(com.gh.gamecenter.feature.R.string.launch.toResString()) -> {
                            localDownloadContainer?.goneIf(true)
                            downloadPb.goneIf(true)
                            true
                        }

                        downloadText.contains(R.string.update.toResString()) -> true

                        else -> false
                    }
                }

                else -> false
            }
            it.checkIfShowSpeedUi(showSpeedUi, showDualDownloadButton)

        }
    }

    fun setSpeedViewsVisible(isVisible: Boolean) {
        ivFreeVipTag?.goneIf(!isVisible)
        speedContainer?.goneIf(!isVisible)
    }

    internal class OnDetailDownloadClickListener(
        private val mViewHolder: DetailViewHolder,
        private val mEntrance: String?,
        private val mName: String,
        private val mTitle: String,
        private val mAsVGame: Boolean,
        private val mShowDualDownloadButton: Boolean,
        private val mTraceEvent: ExposureEvent?,
        private val onDownloadClickAction: ((Boolean) -> Unit)? = null
    ) : View.OnClickListener {

        private val mGameEntity: GameEntity = mViewHolder.gameEntity
        private var mDownloadEntity: DownloadEntity? = null
        private val mPausedText = mViewHolder.context.getString(com.gh.gamecenter.feature.R.string.paused)

        private fun showLandPageAddressDialogIfNeeded() {
            if (mGameEntity.isLandPageAddressDialog() && !mGameEntity.isLandPageAddressDialogShowOnly()) {
                // 第三方落地页为开启状态并且展示状态不为“仅显示弹窗”,需要在点击确认后显示弹窗
                DialogUtils.showLandPageAddressDialog(mViewHolder.context, mGameEntity) {
                    val packageName = mGameEntity.getApk().firstOrNull()?.packageName
                    if (packageName?.isNotEmpty() == true) {
                        PackageChangeHelper.addInstallPendingPackage(packageName)
                    }
                    DirectUtils.directToExternalBrowser(mViewHolder.context, mGameEntity.landPageAddressDialog!!.link!!)
                }
            }
        }

        override fun onClick(v: View) {
            v.tag = null

            val downloadButton: DownloadButton = if (mAsVGame) {
                mViewHolder.downloadPb
            } else if (mShowDualDownloadButton) {
                mViewHolder.localDownloadButton ?: mViewHolder.downloadPb
            } else {
                mViewHolder.downloadPb
            }

            if (downloadButton.buttonStyle !== ButtonStyle.INSTALL_NORMAL
                && downloadButton.buttonStyle !== ButtonStyle.INSTALL_PLUGIN
                && downloadButton.buttonStyle !== ButtonStyle.LAUNCH_OR_OPEN
                && downloadButton.buttonStyle !== ButtonStyle.NONE
                && downloadButton.buttonStyle !== ButtonStyle.NONE_WITH_HINT
            ) {
                // 畅玩游戏的非真实点击下载按钮下载不需要滚动到特定地方
                if (!mAsVGame || VHelper.shouldLaunchGameAfterInstallation()) {
                    EventBus.getDefault().post(EBScroll(Constants.EB_GAME_DETAIL, mGameEntity.id))
                }
            }

            if (mDownloadEntity == null) {
                mDownloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(mGameEntity)
            }

            if (mDownloadEntity != null) {
                val xapkStatus = mDownloadEntity!!.meta[XapkInstaller.XAPK_UNZIP_STATUS]
                // 安装过程中避免重复点击
                if (XapkUnzipStatus.SUCCESS.name == xapkStatus && XapkInstaller.isInstalling(mDownloadEntity!!.path)) {
                    return
                }
                if (XapkUnzipStatus.UNZIPPING.name == xapkStatus) {
                    XapkInstaller.cancelUnzipTask(mDownloadEntity!!)
                    return
                } else if (XapkUnzipStatus.FAILURE.name == xapkStatus) {
                    PermissionHelper.checkStoragePermissionBeforeAction(
                        context = mViewHolder.context,
                        gameId = mGameEntity.id,
                        gameName = (if (mGameEntity.name != null) mGameEntity.name else "")!!,
                        gameType = mGameEntity.categoryChinese,
                        gameFormat = mGameEntity.getApk().firstOrNull()?.format
                    ) {
                        if (mDownloadEntity != null) {
                            val path = mDownloadEntity!!.path
                            if (FileUtils.isEmptyFile(path)) {
                                ToastUtils.toast(mViewHolder.context.getString(com.gh.gamecenter.common.R.string.install_failure_hint))
                                DownloadManager.getInstance().cancel(mDownloadEntity!!.url)
                            } else {
                                NewFlatLogUtils.logGameInstall(
                                    mGameEntity.id,
                                    mGameEntity.name ?: "",
                                    "主动安装"
                                )
                                SensorsBridge.trackInstallGameClick(
                                    mGameEntity.id,
                                    mGameEntity.name ?: "",
                                    "主动安装",
                                    mGameEntity.isDspGame,
                                    mGameEntity.dspAdId
                                )
                                PackageInstaller.install(mViewHolder.context, mDownloadEntity)
                            }
                        }
                    }
                    return
                }
            }

            when (downloadButton.buttonStyle) {
                ButtonStyle.NONE_WITH_HINT, ButtonStyle.NONE -> {
                    val offStatus = mGameEntity.downloadOffStatus
                    if (offStatus != null && "off" != offStatus) {
                        when (offStatus) {
                            "dialog" -> {
                                showOffServiceDialog(mGameEntity.downloadOffDialog) {
                                    showLandPageAddressDialogIfNeeded()
                                }
                            }

                            "toast" -> {
                                mViewHolder.viewModel?.performTabSelected(GameDetailTabEntity.TYPE_COMMENT)
                                ToastUtils.toast("该游戏因故暂不提供下载，具体详情可在相关评论中查看，敬请谅解～")
                                showLandPageAddressDialogIfNeeded()
                            }

                            "third_party" -> {
                                showLandPageAddressDialogIfNeeded()
                            }
                        }
                    } else {
                        ToastUtils.toast("该游戏已关闭下载")
                        showLandPageAddressDialogIfNeeded()
                    }
                }

                ButtonStyle.NORMAL -> {
                    val gameH5Download = RegionSettingHelper.getGameH5DownloadByGameId(mGameEntity.id)
                    if (gameH5Download != null) {
                        DialogUtils.showGameH5DownloadDialog(mViewHolder.context, mGameEntity, gameH5Download)
                        return
                    } else {
                        DataLogUtils.uploadGameLog(mViewHolder.context, mGameEntity.id, mGameEntity.name, mEntrance)
                    }

                    preDownload()
                }

                ButtonStyle.PLUGIN -> {
                    preDownload()
                }

                ButtonStyle.LAUNCH_OR_OPEN -> if (mGameEntity.getApk().size == 1) {
                    //启动模拟器游戏
                    if (SimulatorGameManager.isSimulatorGame(mGameEntity)) {
                        if (NewSimulatorGameManager.shouldShowUpdateNewSimulatorAlert(mViewHolder.context)) {
                            NewSimulatorGameManager.showUpdateNewsSimulator(mViewHolder.context, mGameEntity, null)
                            return
                        }
                        val downloadEntity =
                            SimulatorGameManager.findDownloadEntityByUrl(mGameEntity.getApk().firstOrNull()?.url)
                        if (downloadEntity != null) {
                            val file = File(downloadEntity.path)
                            if (!file.exists()) {
                                download(asVGame = false, isSubscribe = false)
                                return
                            }
                            SimulatorGameManager.launchSimulatorGame(downloadEntity, mGameEntity)
                        }
                        return
                    }
                    if (mAsVGame) {
                        VHelper.installOrLaunch(mViewHolder.context, mGameEntity, null)
                    } else {
                        // 如果游戏配置了加速，则启动时需要进行包名检测
                        if (mGameEntity.canSpeed) {
                            PackageCheckDialogFragment.show(mViewHolder.context as AppCompatActivity, mGameEntity) {
                                PackageLauncher.launchApp(
                                    mViewHolder.context, mGameEntity, mGameEntity.getUniquePackageName()
                                )
                            }
                        } else {
                            PackageLauncher.launchApp(
                                mViewHolder.context, mGameEntity, mGameEntity.getUniquePackageName()
                            )
                        }

                    }
                } else {
                    GamePermissionDialogFragment.show(
                        activity = (mViewHolder.context as AppCompatActivity),
                        game = mGameEntity,
                        gameInfo = mGameEntity.info
                    ) {
                        PermissionHelper.checkStoragePermissionBeforeAction(
                            context = mViewHolder.context,
                            gameId = mGameEntity.id,
                            gameName = mGameEntity.name ?: "",
                            gameType = mGameEntity.categoryChinese,
                            gameFormat = mGameEntity.getApk().firstOrNull()?.format
                        ) {
                            DownloadDialog.showDownloadDialog(
                                context = mViewHolder.context,
                                gameEntity = mGameEntity,
                                traceEvent = mTraceEvent,
                                entrance = StringUtils.buildString(mEntrance, "+(", mName, "[", mTitle, "])"),
                                location = "$mName:$mTitle",
                                onDownloadClickAction = onDownloadClickAction
                            )
                        }
                    }
                }

                ButtonStyle.INSTALL_PLUGIN, ButtonStyle.INSTALL_NORMAL -> {
                    if (mGameEntity.getApk().isEmpty()) return

                    NewFlatLogUtils.logGameInstall(
                        gameId = mGameEntity.id,
                        gameName = mGameEntity.name ?: "",
                        trigger = "主动安装"
                    )
                    SensorsBridge.trackInstallGameClick(
                        gameId = mGameEntity.id,
                        gameName = mGameEntity.name ?: "",
                        action = "主动安装",
                        isDspGame = mGameEntity.isDspGame,
                        dspAdId = mGameEntity.dspAdId
                    )
                    val url = mGameEntity.getApk().firstOrNull()?.url
                    val downloadEntity = SimulatorGameManager.findDownloadEntityByUrl(url)
                    if (mGameEntity.simulator != null) {
                        val isInstalled = PackageUtils.isInstalledFromAllPackage(
                            mViewHolder.context,
                            mGameEntity.simulator!!.apk!!.packageName
                        )
                        val isInstalledNewSimulator = SimulatorGameManager.isNewSimulatorInstalled(mViewHolder.context)
                        val isInstalledOldSimulator = SimulatorGameManager.isOldSimulatorInstalled(mViewHolder.context)
                        var simulator = mGameEntity.simulator
                        val newSimulator = Config.getNewSimulatorEntitySetting()
                        if (!isInstalledOldSimulator && newSimulator != null && newSimulator.active) {
                            simulator = newSimulator
                        }
                        if (downloadEntity != null && SimulatorGameManager.isSimulatorGame(mGameEntity) && !isInstalled && !isInstalledNewSimulator) {
                            SimulatorDownloadManager.getInstance().showDownloadDialog(
                                context = mViewHolder.context,
                                simulator = simulator,
                                location = SimulatorDownloadManager.SimulatorLocation.LAUNCH,
                                gameId = mGameEntity.id,
                                gameName = mGameEntity.name!!,
                                gameCategoryChinese = mGameEntity.categoryChinese,
                                cancelCallback = null
                            )
                            return
                        }
                    }
                    if (mAsVGame) {
                        VHelper.installOrLaunch(v.context, mGameEntity, null)
                        return
                    }
                    PermissionHelper.checkStoragePermissionBeforeAction(
                        context = mViewHolder.context,
                        gameId = mGameEntity.id,
                        gameName = (if (mGameEntity.name != null) mGameEntity.name else "")!!,
                        gameType = mGameEntity.categoryChinese,
                        gameFormat = mGameEntity.getApk().firstOrNull()?.format
                    ) {
                        if (mDownloadEntity == null) {
                            mDownloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(mGameEntity)
                        }
                        if (mDownloadEntity != null) {
                            val path = mDownloadEntity!!.path
                            if (FileUtils.isEmptyFile(path)) {
                                ToastUtils.toast(mViewHolder.context.getString(com.gh.gamecenter.common.R.string.install_failure_hint))
                                DownloadManager.getInstance().cancel(mDownloadEntity!!.url)
                            } else {
                                PackageInstaller.install(
                                    context = mViewHolder.context,
                                    downloadEntity = mDownloadEntity!!,
                                    showUnzipToast = false,
                                    ignoreAsVGame = true
                                )
                            }
                        }
                    }
                }

                ButtonStyle.RESERVABLE -> {
                    GamePermissionDialogFragment.show(
                        activity = (mViewHolder.context as AppCompatActivity),
                        game = mGameEntity,
                        gameInfo = mGameEntity.info
                    ) {
                        SensorsBridge.trackEvent(
                            "AppointmentGame",
                            "game_name",
                            mGameEntity.name!!,
                            "game_id",
                            mGameEntity.id,
                            "game_type",
                            mGameEntity.categoryChinese,
                            "source_entrance", "其他",
                            "page_name", getCurrentPageEntity().pageName,
                            "page_id", getCurrentPageEntity().pageId,
                            "page_business_id", getCurrentPageEntity().pageBusinessId,
                            "last_page_name", getLastPageEntity().pageName,
                            "last_page_id", getLastPageEntity().pageId,
                            "last_page_business_id", getLastPageEntity().pageBusinessId,
                            "source", mGameEntity.exposureEvent?.source?.toString() ?: "",
                            "is_ad", if (mGameEntity.adGroupId.isEmpty()) "false" else "true",
                            "ad_group_id", mGameEntity.adGroupId,
                            *mGameEntity.customPageTrackData?.toKV() ?: arrayOf()
                        )
                        CheckLoginUtils.checkLogin(mViewHolder.context, mEntrance) {
                            ReservationHelper.reserve(mViewHolder.context, mGameEntity) {
                                LogUtils.logReservation(mGameEntity, mTraceEvent)
                                DetailDownloadUtils.updateViewHolder(mViewHolder)
                            }
                        }
                    }
                }

                ButtonStyle.RESERVED -> {
                    ReservationHelper.showCancelReservationDialog(mViewHolder.context, mGameEntity) {
                        ReservationHelper.cancelReservation(mGameEntity) {
                            DetailDownloadUtils.updateViewHolder(mViewHolder)
                        }
                    }
                }

                ButtonStyle.H5_GAME -> {
                    val linkEntity = mGameEntity.h5Link
                    val isPlay = "play" == linkEntity!!.type // 是否为开始玩
                    if (isPlay) {
                        HistoryHelper.insertGameEntity(mGameEntity)
                    }
                    GamePermissionDialogFragment.show(
                        (mViewHolder.context as AppCompatActivity), mGameEntity, mGameEntity.info
                    ) {
                        val i = Intent(
                            WebActivity.getIntentForWebGame(
                                mViewHolder.context,
                                linkEntity.link,
                                mGameEntity.name,
                                isPlay,
                                linkEntity.closeButton
                            )
                        )
                        mViewHolder.context.startActivity(i)
                    }
                }

                ButtonStyle.UPDATING -> {
                    ToastUtils.toast("正在加急更新版本，敬请后续留意")
                    showLandPageAddressDialogIfNeeded()
                }

                ButtonStyle.TEENAGER_MODE -> {
                    SensorsBridge.trackAdolescentModeDialogShow(
                        mGameEntity.id,
                        (if (mGameEntity.name != null) mGameEntity.name else "")!!,
                        mGameEntity.categoryChinese
                    )
                    DialogHelper.showCenterDialog(
                        context = mViewHolder.context,
                        title = "提示",
                        content = "当前处于儿童/青少年模式， \n暂不提供游戏下载",
                        positiveText = "退出青少年模式",
                        negativeText = "关闭",
                        positiveClickCallback = {
                            mViewHolder.context.startActivity(getIntent(mViewHolder.context))
                            SensorsBridge.trackAdolescentModeDialogClick(
                                "退出青少年模式",
                                mGameEntity.id,
                                (if (mGameEntity.name != null) mGameEntity.name else "")!!,
                                mGameEntity.categoryChinese
                            )
                        },
                        negativeClickCallback = {
                            SensorsBridge.trackAdolescentModeDialogClick(
                                "关闭弹窗",
                                mGameEntity.id,
                                (if (mGameEntity.name != null) mGameEntity.name else "")!!,
                                mGameEntity.categoryChinese
                            )
                        }
                    ) {
                        SensorsBridge.trackAdolescentModeDialogClick(
                            "关闭",
                            mGameEntity.id,
                            (if (mGameEntity.name != null) mGameEntity.name else "")!!,
                            mGameEntity.categoryChinese
                        )
                    }
                }

                ButtonStyle.SPECIAL_DOWNLOAD -> {
                    val info = RegionSettingHelper.getGameSpecialDownloadInfo(mGameEntity.id)
                    if (info != null && !TextUtils.isEmpty(info.bbsId)) {
                        if (!TextUtils.isEmpty(info.topId)) {
                            val map = HashMap<String, String>()
                            map[EntranceConsts.KEY_TOP_ID] = info.topId
                            PageSwitchDataHelper.pushCurrentPageData(map)
                        }
                        DirectUtils.directForumDetail(mViewHolder.context, info.bbsId, mEntrance)
                    }
                }

                ButtonStyle.WAITING -> ToastUtils.toast("最多只能同时下载三个任务，请稍等")
                ButtonStyle.DOWNLOADING_NORMAL, ButtonStyle.DOWNLOADING_PLUGIN -> {
                    if (mDownloadEntity == null) {
                        mDownloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(mGameEntity)
                    }
                    if (mDownloadEntity != null) {
                        if (downloadButton.text.contains(mPausedText)) {
                            DownloadManager.getInstance().resume(mDownloadEntity, false)
                        } else {
                            DownloadManager.getInstance().pause(mDownloadEntity!!.url)
                            downloadButton.text =
                                "${DetailDownloadUtils.getValidProgress(mDownloadEntity)}% $mPausedText"
                        }
                    }
                }

                else -> if (mGameEntity.getApk().isNotEmpty()) {
                    val intent = DownloadManagerActivity.getDownloadMangerIntent(
                        mViewHolder.context,
                        mGameEntity.getApk().firstOrNull()?.url,
                        StringUtils.buildString(mEntrance, "+(", mName, "[", mTitle, "])")
                    )
                    mViewHolder.context.startActivity(intent)
                }
            }
        }

        private fun showOffServiceDialog(dialog: GameEntity.Dialog?, callback: () -> Unit) {
            val dialogFragment = GameOffServiceDialogFragment.getInstance(dialog!!, callback)
            dialogFragment.show((mViewHolder.context as FragmentActivity).supportFragmentManager, "off_service_dialog")
        }

        private fun download(asVGame: Boolean, isSubscribe: Boolean) {
            var buttonText = mViewHolder.downloadPb.text

            if (buttonText.isEmpty()) buttonText = mViewHolder.overlayTv?.text.toString()

            if (mGameEntity.getApk().size == 0) {
                ToastUtils.toast("暂时无法下载，请稍后再试")
                return
            }
            val apkEntity = mGameEntity.getApk().firstOrNull()
            val msg = FileUtils.isCanDownload(mViewHolder.context, apkEntity?.size ?: "")
            if (TextUtils.isEmpty(msg)) {
                val btnContainsUpdateText =
                    mViewHolder.context.getString(com.gh.gamecenter.feature.R.string.update_v) == buttonText
                            || buttonText.contains(mViewHolder.context.getString(com.gh.gamecenter.feature.R.string.update))

                if (asVGame && btnContainsUpdateText) {
                    VHelper.updateOrReDownload(mGameEntity)
                } else {
                    DownloadManager.createDownload(
                        mViewHolder.context,
                        apkEntity,
                        mGameEntity,
                        asVGame,
                        mGameEntity.isDualBtnModeEnabled(),
                        StringUtils.buildString(mEntrance, "+(", mName, "[", mTitle, "])"),
                        "$mName:$mTitle",
                        isSubscribe,
                        mTraceEvent
                    )
                }
                mViewHolder.downloadPb.progress = 0
                mViewHolder.downloadPb.buttonStyle =
                    if (buttonText.contains("插件化")) ButtonStyle.DOWNLOADING_PLUGIN else ButtonStyle.DOWNLOADING_NORMAL
                DeviceRemindDialog.showDeviceRemindDialog(mViewHolder.context, mGameEntity)
            } else {
                ToastUtils.toast(msg)
            }
        }

        private fun preDownload() {
            val builder = DownloadChainBuilder()
            builder.addHandler(UnsupportedFeatureHandler())
            builder.addHandler(UpdateNewSimulatorHandler())
            builder.addHandler(GamePermissionHandler())
            builder.addHandler(CheckStoragePermissionHandler())
            builder.addHandler(ValidateVSpaceHandler())
            if (mGameEntity.getApk().size == 1) {
                val downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(mGameEntity)

                // 双按钮下载，且是以另外一种状态进行下载完成的，那么更新它的下载触发源并直接唤起安装
                if (mShowDualDownloadButton
                    && downloadEntity != null
                    && downloadEntity.status == DownloadStatus.done
                    && !FileUtils.isEmptyFile(downloadEntity.path)
                ) {

                    if (downloadEntity.getMetaExtra(Constants.APK_MD5) != mGameEntity.getApk().firstOrNull()?.md5) {
                        // 已下载的 md5 与接口返回的不一样，不使用快速安装功能，重新下载安装
                        DownloadManager.getInstance().cancel(downloadEntity.url)
                    } else if (mAsVGame && downloadEntity.isLocalDownloadInDualDownloadMode()) {
                        runOnIoThread {
                            // 由于不想执行上面的 builder 相关的判断，所以这里还是丑陋的修改 downloadEntity 实体并保存到数据库中
                            downloadEntity.setVGameDownloadModeInDualDownloadMode()
                            DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
                            runOnUiThread {
                                PackageInstaller.install(mViewHolder.context, downloadEntity)
                            }
                        }
                        return
                    } else if (!mAsVGame && downloadEntity.isVGameDownloadInDualDownloadMode()) {
                        runOnIoThread {
                            downloadEntity.setLocalDownloadModeInDualDownloadMode()
                            DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
                            runOnUiThread {
                                PackageInstaller.install(mViewHolder.context, downloadEntity)
                            }
                        }
                        return
                    }
                }

                builder.addHandler(BrowserInstallHandler())
                builder.addHandler(PackageCheckHandler())
                builder.addHandler(DownloadDialogHelperHandler())
                builder.addHandler(VersionNumberHandler())
                builder.addHandler(LandPageAddressHandler())
                builder.addHandler(OverseaDownloadHandler())
                builder.addHandler(CheckDownloadHandler())
                builder.setProcessEndCallback(mGameEntity.id) { asVGame: Boolean, isSubscribe: Any? ->
                    performDownloadClickAction()
                    download(asVGame, isSubscribe as Boolean)
                }
            } else {
                builder.addHandler(VersionNumberHandler())
                builder.setProcessEndCallback(mGameEntity.id) { _: Boolean?, _: Any? ->
                    DownloadDialog.showDownloadDialog(
                        mViewHolder.context,
                        mGameEntity,
                        mTraceEvent,
                        StringUtils.buildString(
                            mEntrance,
                            "+(",
                            mName,
                            "[",
                            mTitle,
                            "])"
                        ),
                        "$mName:$mTitle",
                        onDownloadClickAction
                    )
                }
            }
            val chainHandler = builder.buildHandlerChain()
            chainHandler?.handleRequest(
                mViewHolder.context,
                mGameEntity,
                mAsVGame
            )
        }

        private fun performDownloadClickAction() {
            val buttonText = if (mShowDualDownloadButton && !mAsVGame) {
                mViewHolder.localDownloadTitleTv?.text?.ifEmpty {
                    mViewHolder.downloadPb.text.ifEmpty {
                        mViewHolder.overlayTv?.text ?: ""
                    }
                }
            } else {
                mViewHolder.downloadPb.text.ifEmpty { mViewHolder.overlayTv?.text ?: "" }
            }
            val isUpdate =
                buttonText?.contains(mViewHolder.context.getString(com.gh.gamecenter.feature.R.string.update)) == true
            onDownloadClickAction?.invoke(isUpdate)
        }
    }
}
