package com.gh.gamecenter.home

import android.annotation.SuppressLint
import android.app.Application
import android.text.TextUtils
import androidx.collection.ArrayMap
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.MediatorLiveData
import androidx.lifecycle.MutableLiveData
import com.gh.common.filter.RegionSettingHelper
import com.gh.common.util.*
import com.gh.download.DownloadManager
import com.gh.gamecenter.BuildConfig
import com.gh.gamecenter.common.baselist.LoadStatus
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.common.utils.observableToMain
import com.gh.gamecenter.core.runOnIoThread
import com.gh.gamecenter.core.utils.RandomUtils
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.entity.*
import com.gh.gamecenter.game.rank.RankCollectionAdapter
import com.gh.gamecenter.gamecollection.square.GameCollectionListItemData
import com.gh.gamecenter.packagehelper.PackageRepository
import com.gh.gamecenter.retrofit.RetrofitManager
import com.gh.vspace.VGameItemData
import com.gh.vspace.VHelper
import com.halo.assistant.HaloApp
import com.lightgame.download.DownloadEntity
import com.lightgame.utils.Utils
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import retrofit2.HttpException
import kotlin.collections.set
import kotlin.math.roundToInt

class HomeViewModel(application: Application) : AndroidViewModel(application) {

    private val mApi = RetrofitManager.getInstance().api

    private var mSnapshotItemList = ArrayList<HomeItemData>()
    private val mSubjectChangedMap: ArrayMap<String, List<GameEntity>> = ArrayMap() // 存储换一换的数据

    private var mHomeSlides = ArrayList<HomeSlide>()
    private var mHomeRecommends = ArrayList<HomeRecommend>()
    private var mHomeContents = ArrayList<HomeContent>()
    private var mPluginList: List<GameEntity>? = null // 插件化
    private var mSmartSubject: SubjectEntity? = null // 智能推荐专题
    private var mVGameList: ArrayList<VGameItemData>? = null // 最近的畅玩游戏
    private var mDiscoveryGameCard: DiscoveryGameCardEntity? = null
    private var mDiscoveryGameCardLabels: List<DiscoveryGameCardLabel>? = null

    private var mContentPage = 1 // 专题分页
    private var mIsLoading = false
    private var mShouldLogReplaceEvent = true // 是否需要记录启动时的专题游戏替换事件
    private var mIsDiscoveryDataLoading = false // 是否正在获取发现页数据

    // 所有专题里的所有游戏 ID 集合，供替换时排重用
    private var mSubjectGameIdList = hashSetOf<String>()

    // 首页是否只有首页，不显示其它 tab
    var homeOnlyWithoutOtherTab = false

    var itemDataList: MediatorLiveData<List<HomeItemData>> = MediatorLiveData()
    private var mPositionAndPackageMap = HashMap<String, Int>() // key: packageName + position, value: position
    var positionAndPackageMap = MutableLiveData<HashMap<String, Int>>()

    val loadStatus = MutableLiveData<LoadStatus>()

    init {
        itemDataList.addSource(PackageRepository.gameUpdateLiveData) {
            initPlugin(it)
            refreshRecentVGameIfNeeded()
        }
        itemDataList.addSource(DownloadManager.getInstance().downloadEntityLiveData) {
            refreshRecentVGameIfNeeded()
        }

        loadStatus.postValue(LoadStatus.INIT_LOADING)
    }

    fun initData(homeDataEntity: HomeDataEntity?) {
        mHomeSlides = arrayListOf()
        mHomeRecommends = arrayListOf()
        mHomeContents = arrayListOf()
        mSubjectGameIdList = hashSetOf()

        homeDataEntity?.let {
            mHomeSlides.addAll(it.homeSlide)
            mHomeRecommends.addAll(it.homeRecommend)
            mHomeContents.addAll(it.homeContent)
            transformationItemData(mHomeContents)
            mContentPage = 2
            loadStatus.postValue(LoadStatus.INIT_LOADED)
        }

        // 触发列表刷新行为时亦刷新内存中的备用游戏库列表
        GameSubstituteRepositoryHelper.refreshRepositoryFromLocal()

        if (SPUtils.getBoolean(Constants.SP_PERSONAL_RECOMMEND, true)) {
            getSmartColumn()
        }

        refreshRecentVGameIfNeeded()
    }

    fun refreshRecentVGameIfNeeded() {
        if (VHelper.isVGameOn()
            && SPUtils.getBoolean(Constants.SP_HOME_VGAME_AREA_ENABLED, true)
        ) {
            val entityList = getSortedVEntityList()

            if (entityList.isNotEmpty()) {
                mVGameList = ArrayList(entityList)

                if (mHomeSlides.isNotEmpty() || mHomeRecommends.isNotEmpty()) {
                    transformationItemData(mHomeContents)
                }
            } else {
                mVGameList?.clear()
                transformationItemData(mHomeContents)
            }
        } else {
            mVGameList?.clear()
            transformationItemData(mHomeContents)
        }
    }

    /**
     * 获取排好序的最近在玩列表
     *
     * 首位：固定展示最近一次点击过下载\启动的游戏
     * 后续位置-优先级：完成下载但未启动过的游戏 > 完成下载且已启动过的游戏
     *         完成下载但未启动过的游戏：按照点击下载的时间倒序排列
     *         完成下载且已启动过的游戏：按照游戏的畅玩时长从左（长）向右（短）排列
     */
    private fun getSortedVEntityList(): List<VGameItemData> {
        val rawDownloadEntityList = DownloadManager.getInstance().allVDownloadTaskSnapshots
        val rawInstalledEntityList = VHelper.getAllVGameSnapshots()
        val rawEntityList = arrayListOf<DownloadEntity>()

        var fixedTopEntity: VGameItemData? = null
        val unplayedEntityList = arrayListOf<VGameItemData>()
        val playedEntityList = arrayListOf<VGameItemData>()
        val sortedEntityList = arrayListOf<VGameItemData>()

        val distinctIdSet = hashSetOf<String>()
        // 将下载任务的实体放进待排序列表里
        for (rawDownloadEntity in rawDownloadEntityList) {
            distinctIdSet.add(rawDownloadEntity.gameId)
            rawEntityList.add(rawDownloadEntity)
        }
        // 将已安装任务的实体放进待排序列表里
        for (rawInstalledEntity in rawInstalledEntityList) {
            if (distinctIdSet.contains(rawInstalledEntity.downloadEntity.gameId)) {
                continue
            }
            rawEntityList.add(rawInstalledEntity.downloadEntity)
        }
        distinctIdSet.clear()

        for (rawEntity in rawEntityList) {
            val lastPlayedTime = VHelper.getLastPlayedTime(rawEntity)
            val latestModifiedTime = maxOf(rawEntity.start, VHelper.getLastPlayedTime(rawEntity))

            if (fixedTopEntity == null) {
                fixedTopEntity = VGameItemData.from(rawEntity)
            } else {
                val fixedTopLatestModifiedTime =
                    maxOf(fixedTopEntity.downloadEntity.start, VHelper.getLastPlayedTime(fixedTopEntity.downloadEntity))
                if (latestModifiedTime > fixedTopLatestModifiedTime) {
                    fixedTopEntity = VGameItemData.from(rawEntity)
                }
            }

            if (lastPlayedTime == 0L) {
                unplayedEntityList.add(VGameItemData.from(rawEntity))
            } else {
                playedEntityList.add(VGameItemData.from(rawEntity))
            }
        }

        fixedTopEntity?.let {
            sortedEntityList.add(it)
            unplayedEntityList.removeAll { entity ->
                entity.downloadEntity.packageName == fixedTopEntity.downloadEntity.packageName
            }
            playedEntityList.removeAll { entity ->
                entity.downloadEntity.packageName == fixedTopEntity.downloadEntity.packageName
            }
        }
        sortedEntityList.addAll(unplayedEntityList.sortedByDescending { it.downloadEntity.start })
        sortedEntityList.addAll(playedEntityList.sortedByDescending { VHelper.getTotalPlayedTime(it.downloadEntity.packageName) })

        return sortedEntityList.take(8)
    }

    private fun initPlugin(updateList: List<GameUpdateEntity>?) {
        if (updateList == null) return

        val list = ArrayList<GameEntity>()
        for (update in updateList) {
            if (update.isPluggable && update.indexPlugin == "open" && update.isShowPlugin(PluginLocation.only_index)) {
                val game = update.transformGameEntity()
                if (HomePluggableHelper.showHomePluggable(game)) {
                    list.add(game)
                }
            }
        }
        for (game in list) {
            game.setEntryMap(DownloadManager.getInstance().getEntryMap(game.name))
        }

        // 下载7天排序
        list.sortWith { o1, o2 -> o2.download - o1.download }

        mPluginList = list
        if (mHomeSlides.isNotEmpty() || mHomeRecommends.isNotEmpty()) {
            transformationItemData(mHomeContents)
        }
    }

    @SuppressLint("CheckResult")
    fun getHomeContent(initData: Boolean) {
        if (mIsLoading && !initData || loadStatus.value == LoadStatus.LIST_OVER) return
        mIsLoading = true

        if (initData) {
            mContentPage = 1
        } else {
            loadStatus.postValue(LoadStatus.LIST_LOADING)
        }

        mApi.getHomeContents(HaloApp.getInstance().channel, BuildConfig.VERSION_NAME, mContentPage)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : BiResponse<List<HomeContent>>() {
                override fun onSuccess(data: List<HomeContent>) {
                    mHomeContents.addAll(data)
                    transformationItemData(mHomeContents)
                    mContentPage++
                    mIsLoading = false

                    when {
                        data.isEmpty() -> loadStatus.postValue(LoadStatus.LIST_OVER)
                        initData -> loadStatus.postValue(LoadStatus.INIT_LOADED)
                        else -> loadStatus.postValue(LoadStatus.LIST_LOADED)
                    }
                }

                override fun onFailure(exception: Exception) {
                    transformationItemData(mHomeContents)
                    mIsLoading = false

                    if (initData && mHomeSlides.isEmpty() && mHomeRecommends.isEmpty()) {
                        loadStatus.postValue(LoadStatus.INIT_FAILED)
                    } else {
                        loadStatus.postValue(LoadStatus.LIST_FAILED)
                    }
                }
            })
    }

    private fun getSmartColumn() {
        mApi.homeSmartColumn
            .map {
                it.data = RegionSettingHelper.filterGame(it.data)
                val gameList = it.data
                if (gameList != null) {
                    for (game in gameList) {
                        ApkActiveUtils.filterHideApk(game)
                    }
                }
                it
            }
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : Response<SubjectEntity>() {
                override fun onResponse(response: SubjectEntity?) {
                    mSmartSubject = response
                }
            })
    }

    fun changeSubjectGame(subjectId: String) {
        val list = mSubjectChangedMap[subjectId]
        if (list != null) {
            initRandomGame(subjectId, ArrayList(list))
        } else {
            getChangeSubjectGame(subjectId)
        }
    }

    private fun getDiscoverCardData() {
        val paramsMap = if (SPUtils.getBoolean(Constants.SP_DISCOVER_FORCE_REFRESH)) {
            mapOf("refresh" to "true")
        } else {
            mapOf()
        }
        val discoveryGamesObservable = mApi.getDiscoveryGames(1, paramsMap).compose(observableToMain())
        val cardLabelsObservable = mApi.cardLabels.compose(observableToMain())
        when {
            mDiscoveryGameCard == null && mDiscoveryGameCardLabels == null -> {
                Observable.mergeDelayError(cardLabelsObservable, discoveryGamesObservable)
                    .subscribe(object : Response<Any>() {
                        override fun onNext(response: Any) {
                            when (response) {
                                is ArrayList<*> -> mDiscoveryGameCardLabels =
                                    response as ArrayList<DiscoveryGameCardLabel>
                                is DiscoveryGameCardEntity -> mDiscoveryGameCard =
                                    response.apply {
                                        SPUtils.setBoolean(Constants.SP_DISCOVER_FORCE_REFRESH, false)
                                    }
                            }
                        }

                        override fun onFailure(e: HttpException?) {
                            mIsDiscoveryDataLoading = false
                        }

                        override fun onComplete() {
                            mIsDiscoveryDataLoading = false
                            filterDiscoverGames()
                            filterDiscoveryLabel()
                            transformationItemData(mHomeContents)
                        }
                    })
            }
            mDiscoveryGameCard == null -> {
                discoveryGamesObservable.compose(observableToMain())
                    .subscribe(object : Response<DiscoveryGameCardEntity>() {
                        override fun onResponse(response: DiscoveryGameCardEntity?) {
                            mIsDiscoveryDataLoading = false
                            SPUtils.setBoolean(Constants.SP_DISCOVER_FORCE_REFRESH, false)
                            mDiscoveryGameCard = response
                            filterDiscoverGames()
                            filterDiscoveryLabel()
                            transformationItemData(mHomeContents)
                        }
                    })
            }
            mDiscoveryGameCardLabels == null -> {
                cardLabelsObservable.compose(observableToMain())
                    .subscribe(object : Response<ArrayList<DiscoveryGameCardLabel>>() {
                        override fun onResponse(response: ArrayList<DiscoveryGameCardLabel>?) {
                            mIsDiscoveryDataLoading = false
                            mDiscoveryGameCardLabels = response
                            filterDiscoveryLabel()
                            transformationItemData(mHomeContents)
                        }
                    })
            }
        }
    }

    fun refreshDiscoverCardData() {
        if (mDiscoveryGameCard != null) {
            val paramsMap = if (SPUtils.getBoolean(Constants.SP_DISCOVER_FORCE_REFRESH)) {
                mapOf("refresh" to "true")
            } else {
                mapOf()
            }
            val discoveryGamesObservable = mApi.getDiscoveryGames(1, paramsMap).compose(observableToMain())
            val cardLabelsObservable = mApi.cardLabels.compose(observableToMain())
            Observable.mergeDelayError(cardLabelsObservable, discoveryGamesObservable)
                .subscribe(object : Response<Any>() {
                    override fun onNext(response: Any) {
                        when (response) {
                            is ArrayList<*> -> mDiscoveryGameCardLabels =
                                response as ArrayList<DiscoveryGameCardLabel>
                            is DiscoveryGameCardEntity -> mDiscoveryGameCard =
                                response.apply {
                                    SPUtils.setBoolean(Constants.SP_DISCOVER_FORCE_REFRESH, false)
                                }
                        }
                    }

                    override fun onComplete() {
                        filterDiscoverGames()
                        filterDiscoveryLabel()
                        transformationItemData(mHomeContents)
                    }
                })
        }
    }

    // 在保证游戏数量不少于18情况下过滤掉已安装游戏
    private fun filterDiscoverGames() {
        mDiscoveryGameCard?.run {
            val tempList = arrayListOf<GameEntity>()
            tempList.addAll(games)
            var i = 0
            // 删除已安装的游戏
            while (i < tempList.size) {
                val gameEntity = tempList[i]
                if (gameEntity.getApk().isNotEmpty() && PackageUtils.isInstalled(
                        HaloApp.getInstance().application,
                        gameEntity.getApk()[0].packageName
                    )
                ) {
                    tempList.removeAt(i)
                    i--
                }
                i++
            }
            games = if (tempList.size >= 18) {
                ArrayList(tempList.take(18))
            } else {
                ArrayList(games.take(18))
            }
        }
    }

    // 过滤分组，现只需要"卡片一"分组
    private fun filterDiscoveryLabel() {
        mDiscoveryGameCardLabels = mDiscoveryGameCardLabels?.filter { it.card == "卡片一" }
        // 如果link_type为空需要在mUserTags/mGameTags中依次获取
        val gameTags = mDiscoveryGameCard?.gameTags
        val userTags = mDiscoveryGameCard?.userTags
        var gameTagIndex = 0
        var userTagIndex = 0
        mDiscoveryGameCardLabels?.forEach { label ->
            if (!userTags.isNullOrEmpty() && userTags.size > userTagIndex && label.type.isNullOrEmpty()) {
                val userTag = userTags[userTagIndex]
                label.link = userTag.id
                label.type = "tag"
                label.linkText = userTag.name
                label.title = userTag.name
                userTagIndex++
            } else if (!gameTags.isNullOrEmpty() && gameTags.size > gameTagIndex && label.type.isNullOrEmpty()) {
                val gameTag = gameTags[gameTagIndex]
                label.link = gameTag.link
                label.type = gameTag.type
                label.linkText = gameTag.linkText
                label.title = gameTag.linkText
                gameTagIndex++
            }
        }
    }

    //换一批
    private fun getChangeSubjectGame(subjectId: String) {
        mApi
            .getSubjectGame(subjectId)
            .map(RegionSettingHelper.filterGame)
            .map(ApkActiveUtils.filterMapperList)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : Response<List<GameEntity>>() {
                override fun onResponse(response: List<GameEntity>?) {
                    if (response != null) {
                        mSubjectChangedMap[subjectId] = response
                        initRandomGame(subjectId, java.util.ArrayList(response))
                    }
                }

                override fun onFailure(e: HttpException?) {
                    Utils.toast(getApplication(), "网络异常")
                }
            })

    }

    // 随机产生专题数据(换一换)
    private fun initRandomGame(subjectId: String, sourceList: List<GameEntity>?) {
        var rawList: MutableList<GameEntity>? = null
        for (entity in mHomeContents) {
            if (entity.linkColumn?.id == subjectId) rawList = entity.linkColumn.data
        }
        if (rawList == null) return

        var sourceList = sourceList

        var size = rawList.size // 判断是否有大图

        var i = 0
        while (i < rawList.size) { //删除原数据，排除大图
            if (TextUtils.isEmpty(rawList[i].image)) {
                rawList.removeAt(i)
                i--
            } else {
                size--
            }
            i++
        }

        if (size * 2 <= sourceList!!.size) {
            sourceList = GameUtils.removeDuplicateData(rawList, sourceList)//排除重复
        }

        val indexes = RandomUtils.getRandomArray(size, sourceList!!.size)
        for (index in indexes) {
            val gameEntity = sourceList[index]
            rawList.add(gameEntity)
        }
        transformationItemData(mHomeContents)
    }

    fun transformationItemData(homeContents: ArrayList<HomeContent>) {
        runOnIoThread(true) {
            mSnapshotItemList.clear()

            // 是否使用带特别高的带分割线的 item
            var useUltraHeightDivider = false
            var shouldShowDivider = false

            val iterator = homeContents.iterator()
            while (iterator.hasNext()) {
                val item = iterator.next()
                // 裁剪排行榜数据数量
                if (item.linkType == "column_collection" && item.linkColumn?.style == "top") {
                    item.linkColumn.columns.let { columns ->
                        for (column in columns) {
                            column.data =
                                ArrayList(column.data?.take(RankCollectionAdapter.MAX_RANK_ITEM_COUNT) ?: listOf())
                        }
                    }
                }

                // 双列卡片专题过滤掉无封面图游戏
                if (item.linkType == "column" && item.linkColumn?.type == "game_double_card") {
                    item.linkColumn.data = item.linkColumn.data?.filter { it.columnImage.isNotBlank() }?.toMutableList()
                    // 游戏数量小于2个不显示专题，所以直接去掉
                    if ((item.linkColumn.data?.size ?: 0) < 2) {
                        iterator.remove()
                    }
                }
            }

            if (mSmartSubject != null && homeContents.size > mSmartSubject!!.sort) {
                val element = HomeContent(
                    linkType = "smart_subject",
                    linkId = mSmartSubject?.id ?: "",
                    linkText = mSmartSubject?.name ?: "",
                    linkColumn = mSmartSubject
                )
                homeContents.add(mSmartSubject!!.sort, element)
                mSmartSubject = null // 防止重复插入
            }

            if (mHomeSlides.isNotEmpty()) {
                val slideItem = HomeItemData()
                slideItem.slides = mHomeSlides
                mSnapshotItemList.add(slideItem)
            }

            if (mHomeRecommends.isNotEmpty()) {
                val recommend = HomeItemData()
                recommend.recommends = mHomeRecommends
                mSnapshotItemList.add(recommend)
            }

            // 最近在玩的畅玩游戏
            if (mVGameList != null && !mVGameList.isNullOrEmpty()) {
                val item = HomeItemData()
                item.recentVGame = mVGameList
                mSnapshotItemList.add(item)

                for (entity in mVGameList!!) {
                    val packageName = entity.downloadEntity.packageName
                    mPositionAndPackageMap[packageName + (mSnapshotItemList.size - 1)] = mSnapshotItemList.size - 1
                }
            }

            // 插件化
            if (mPluginList != null && mPluginList!!.isNotEmpty()) {
                val plugin = HomeItemData()
                plugin.pluginList = mPluginList
                mSnapshotItemList.add(plugin)

                for (entity in mPluginList!!) {
                    addGamePositionAndPackage(entity)
                }
            }

            for (i in 0 until homeContents.size) {
                val homeContent = homeContents[i]
                val linkType = homeContent.linkType
                val linkStyle = homeContent.linkColumn?.style ?: ""
                val adIconActive = homeContent.adIconActive

                if (i + 1 < homeContents.size) {
                    val nextItem = homeContents[i + 1]
                    shouldShowDivider = nextItem.linkType == "game" || nextItem.linkType == "video"
                }

                if (linkType == "game" || linkType == "video") {
                    val attachGame = HomeItemData()
                    attachGame.blockPosition = i
                    attachGame.attachGame = homeContent
                    attachGame.attachGame?.linkGame?.outerSequence = attachGame.blockPosition
                    attachGame.attachGame?.linkGame?.sequence = attachGame.blockPosition
                    attachGame.attachGame?.linkGame?.isAdData = adIconActive
                    mSnapshotItemList.add(attachGame)
                    homeContent.linkGame?.let {
                        addGamePositionAndPackage(it)
                    }
                } else if (linkType == "top_game_comment") {
                    val head = HomeItemData()
                    head.columnHead = SubjectEntity(
                        type = linkType,
                        name = "安利墙",
                        adIconActive = homeContent.linkColumn?.adIconActive ?: false
                    )
                    mSnapshotItemList.add(LegacyHomeSubjectTransformer.getBlankSpacingItem(HomeItemData()) as HomeItemData)
                    mSnapshotItemList.add(head)

                    val amway = HomeItemData()
                    amway.blockPosition = i
                    amway.amway = homeContent.linkTopGameComment?.apply {
                        for ((index, amwayEntity) in this.withIndex()) {
                            amwayEntity.game.sequence = index
                            amwayEntity.game.outerSequence = i
                        }
                    }
                    mSnapshotItemList.add(amway)
                } else if (linkType == "column"
                    || linkType == "column_collection" && linkStyle != "top"
                    || linkType == "smart_subject"
                    || linkType == "column_test"
                ) {

                    homeContent.linkColumn?.data = RegionSettingHelper.filterGame(homeContent.linkColumn?.data)

                    homeContent.linkColumn?.let { subjectEntity ->
                        subjectEntity.data?.let { data ->
                            // 这个 for 循环主要功能是用来标识替换已安装的游戏
                            for (game in data) {
                                mSubjectGameIdList.add(game.id)
                                // 应用专题是否显示游戏名后缀的配置
                                game.shouldShowNameSuffix = subjectEntity.showSuffix
                            }

                            subjectEntity.relatedColumnId?.let {
                                GameSubstituteRepositoryHelper.replaceGames(
                                    data,
                                    mSubjectGameIdList,
                                    it,
                                    mShouldLogReplaceEvent
                                )
                                mShouldLogReplaceEvent = false
                            }
                        }
                    }

                    // 仅普通纵向专题需要特别高的分割线
                    useUltraHeightDivider = homeContent.linkColumn?.type == "game_vertical"

                    homeContent.linkColumn?.adIconActive = homeContent.adIconActive
                    LegacyHomeSubjectTransformer.transform(
                        mSnapshotItemList as ArrayList<LegacyHomeItemData>,
                        homeContent.linkColumn,
                        i,
                        { HomeItemData() },
                        { addGamePositionAndPackage(it) }
                    )
                } else if (linkType == "column_collection" && linkStyle == "top") {
                    val rankItem = HomeItemData().apply {
                        blockPosition = i
                        rankCollection = homeContent.linkColumn
                    }
                    mSnapshotItemList.add(rankItem)
                    appendAdditionalInfoToRankSubjectGame(homeContent.linkColumn, i)
                } else if (linkType == "common_collection") {
                    val subjectEntity = SubjectEntity().apply {
                        type = homeContent.linkType
                        id = homeContent.linkId
                        name = homeContent.linkText
                        style = homeContent.commonCollection?.style
                        homePageStyle = homeContent.commonCollection?.homePageStyle ?: ""
                        verticalLine = homeContent.commonCollection?.verticalLine ?: ""
                        commonCollectionList = homeContent.commonCollection?.collectionList
                        this.adIconActive = adIconActive
                    }
                    val head = HomeItemData()
                    head.columnHead = subjectEntity
                    mSnapshotItemList.add(LegacyHomeSubjectTransformer.getBlankSpacingItem(HomeItemData()) as HomeItemData)
                    mSnapshotItemList.add(head)
                    if (homeContent.commonCollection?.homePageStyle == "1-2") {
                        // 样式为一行两个的时候把数据拆分为若干个一行两个的小item，根据 offset 来在原数据中的获取数据
                        var lineCount = (((subjectEntity.commonCollectionList?.size ?: 0).toDouble()) / 2).roundToInt()
                        if (!TextUtils.isEmpty(subjectEntity.verticalLine)) {
                            val serverSideLineCount = subjectEntity.verticalLine.toInt()
                            if (lineCount == 0 || serverSideLineCount < lineCount) {
                                lineCount = serverSideLineCount
                            }
                        }

                        for (line in 0 until lineCount) {
                            if (line == 0) {
                                mSnapshotItemList.add(HomeItemData().apply { blankDivider = 12F })
                            } else if (subjectEntity.style == "img-list") {
                                mSnapshotItemList.add(HomeItemData().apply { blankDivider = 12F })
                            }

                            val itemDataSubject = HomeItemData()
                            itemDataSubject.commonCollection12 = subjectEntity
                            itemDataSubject.blockPosition = i
                            itemDataSubject.offset = if (line == 0) 0 else line * 2
                            mSnapshotItemList.add(itemDataSubject)
                        }
                    } else {
                        val commonCollectionItem = HomeItemData()
                        commonCollectionItem.commonCollection = subjectEntity
                        commonCollectionItem.blockPosition = i
                        mSnapshotItemList.add(commonCollectionItem)
                    }
                } else if (linkType == "game_list_collection") {
                    val head = HomeItemData()
                    head.columnHead =
                        SubjectEntity(type = linkType, name = homeContent.linkText, adIconActive = adIconActive)
                    mSnapshotItemList.add(LegacyHomeSubjectTransformer.getBlankSpacingItem(HomeItemData()) as HomeItemData)
                    mSnapshotItemList.add(head)

                    val gameCollection = HomeItemData()
                    gameCollection.blockPosition = i
                    val itemDataList = arrayListOf<GameCollectionListItemData>().apply {
                        if (!homeContent.linkGameCollection.isNullOrEmpty()) {
                            var position = 0
                            for (item in homeContent.linkGameCollection) {
                                add(GameCollectionListItemData(gameCollectionItem = item, gameStartPosition = position))
                                position += if (item.count?.game!! > 2) 3 else if (item.games?.size == 0) 0 else item.count?.game
                                    ?: 0
                            }
                        }
                    }
                    gameCollection.gameCollection = itemDataList
                    mSnapshotItemList.add(gameCollection)
                } else if (linkType == "community_article"
                    || linkType == "question"
                    || linkType == "bbs_video"
                    || linkType == "news"
                ) {
                    val homeItemData = HomeItemData().apply {
                        blockPosition = i
                        bigImageRecommend = SubjectEntity(
                            id = homeContent.linkId,
                            type = homeContent.linkType,
                            image = homeContent.image,
                            firstLineRecommend = homeContent.firstLineRecommend,
                            secondLineRecommend = homeContent.secondLineRecommend,
                            recommendTag = homeContent.recommendTag,
                            columnName = homeContent.linkText
                        )
                    }
                    mSnapshotItemList.add(LegacyHomeSubjectTransformer.getBlankSpacingItem(HomeItemData()) as HomeItemData)
                    mSnapshotItemList.add(homeItemData)
                } else if (linkType == "game_explore") {
                    if (mDiscoveryGameCard == null || mDiscoveryGameCardLabels == null) {
                        if (!mIsDiscoveryDataLoading) {
                            mIsDiscoveryDataLoading = true
                            getDiscoverCardData()
                        }
                    } else {
                        val homeItemData = HomeItemData().apply {
                            blockPosition = i
                            discoverCard = DiscoveryCardEntity(
                                mDiscoveryGameCard?.games ?: arrayListOf(),
                                mDiscoveryGameCardLabels ?: listOf()
                            )
                        }
                        mSnapshotItemList.add(homeItemData)
                        mDiscoveryGameCard?.games?.forEach {
                            addGamePositionAndPackage(it)
                        }
                    }
                } else {
                    val unknown = HomeItemData()
                    unknown.blockPosition = i + 1
                    unknown.unknownData = ""
                    mSnapshotItemList.add(unknown)
                }

                if (i != 0 && shouldShowDivider) {
                    if (useUltraHeightDivider) {
                        useUltraHeightDivider = false
                        mSnapshotItemList.add(HomeItemData(lineDivider = ULTRA_HEIGHT_DIVIDER))
                    } else {
                        mSnapshotItemList.add(HomeItemData(lineDivider = DEFAULT_DIVIDER))
                    }
                    shouldShowDivider = false
                }
            }
            positionAndPackageMap.postValue(HashMap(mPositionAndPackageMap))
            itemDataList.postValue(ArrayList(mSnapshotItemList))
        }
    }

    private fun addGamePositionAndPackage(game: GameEntity) {
        var packages = ""
        for (apkEntity in game.getApk()) {
            packages += apkEntity.packageName
        }
        mPositionAndPackageMap[packages + (mSnapshotItemList.size - 1)] = mSnapshotItemList.size - 1
        game.gameLocation = GameEntity.GameLocation.INDEX
        game.setEntryMap(DownloadManager.getInstance().getEntryMap(game.name))
    }

    private fun appendAdditionalInfoToRankSubjectGame(subject: SubjectEntity?, outerPosition: Int) {
        subject?.columns?.forEach {
            it.data?.forEachIndexed { index, game ->
                if (subject.tag != "test") {
                    game.subjectId = subject.id
                }
                game.sequence = index
                game.outerSequence = outerPosition
                addGamePositionAndPackage(game)
            }
        }
    }

    companion object {
        const val DEFAULT_DIVIDER = 1F
        const val ULTRA_HEIGHT_DIVIDER = 8F
    }

}