package com.gh.gamecenter.home.custom.model

import com.gh.common.util.ViewPagerFragmentHelper
import com.gh.gamecenter.common.entity.LinkEntity
import com.gh.gamecenter.common.entity.PKEntity
import com.gh.gamecenter.common.exposure.ExposureSource
import com.gh.gamecenter.core.utils.TimeUtils
import com.gh.gamecenter.entity.AmwayCommentEntity
import com.gh.gamecenter.entity.DiscoveryCardEntity
import com.gh.gamecenter.entity.HomeItemTestV2Entity
import com.gh.gamecenter.entity.SubjectEntity
import com.gh.gamecenter.feature.entity.AcctRecord
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.vspace.VGameItemData

abstract class CustomPageItem(
    // 当前模块在数据列表中的位置（注意：非ui页面的位置，而是数据列表中的位置，因为某条数据可能会拆分成多个item）
    val link: LinkEntity,
    var position: Int,
    val componentPosition: Int
) {

    abstract val itemType: Int

    val componentName: String
        get() = componentTypeToName[link.type] ?: ""

    open val componentStyle: String
        get() = ""

    /**
     * 是否需要显示下载按钮
     */
    val shouldShowDownloadButton: Boolean
        get() = shouldShowDownloadButtonItemTypes.contains(itemType)
                || (checkShowDownloadButtonItemTypes.contains(itemType) && showDownload)

    protected open val showDownload: Boolean
        get() = false


    /**
     * 当前模块中包含的游戏)
     * Note：只有需要显示游戏下载按钮的模块需要调用此方法
     */
    val showDownloadGames: List<GameEntity>
        get() {
            return if (shouldShowDownloadButton) {
                games
            } else {
                emptyList()
            }
        }

    protected open val games: List<GameEntity>
        get() = emptyList()

    var exposureEvent: ExposureEvent? = null

    var exposureEventList: ArrayList<ExposureEvent> = arrayListOf()

    fun areItemsTheSame(other: CustomPageItem): Boolean =
        itemType == other.itemType
                && doAreItemsTheSame(other)

    fun areContentsTheSame(other: CustomPageItem): Boolean =
        itemType == other.itemType
                && doAreContentsTheSames(other)

    open fun doAreItemsTheSame(other: CustomPageItem): Boolean = true

    open fun doAreContentsTheSames(other: CustomPageItem) =
        this == other

    companion object {
        const val CUSTOM_LINK_TYPE_GAME = "game"
        const val CUSTOM_LINK_TYPE_COLUMN = "column"
        const val CUSTOM_LINK_TYPE_ARTICLE = "article"
        const val CUSTOM_LINK_TYPE_COMMUNITY_ARTICLE = "community_article"
        const val CUSTOM_LINK_TYPE_VIDEO = "video"
        const val CUSTOM_LINK_TYPE_QUESTION = "question"
        const val CUSTOM_LINK_TYPE_PLUGIN_AREA = "plugin_area"
        const val CUSTOM_LINK_TYPE_CWZS_RECENTLY_PLAYED = "cwzs_recently_played"
        const val CUSTOM_LINK_TYPE_QQ_GAME_RECENTLY_PLAYED = "qq_game_recently_played"
        const val CUSTOM_LINK_TYPE_WECHAT_GAME_RECENTLY_PLAYED = "wechat_game_recently_played"
        const val CUSTOM_LINK_TYPE_ACCELERATOR_RECENTLY_PLAYED = "accelerator_recently_played"
        const val CUSTOM_LINK_TYPE_QQ_MINI_GAME_COLUMN_DETAIL = ViewPagerFragmentHelper.TYPE_QQ_MINI_GAME_COLUMN
        const val CUSTOM_LINK_TYPE_WECHAT_MINI_GAME_COLUMN_DETAIL = ViewPagerFragmentHelper.TYPE_WECHAT_GAME_COLUMN
        const val CUSTOM_LINK_TYPE_WECHAT_WECHAT_GAME_CPM_COLUMN_DETAIL =
            ViewPagerFragmentHelper.TYPE_WECHAT_GAME_CPM_COLUMN
        const val CUSTOM_LINK_TYPE_HALO_RECOMMEND = "halo_recommend"
        const val CUSTOM_LINK_TYPE_COLUMN_COLLECTION = "column_collection"  // 专题合集
        const val CUSTOM_LINK_TYPE_GAME_LIST_COLLECTION = "game_list_collection"
        const val CUSTOM_LINK_TYPE_COLUMN_TEST_V2 = "column_test_v2"
        const val CUSTOM_LINK_TYPE_COMMON_COLLECTION = "common_collection"
        const val CUSTOM_LINK_TYPE_TOP_GAME_COMMENT = "top_game_comment"
        const val CUSTOM_LINK_TYPE_PK = "pk"
        const val CUSTOM_LINK_TYPE_DSP_GAME_COLUMN = "dsp_game_column"

        // 游戏专题
        const val COMPONENTS_GAME_SUBJECT_TYPE_DOUBLE_CARD = "game_double_card"
        const val COMPONENTS_GAME_SUBJECT_TYPE_GAME_VIDEO_HORIZONTAL_SLIDE = "game_video_horizontal_slide"
        const val COMPONENTS_GAME_SUBJECT_TYPE_GAME_VERTICAL = "game_vertical"
        const val COMPONENTS_SUBJECT_TYPE_GAME_VERTICAL_SLIDE = "game_vertical_slide"
        const val COMPONENTS_SUBJECT_TYPE_GAME_HORIZONTAL = "game_horizontal"
        const val COMPONENTS_SUBJECT_TYPE_GAME_HORIZONTAL_SLIDE = "game_horizontal_slide"
        const val COMPONENTS_SUBJECT_TYPE_GAME_TIMELINE_HORIZONTAL_SLIDE = "game_timeline_horizontal_slide"
        const val COMPONENTS_SUBJECT_TYPE_GALLERY = "gallery"
        const val COMPONENTS_SUBJECT_TYPE_GALLERY_SLIDE = "gallery_slide"
        const val COMPONENTS_SUBJECT_TYPE_GAME_FOLD_SLIDE = "game_fold_slide"
        const val COMPONENTS_SUBJECT_TYPE_GAME = "game"
        const val COMPONENTS_SUBJECT_TYPE_GAME_EXPAND = "game_expand"
        const val COMPONENTS_SUBJECT_TYPE_SINGLE_GAME_CARD = "game_single_card"
        const val COMPONENTS_SUBJECT_TYPE_DOUBLE_GAME_WELFARE_CARD = "game_double_welfare_card"
        const val COMPONENTS_SUBJECT_TYPE_GAME_VERTICAL_IMAGE_TEXT = "game_vertical_image_text"

        // 合集
        const val COMPONENTS_COLLECTION_STYLE_RANKING_LIST = "ranking-list"
        const val COMPONENTS_COLLECTION_STYLE_X_SLIDE_CARD = "x-slide-card"
        const val COMPONENTS_COLLECTION_STYLE_X_SLIDE_CARD_SMALL = "x-slide-card-small"
        const val COMPONENTS_COLLECTION_STYLE_REFRESH_SLIDE_LIST = "refresh-slide-list"
        const val COMPONENTS_COLLECTION_STYLE_REFRESH_SLIDE_ICON = "refresh-slide-icon"
        const val COMPONENTS_COLLECTION_STYLE_REFRESH_ICONS_4_2 = "refresh-icons-4x2"
        const val COMPONENTS_COLLECTION_STYLE_REFRESH_X = "refresh-x"
        const val COMPONENTS_COLLECTION_STYLE_REFRESH_Y = "refresh-y"
        const val COMPONENTS_COLLECTION_STYLE_CAROUSEL = "carousel"

        // 通用内用合集
        const val COMMON_CONTENT_COLLECTION_LAYOUT_BANNER = 0
        const val COMMON_CONTENT_COLLECTION_LAYOUT_NAVIGATION = 1
        const val COMMON_CONTENT_COLLECTION_LAYOUT_KING_KONG = 2
        const val COMMON_CONTENT_COLLECTION_LAYOUT_HORIZONTAL_SLIDE_BANNER = 3
        const val COMMON_CONTENT_COLLECTION_LAYOUT_DOUBLE_ROW_BANNER = 4
        const val COMMON_CONTENT_COLLECTION_LAYOUT_HORIZONTAL_VERTICAL_CARD = 5
        const val COMMON_CONTENT_COLLECTION_LAYOUT_DOUBLE_ROW_VERTICAL_CARD = 6
        const val COMMON_CONTENT_COLLECTION_LAYOUT_VERTICAL_IMAGE_TEXT = 7
        const val COMMON_CONTENT_COLLECTION_LAYOUT_HORIZONTAL_IMAGE_TEXT = 8
        const val COMMON_CONTENT_COLLECTION_LAYOUT_CONTENT_LABEL_LANE = 9
        const val COMMON_CONTENT_COLLECTION_LAYOUT_NOTIFICATION_COLUMN = 10
        const val COMMON_CONTENT_COLLECTION_LAYOUT_ANNOUNCEMENT_BANNER = 11
        const val COMMON_CONTENT_COLLECTION_LAYOUT_RECOMMEND_CARD = 12

        const val CUSTOM_PAGE_ITEM_TYPE_INVALID = -2
        const val CUSTOM_PAGE_ITEM_TYPE_FOOTER = -1
        const val CUSTOM_PAGE_ITEM_TYPE_DOUBLE_ROW = 1
        const val CUSTOM_PAGE_ITEM_TYPE_HORIZONTAL_SLIDE_VIDEO_LIST = 2
        const val CUSTOM_PAGE_ITEM_TYPE_GAME_VERTICAL_SLIDE = 3
        const val CUSTOM_PAGE_ITEM_TYPE_GAME_LONG_LIST = 4
        const val CUSTOM_PAGE_ITEM_TYPE_GAME_ICON_MATRIX = 5
        const val CUSTOM_PAGE_ITEM_TYPE_GAME_HORIZONTAL_TIME_LINE = 6
        const val CUSTOM_PAGE_ITEM_TYPE_GAME_HORIZONTAL_ICON_LANE = 7
        const val CUSTOM_PAGE_ITEM_TYPE_GAME_HORIZONTAL_STATIC_GALLERY = 8
        const val CUSTOM_PAGE_ITEM_TYPE_GAME_HORIZONTAL_GALLERY_SLIDE = 9
        const val CUSTOM_PAGE_ITEM_TYPE_GAME_FOLD_SLIDE_LARGE_IMAGE = 10
        const val CUSTOM_PAGE_ITEM_TYPE_GAME_HOME_GAME_ITEM = 11
        const val CUSTOM_PAGE_ITEM_TYPE_RANK_COLLECTION = 12
        const val CUSTOM_PAGE_ITEM_TYPE_SUBJECT_COLLECTION_HORIZONTAL_SLIDE_LARGE_CARD = 13
        const val CUSTOM_PAGE_ITEM_TYPE_SUBJECT_COLLECTION_HORIZONTAL_SLIDE_SMALL_CARD = 14
        const val CUSTOM_PAGE_ITEM_TYPE_SUBJECT_COLLECTION_BANNER = 15
        const val CUSTOM_PAGE_ITEM_TYPE_RECENT_PLAY = 16
        const val CUSTOM_PAGE_ITEM_TYPE_PLUGIN = 17
        const val CUSTOM_PAGE_ITEM_TYPE_NEW_GAME_TEST = 18
        const val CUSTOM_PAGE_ITEM_TYPE_DISCOVER = 19
        const val CUSTOM_PAGE_ITEM_TYPE_CONTENT_CARD = 20
        const val CUSTOM_PAGE_ITEM_TYPE_AMWAY_WALL = 21
        const val CUSTOM_PAGE_ITEM_TYPE_COMMON_BANNER = 22
        const val CUSTOM_PAGE_ITEM_TYPE_COMMON_BANNER_WITH_CARDS = 23
        const val CUSTOM_PAGE_ITEM_TYPE_NAVIGATION = 24
        const val CUSTOM_PAGE_ITEM_TYPE_RECOMMEND = 25
        const val CUSTOM_PAGE_ITEM_TYPE_COMMON_HORIZONTAL_SLIDE = 26
        const val CUSTOM_PAGE_ITEM_TYPE_COMMON_VERTICAL_TWO_CARDS = 27
        const val CUSTOM_PAGE_ITEM_TYPE_COLLECTION_REFRESH_ICON_MATRIX = 28
        const val CUSTOM_PAGE_ITEM_TYPE_COLLECTION_REFRESH_ICON_LANE = 29
        const val CUSTOM_PAGE_ITEM_TYPE_COLLECTION_REFRESH_SLIDE_LIST = 30
        const val CUSTOM_PAGE_ITEM_TYPE_COMMON_CONTENT_LABEL_LANE = 31
        const val CUSTOM_PAGE_ITEM_TYPE_COMMON_NOTIFICATION_COLUMN = 32
        const val CUSTOM_PAGE_ITEM_TYPE_COMMON_ANNOUNCEMENT_BANNER = 33
        const val CUSTOM_PAGE_ITEM_TYPE_COMMON_RECOMMEND_CARD = 34
        const val CUSTOM_PAGE_ITEM_TYPE_MINI_GAME_RECENT_PLAY = 35
        const val CUSTOM_PAGE_ITEM_TYPE_SINGLE_GAME_CARD = 36
        const val CUSTOM_PAGE_ITEM_TYPE_DOUBLE_GAME_WELFARE_CARD = 37
        const val CUSTOM_PAGE_ITEM_TYPE_PK = 38
        const val CUSTOM_PAGE_ITEM_TYPE_ACCELERATOR_RECENT_PLAYED = 39
        const val CUSTOM_PAGE_ITEM_TYPE_GAME_VERTICAL_IMAGE_TEXT = 40

        // 专题样式 to itemType
        val subjectTypeMap: HashMap<String, Int> = hashMapOf(
            COMPONENTS_GAME_SUBJECT_TYPE_DOUBLE_CARD to CUSTOM_PAGE_ITEM_TYPE_DOUBLE_ROW,
            COMPONENTS_GAME_SUBJECT_TYPE_GAME_VIDEO_HORIZONTAL_SLIDE to CUSTOM_PAGE_ITEM_TYPE_HORIZONTAL_SLIDE_VIDEO_LIST,
            COMPONENTS_GAME_SUBJECT_TYPE_GAME_VERTICAL to CUSTOM_PAGE_ITEM_TYPE_GAME_LONG_LIST,
            COMPONENTS_SUBJECT_TYPE_GAME_VERTICAL_SLIDE to CUSTOM_PAGE_ITEM_TYPE_GAME_VERTICAL_SLIDE,
            COMPONENTS_SUBJECT_TYPE_GAME_HORIZONTAL to CUSTOM_PAGE_ITEM_TYPE_GAME_ICON_MATRIX,
            COMPONENTS_SUBJECT_TYPE_GAME_HORIZONTAL_SLIDE to CUSTOM_PAGE_ITEM_TYPE_GAME_HORIZONTAL_ICON_LANE,
            COMPONENTS_SUBJECT_TYPE_GAME_TIMELINE_HORIZONTAL_SLIDE to CUSTOM_PAGE_ITEM_TYPE_GAME_HORIZONTAL_TIME_LINE,
            COMPONENTS_SUBJECT_TYPE_GALLERY to CUSTOM_PAGE_ITEM_TYPE_GAME_HORIZONTAL_STATIC_GALLERY,
            COMPONENTS_SUBJECT_TYPE_GALLERY_SLIDE to CUSTOM_PAGE_ITEM_TYPE_GAME_HORIZONTAL_GALLERY_SLIDE,
            COMPONENTS_SUBJECT_TYPE_GAME_FOLD_SLIDE to CUSTOM_PAGE_ITEM_TYPE_GAME_FOLD_SLIDE_LARGE_IMAGE,
            COMPONENTS_SUBJECT_TYPE_GAME to CUSTOM_PAGE_ITEM_TYPE_GAME_HOME_GAME_ITEM,
            COMPONENTS_SUBJECT_TYPE_SINGLE_GAME_CARD to CUSTOM_PAGE_ITEM_TYPE_SINGLE_GAME_CARD,
            COMPONENTS_SUBJECT_TYPE_DOUBLE_GAME_WELFARE_CARD to CUSTOM_PAGE_ITEM_TYPE_DOUBLE_GAME_WELFARE_CARD,
            COMPONENTS_SUBJECT_TYPE_GAME_VERTICAL_IMAGE_TEXT to CUSTOM_PAGE_ITEM_TYPE_GAME_VERTICAL_IMAGE_TEXT
        )

        // 专题样式 to 组件样式名称
        val subjectTypeToComponentStyle by lazy {
            hashMapOf(
                COMPONENTS_GAME_SUBJECT_TYPE_DOUBLE_CARD to "双列卡片",
                COMPONENTS_GAME_SUBJECT_TYPE_GAME_VIDEO_HORIZONTAL_SLIDE to "视频横屏滑动",
                COMPONENTS_GAME_SUBJECT_TYPE_GAME_VERTICAL to "长列表式",
                COMPONENTS_SUBJECT_TYPE_GAME_VERTICAL_SLIDE to "滑动列表",
                COMPONENTS_SUBJECT_TYPE_GAME_HORIZONTAL to "图标矩阵",
                COMPONENTS_SUBJECT_TYPE_GAME_HORIZONTAL_SLIDE to "图标泳道",
                COMPONENTS_SUBJECT_TYPE_GAME_TIMELINE_HORIZONTAL_SLIDE to "横向时间轴",
                COMPONENTS_SUBJECT_TYPE_GALLERY to "静态图集",
                COMPONENTS_SUBJECT_TYPE_GALLERY_SLIDE to "横向滚动图集",
                COMPONENTS_SUBJECT_TYPE_GAME_FOLD_SLIDE to "折叠滑动大图",
                COMPONENTS_SUBJECT_TYPE_GAME to "展开大图",
                COMPONENTS_SUBJECT_TYPE_GAME_EXPAND to "展开大图",
                COMPONENTS_SUBJECT_TYPE_SINGLE_GAME_CARD to "单游戏卡片",
                COMPONENTS_SUBJECT_TYPE_DOUBLE_GAME_WELFARE_CARD to "双列福利卡片",
                COMPONENTS_SUBJECT_TYPE_GAME_VERTICAL_IMAGE_TEXT to "竖式图文列表"
            )
        }

        // 专题合集  游戏单合集 样式
        val collectionTypeMap: HashMap<String, Int> = hashMapOf(
            COMPONENTS_COLLECTION_STYLE_RANKING_LIST to CUSTOM_PAGE_ITEM_TYPE_RANK_COLLECTION,
            COMPONENTS_COLLECTION_STYLE_X_SLIDE_CARD to CUSTOM_PAGE_ITEM_TYPE_SUBJECT_COLLECTION_HORIZONTAL_SLIDE_LARGE_CARD,
            COMPONENTS_COLLECTION_STYLE_X_SLIDE_CARD_SMALL to CUSTOM_PAGE_ITEM_TYPE_SUBJECT_COLLECTION_HORIZONTAL_SLIDE_SMALL_CARD,
            COMPONENTS_COLLECTION_STYLE_REFRESH_SLIDE_LIST to CUSTOM_PAGE_ITEM_TYPE_COLLECTION_REFRESH_SLIDE_LIST,
            COMPONENTS_COLLECTION_STYLE_REFRESH_SLIDE_ICON to CUSTOM_PAGE_ITEM_TYPE_COLLECTION_REFRESH_ICON_LANE,
            COMPONENTS_COLLECTION_STYLE_REFRESH_ICONS_4_2 to CUSTOM_PAGE_ITEM_TYPE_COLLECTION_REFRESH_ICON_MATRIX,
            COMPONENTS_COLLECTION_STYLE_REFRESH_X to CUSTOM_PAGE_ITEM_TYPE_COLLECTION_REFRESH_ICON_LANE,
            COMPONENTS_COLLECTION_STYLE_REFRESH_Y to CUSTOM_PAGE_ITEM_TYPE_COLLECTION_REFRESH_SLIDE_LIST,
            COMPONENTS_COLLECTION_STYLE_CAROUSEL to CUSTOM_PAGE_ITEM_TYPE_SUBJECT_COLLECTION_BANNER
        )

        // 专题合集 游戏单合集 样式 to 组件样式名称
        val collectionTypeToComponentName by lazy {
            hashMapOf(
                COMPONENTS_COLLECTION_STYLE_RANKING_LIST to "排行榜",
                "top" to "排行榜",
                COMPONENTS_COLLECTION_STYLE_X_SLIDE_CARD to "横排滑动大卡片",
                COMPONENTS_COLLECTION_STYLE_X_SLIDE_CARD_SMALL to "横排滑动小卡片",
                COMPONENTS_COLLECTION_STYLE_REFRESH_SLIDE_LIST to "轮换刷新-滑动列表",
                COMPONENTS_COLLECTION_STYLE_REFRESH_SLIDE_ICON to "轮换刷新-图标泳道",
                COMPONENTS_COLLECTION_STYLE_REFRESH_ICONS_4_2 to "轮换刷新-图标矩阵",
                COMPONENTS_COLLECTION_STYLE_REFRESH_X to "轮换刷新-图标泳道",
                COMPONENTS_COLLECTION_STYLE_REFRESH_Y to "轮换刷新-滑动列表",
                COMPONENTS_COLLECTION_STYLE_CAROUSEL to "轮播图"
            )
        }

        // 内容卡片组件样式 to 样式名称
        val contentCardTypeToComponentName by lazy {
            hashMapOf(
                CUSTOM_LINK_TYPE_ARTICLE to "文章",
                CUSTOM_LINK_TYPE_COMMUNITY_ARTICLE to "帖子",
                CUSTOM_LINK_TYPE_VIDEO to "视频贴",
                CUSTOM_LINK_TYPE_QUESTION to "提问"
            )
        }

        // 通用内容合集 样式
        val commonContentCollection: HashMap<Int, Int> = hashMapOf(
            COMMON_CONTENT_COLLECTION_LAYOUT_NAVIGATION to CUSTOM_PAGE_ITEM_TYPE_NAVIGATION,
            COMMON_CONTENT_COLLECTION_LAYOUT_KING_KONG to CUSTOM_PAGE_ITEM_TYPE_RECOMMEND,
            COMMON_CONTENT_COLLECTION_LAYOUT_HORIZONTAL_SLIDE_BANNER to CUSTOM_PAGE_ITEM_TYPE_COMMON_HORIZONTAL_SLIDE,
            COMMON_CONTENT_COLLECTION_LAYOUT_DOUBLE_ROW_BANNER to CUSTOM_PAGE_ITEM_TYPE_COMMON_VERTICAL_TWO_CARDS,
            COMMON_CONTENT_COLLECTION_LAYOUT_HORIZONTAL_VERTICAL_CARD to CUSTOM_PAGE_ITEM_TYPE_COMMON_HORIZONTAL_SLIDE,
            COMMON_CONTENT_COLLECTION_LAYOUT_DOUBLE_ROW_VERTICAL_CARD to CUSTOM_PAGE_ITEM_TYPE_COMMON_VERTICAL_TWO_CARDS,
            COMMON_CONTENT_COLLECTION_LAYOUT_VERTICAL_IMAGE_TEXT to CUSTOM_PAGE_ITEM_TYPE_COMMON_VERTICAL_TWO_CARDS,
            COMMON_CONTENT_COLLECTION_LAYOUT_HORIZONTAL_IMAGE_TEXT to CUSTOM_PAGE_ITEM_TYPE_COMMON_HORIZONTAL_SLIDE,
            COMMON_CONTENT_COLLECTION_LAYOUT_CONTENT_LABEL_LANE to CUSTOM_PAGE_ITEM_TYPE_COMMON_CONTENT_LABEL_LANE,
            COMMON_CONTENT_COLLECTION_LAYOUT_NOTIFICATION_COLUMN to CUSTOM_PAGE_ITEM_TYPE_COMMON_NOTIFICATION_COLUMN,
            COMMON_CONTENT_COLLECTION_LAYOUT_ANNOUNCEMENT_BANNER to CUSTOM_PAGE_ITEM_TYPE_COMMON_ANNOUNCEMENT_BANNER,
            COMMON_CONTENT_COLLECTION_LAYOUT_RECOMMEND_CARD to CUSTOM_PAGE_ITEM_TYPE_COMMON_RECOMMEND_CARD

        )

        // 通用内容合集 样式 to 样式名称
        val commonContentLayoutToComponentName by lazy {
            hashMapOf(
                COMMON_CONTENT_COLLECTION_LAYOUT_BANNER to "轮播banner",
                COMMON_CONTENT_COLLECTION_LAYOUT_NAVIGATION to "导航栏",
                COMMON_CONTENT_COLLECTION_LAYOUT_KING_KONG to "金刚区",
                COMMON_CONTENT_COLLECTION_LAYOUT_HORIZONTAL_SLIDE_BANNER to "横向滑动banner",
                COMMON_CONTENT_COLLECTION_LAYOUT_DOUBLE_ROW_BANNER to "双列banner",
                COMMON_CONTENT_COLLECTION_LAYOUT_HORIZONTAL_VERTICAL_CARD to "横排竖式卡片",
                COMMON_CONTENT_COLLECTION_LAYOUT_DOUBLE_ROW_VERTICAL_CARD to "双列竖式卡片",
                COMMON_CONTENT_COLLECTION_LAYOUT_VERTICAL_IMAGE_TEXT to "竖式图文列表",
                COMMON_CONTENT_COLLECTION_LAYOUT_HORIZONTAL_IMAGE_TEXT to "横排图文列表",
                COMMON_CONTENT_COLLECTION_LAYOUT_CONTENT_LABEL_LANE to "内容标签泳道",
                COMMON_CONTENT_COLLECTION_LAYOUT_NOTIFICATION_COLUMN to "通知栏目",
                COMMON_CONTENT_COLLECTION_LAYOUT_ANNOUNCEMENT_BANNER to "公告横幅",
                COMMON_CONTENT_COLLECTION_LAYOUT_RECOMMEND_CARD to "推荐卡片"
            )

        }

        val componentTypeToName by lazy {
            hashMapOf(
                CUSTOM_LINK_TYPE_COLUMN to "游戏专题",
                CUSTOM_LINK_TYPE_GAME to "游戏专题",
                CUSTOM_LINK_TYPE_ARTICLE to "内容卡片",
                CUSTOM_LINK_TYPE_COMMUNITY_ARTICLE to "内容卡片",
                CUSTOM_LINK_TYPE_VIDEO to "内容卡片",
                CUSTOM_LINK_TYPE_QUESTION to "内容卡片",
                CUSTOM_LINK_TYPE_PLUGIN_AREA to "插件化区域",
                CUSTOM_LINK_TYPE_CWZS_RECENTLY_PLAYED to "最近在玩",
                CUSTOM_LINK_TYPE_QQ_GAME_RECENTLY_PLAYED to "最近在玩",
                CUSTOM_LINK_TYPE_WECHAT_GAME_RECENTLY_PLAYED to "最近在玩",
                CUSTOM_LINK_TYPE_QQ_MINI_GAME_COLUMN_DETAIL to "QQ小游戏专题",
                CUSTOM_LINK_TYPE_WECHAT_MINI_GAME_COLUMN_DETAIL to "微信小游戏专题",
                CUSTOM_LINK_TYPE_WECHAT_WECHAT_GAME_CPM_COLUMN_DETAIL to "微信小游戏专题",
                CUSTOM_LINK_TYPE_HALO_RECOMMEND to "光环推荐",
                CUSTOM_LINK_TYPE_COLUMN_COLLECTION to "专题合集",
                CUSTOM_LINK_TYPE_GAME_LIST_COLLECTION to "游戏单合集",
                CUSTOM_LINK_TYPE_COLUMN_TEST_V2 to "新游开测",
                CUSTOM_LINK_TYPE_COMMON_COLLECTION to "通用内容合集",
                CUSTOM_LINK_TYPE_TOP_GAME_COMMENT to "安利墙"
            )
        }


        // 需要检测下载按钮是否显示的样式
        val checkShowDownloadButtonItemTypes = listOf(
            CUSTOM_PAGE_ITEM_TYPE_HORIZONTAL_SLIDE_VIDEO_LIST,
            CUSTOM_PAGE_ITEM_TYPE_GAME_VERTICAL_SLIDE,
            CUSTOM_PAGE_ITEM_TYPE_GAME_ICON_MATRIX,
            CUSTOM_PAGE_ITEM_TYPE_GAME_HORIZONTAL_TIME_LINE,
            CUSTOM_PAGE_ITEM_TYPE_GAME_HORIZONTAL_ICON_LANE,
            CUSTOM_PAGE_ITEM_TYPE_GAME_HOME_GAME_ITEM,
            CUSTOM_PAGE_ITEM_TYPE_RANK_COLLECTION,
            CUSTOM_PAGE_ITEM_TYPE_SUBJECT_COLLECTION_HORIZONTAL_SLIDE_LARGE_CARD,
            CUSTOM_PAGE_ITEM_TYPE_PLUGIN,
            CUSTOM_PAGE_ITEM_TYPE_NEW_GAME_TEST,
            CUSTOM_PAGE_ITEM_TYPE_DISCOVER,
            CUSTOM_PAGE_ITEM_TYPE_CONTENT_CARD,
            CUSTOM_PAGE_ITEM_TYPE_COLLECTION_REFRESH_ICON_MATRIX,
            CUSTOM_PAGE_ITEM_TYPE_COLLECTION_REFRESH_ICON_LANE,
            CUSTOM_PAGE_ITEM_TYPE_COLLECTION_REFRESH_SLIDE_LIST,
            CUSTOM_PAGE_ITEM_TYPE_GAME_FOLD_SLIDE_LARGE_IMAGE
        )

        // 一定会显示下载按钮的样式
        val shouldShowDownloadButtonItemTypes = listOf(
            CUSTOM_PAGE_ITEM_TYPE_HORIZONTAL_SLIDE_VIDEO_LIST,
            CUSTOM_PAGE_ITEM_TYPE_GAME_LONG_LIST,
            CUSTOM_PAGE_ITEM_TYPE_GAME_VERTICAL_SLIDE,
            CUSTOM_PAGE_ITEM_TYPE_PLUGIN,
            CUSTOM_PAGE_ITEM_TYPE_RECENT_PLAY,
            CUSTOM_PAGE_ITEM_TYPE_SINGLE_GAME_CARD
        )


    }
}

// 游戏专题
data class CustomSubjectItem(
    private val _link: LinkEntity,
    val data: SubjectEntity,
    private val _position: Int,
    private val _componentPosition: Int
) : CustomPageItem(_link, _position, _componentPosition) {

    override val itemType: Int
        get() = subjectTypeMap[data.type] ?: CUSTOM_PAGE_ITEM_TYPE_INVALID

    override val componentStyle: String
        get() = subjectTypeToComponentStyle[data.type] ?: ""

    override val showDownload: Boolean
        get() = data.showDownload

    override val games: List<GameEntity>
        get() = data.data ?: emptyList()

    // 临时变量，记录横向列表滚动的距离
    var scrolledOffset: Int = 0

    val exposureSource: List<ExposureSource>
        get() = listOf(ExposureSource("专题", "${data.name ?: ""}+$componentStyle+${data.id}"))

    override fun doAreItemsTheSame(other: CustomPageItem): Boolean {
        return other is CustomSubjectItem
                && data.id == other.data.id
    }

    override fun doAreContentsTheSames(other: CustomPageItem): Boolean {
        return other is CustomSubjectItem
                && data == other.data
                && position == other.position
                && componentPosition == other.componentPosition
    }

    /**
     * 横向时间轴的首个位置
     */
    val firstPositionInHorizontalTimeline: Int = if (data.data?.firstOrNull()?.test?.testTime != null) {
        findTheLatestTestGamePosition(data)
    } else {
        -1
    }

    private fun findTheLatestTestGamePosition(subjectEntity: SubjectEntity): Int {
        // first 是日期偏差， second 是 position
        var latestDayBeforeTodayPair = Pair(Int.MIN_VALUE, 0)
        var latestDayAfterTodayPair = Pair(Int.MAX_VALUE, 0)

        for ((index, game) in subjectEntity.data!!.withIndex()) {
            val testDayOffset = TimeUtils.getDaysOffset(game.test?.testTime ?: -999)
            if (testDayOffset == 0) {
                latestDayBeforeTodayPair = Pair(0, index)
                latestDayAfterTodayPair = Pair(0, index)
                break
            } else if (testDayOffset < 0) {
                if (latestDayBeforeTodayPair.first >= testDayOffset) {
                    latestDayBeforeTodayPair = Pair(testDayOffset, index)
                }
            } else if (testDayOffset > 0) {
                if (testDayOffset <= latestDayAfterTodayPair.first) {
                    latestDayAfterTodayPair = Pair(testDayOffset, index)
                }
            }
        }

        return if (latestDayAfterTodayPair.first != Int.MAX_VALUE) {
            latestDayAfterTodayPair.second
        } else {
            latestDayBeforeTodayPair.second
        }
    }

}

// 拆分的 游戏专题
data class CustomSplitSubjectItem(
    private val _link: LinkEntity,
    var data: SubjectEntity,
    private val _position: Int,
    private val _componentPosition: Int,
    val step: Int,
    val startChildPosition: Int
) : CustomPageItem(_link, _position, _componentPosition) {

    var splitItemCount: Int = -1 // 游戏专题拆分出来的子项数量

    val endChildPosition: Int
        get() {
            val gameSize = data.data?.size ?: 0
            return if (startChildPosition + step <= gameSize) {
                startChildPosition + step - 1
            } else {
                gameSize - 1
            }
        }

    override val itemType: Int
        get() = subjectTypeMap[data.type] ?: CUSTOM_PAGE_ITEM_TYPE_INVALID

    override val componentStyle: String
        get() = subjectTypeToComponentStyle[data.type] ?: ""

    override val showDownload: Boolean
        get() = data.showDownload

    override val games: List<GameEntity>
        get() = data.data
            ?.filterIndexed { index, _ ->
                index in startChildPosition until (startChildPosition + step)
            } ?: emptyList()

    val isFirstLine: Boolean
        get() = startChildPosition == 0

    val isLastLine: Boolean
        get() = (startChildPosition + step) >= (data.data?.size ?: 0)

    val exposureSource: List<ExposureSource>
        get() = listOf(
            ExposureSource(
                if (data.isDspSubject) "dsp广告专题" else "专题",
                "${data.name ?: ""}+${componentStyle}+${data.id}"
            )
        )

    override fun doAreItemsTheSame(other: CustomPageItem): Boolean {
        return other is CustomSplitSubjectItem
                && data.id == other.data.id
    }

    override fun doAreContentsTheSames(other: CustomPageItem): Boolean {
        return other is CustomSplitSubjectItem
                && startChildPosition == other.startChildPosition
                && step == other.step
                && (startChildPosition until startChildPosition + step).all {
            data.data?.getOrNull(it) == other.data.data?.getOrNull(it)
        }
    }
}

// 游戏专题：展开大图样式专用
data class CustomGameItem(
    private val _link: LinkEntity,
    val data: GameEntity,
    val linkColumn: SubjectEntity?,
    val childPosition: Int,
    private val _position: Int, // 当前 item 在 ui 中的位置
    private val _componentPosition: Int  // 当前组件的位置
) : CustomPageItem(_link, _position, _componentPosition) {

    override val itemType: Int
        get() = CUSTOM_PAGE_ITEM_TYPE_GAME_HOME_GAME_ITEM

    override val componentStyle: String
        get() = "展开大图"

    override val showDownload: Boolean
        get() = data.homeSetting.downloadBtnSwitch == "on"

    override val games: List<GameEntity>
        get() = listOf(data)

    val isFirstLine: Boolean
        get() = childPosition == 0

    override fun doAreItemsTheSame(other: CustomPageItem): Boolean {
        return other is CustomGameItem
                && data.id == other.data.id
    }

    override fun doAreContentsTheSames(other: CustomPageItem): Boolean {
        return other is CustomGameItem
                && data == other.data
                && linkColumn == other.linkColumn
                && childPosition == other.childPosition
                && position == other.position
                && componentPosition == other.componentPosition
    }
}

// 专题合集 游戏单合集
data class CustomSubjectCollectionItem(
    private val _link: LinkEntity,
    val data: CustomPageData.LinkColumnCollection,
    private val _position: Int,
    private val _componentPosition: Int
) : CustomPageItem(_link, _position, _componentPosition) {

    val isSubjectCollection: Boolean  // 是否是专题合集（还有可能是游戏单合集）
        get() = link.type == CUSTOM_LINK_TYPE_COLUMN_COLLECTION

    override val itemType: Int
        get() = collectionTypeMap[data.style] ?: CUSTOM_PAGE_ITEM_TYPE_INVALID

    override val componentStyle: String
        get() = collectionTypeToComponentName[data.style] ?: ""

    override
    val showDownload: Boolean
        get() = true

    override val games: List<GameEntity>
        get() = if (showDownload) {
            data.data.flatMap {
                it.games
            }
        } else {
            emptyList()
        }

    // 临时变量：记录合集中，轮换刷新时当前显示的页码
    var showPage: Int = 0

    // 临时变量：记录合集中，轮换刷新时当前加载的页码
    var loadPage: Int = 1

    // 临时变量，记录点击轮换刷新时，是否正在loading
    var isLoading: Boolean = false

    // 临时变量，数据是否已全部加载完毕
    var isLoadedEnd: Boolean = false

    var isBackToStart = true

    val showSubject: CustomPageData.LinkColumnCollection.CustomSubjectEntity?
        get() = data.data.getOrNull(showPage % data.data.size)

    override fun doAreItemsTheSame(other: CustomPageItem): Boolean {
        return other is CustomSubjectCollectionItem
                && data.id == other.data.id
    }

    override fun doAreContentsTheSames(other: CustomPageItem): Boolean {
        return other is CustomSubjectCollectionItem
                && showPage == other.showPage
                && isLoading == other.isLoading
                && isLoadedEnd == other.isLoadedEnd
                && showSubject == other.showSubject
    }
}

// 最近在玩
data class CustomRecentGamesItem(
    private val _link: LinkEntity,
    val data: List<VGameItemData>,
    private val _position: Int,
    private val _componentPosition: Int
) : CustomPageItem(_link, _position, _componentPosition) {

    override val itemType: Int
        get() = CUSTOM_PAGE_ITEM_TYPE_RECENT_PLAY

    override fun doAreContentsTheSames(other: CustomPageItem): Boolean {
        return other is CustomRecentGamesItem
                && data == other.data
                && position == other.position
                && componentPosition == other.componentPosition
    }
}


// 微信小游戏-最近在玩
data class CustomRecentWeChatMiniGamesItem(
    private val _link: LinkEntity,
    val data: List<GameEntity>,
    private val _position: Int,
    private val _componentPosition: Int
) : CustomPageItem(_link, _position, _componentPosition) {

    override val itemType: Int
        get() = CUSTOM_PAGE_ITEM_TYPE_MINI_GAME_RECENT_PLAY

    override fun doAreContentsTheSames(other: CustomPageItem): Boolean {
        return other is CustomRecentWeChatMiniGamesItem
                && data == other.data
                && position == other.position
                && componentPosition == other.componentPosition
    }
}

// 微信小游戏CPM专题组件
data class CustomWeChatMiniGamesCPMSubjectItem(
    private val _link: LinkEntity,
    val data: SubjectEntity,
    private val _position: Int,
    private val _componentPosition: Int
) : CustomPageItem(_link, _position, _componentPosition) {

    override val itemType: Int
        get() = CUSTOM_PAGE_ITEM_TYPE_MINI_GAME_RECENT_PLAY

    override fun doAreContentsTheSames(other: CustomPageItem): Boolean {
        return other is CustomWeChatMiniGamesCPMSubjectItem
                && data == other.data
                && position == other.position
                && componentPosition == other.componentPosition
    }
}

// qq小游戏-最近在玩
data class CustomRecentQqMiniGamesItem(
    private val _link: LinkEntity,
    val data: List<GameEntity>,
    val linkQqGameRecentlyPlayed: CustomPageData.LinkRecentlyPlayed,
    private val _position: Int,
    private val _componentPosition: Int
) : CustomPageItem(_link, _position, _componentPosition) {

    override val itemType: Int
        get() = CUSTOM_PAGE_ITEM_TYPE_MINI_GAME_RECENT_PLAY

    override fun doAreContentsTheSames(other: CustomPageItem): Boolean {
        return other is CustomRecentQqMiniGamesItem
                && data == other.data
                && linkQqGameRecentlyPlayed.home == other.linkQqGameRecentlyPlayed.home
                && linkQqGameRecentlyPlayed.moreLink?.type == other.linkQqGameRecentlyPlayed.moreLink?.type
                && linkQqGameRecentlyPlayed.moreLink?.link == other.linkQqGameRecentlyPlayed.moreLink?.link
                && linkQqGameRecentlyPlayed.moreLink?.text == other.linkQqGameRecentlyPlayed.moreLink?.text
                && position == other.position
                && componentPosition == other.componentPosition
    }
}

data class CustomRecentAcceleratorItem(
    private val _link: LinkEntity,
    val data: List<AcctRecord>,
    val moreLink: LinkEntity?,
    private val _position: Int,
    private val _componentPosition: Int
) : CustomPageItem(_link, _position, _componentPosition) {

    override val itemType: Int
        get() = CUSTOM_PAGE_ITEM_TYPE_ACCELERATOR_RECENT_PLAYED

    override fun doAreContentsTheSames(other: CustomPageItem): Boolean {
        return other is CustomRecentAcceleratorItem
                && position == other.position
                && componentPosition == other.componentPosition
                && isSameData(other.data)
    }

    private fun isSameData(other: List<AcctRecord>) =
        data.size == other.size &&
                data.joinToString("_") { it.gameId } == other.joinToString("_") { it.gameId }
}

// 插件化区域
data class CustomPluginItem(
    private val _link: LinkEntity,
    val data: List<GameEntity>,
    private val _position: Int,
    private val _componentPosition: Int
) : CustomPageItem(_link, _position, _componentPosition) {

    override val itemType: Int
        get() = CUSTOM_PAGE_ITEM_TYPE_PLUGIN

    override val games: List<GameEntity>
        get() = data

    override fun doAreContentsTheSames(other: CustomPageItem): Boolean {
        return other is CustomPluginItem
                && data == other.data
                && position == other.position
                && componentPosition == other.componentPosition
    }
}

// 新游开测
data class CustomGameTestV2Item(
    private val _link: LinkEntity,
    val data: HomeItemTestV2Entity,
    private val _position: Int,
    private val _componentPosition: Int
) : CustomPageItem(_link, _position, _componentPosition) {

    override val itemType: Int
        get() = CUSTOM_PAGE_ITEM_TYPE_NEW_GAME_TEST

    override fun doAreContentsTheSames(other: CustomPageItem): Boolean {
        return other is CustomGameTestV2Item
                && data == other.data
                && position == other.position
                && componentPosition == other.componentPosition
    }
}

// 光环推荐
data class CustomDiscoverCardItem(
    private val _link: LinkEntity,
    val data: DiscoveryCardEntity?,
    private val _position: Int,
    private val _componentPosition: Int
) : CustomPageItem(_link, _position, _componentPosition) {

    val spanCount = 3

    override val itemType: Int
        get() = CUSTOM_PAGE_ITEM_TYPE_DISCOVER

    override val showDownload: Boolean
        get() = true

    override val games: List<GameEntity>
        get() = data?.games ?: emptyList()

    override fun doAreContentsTheSames(other: CustomPageItem): Boolean {
        return other is CustomDiscoverCardItem
                && data == other.data
                && position == other.position
                && componentPosition == other.componentPosition
    }
}

// 安利墙
data class CustomAmwayItem(
    private val _link: LinkEntity,
    val data: List<AmwayCommentEntity>,
    private val _position: Int,
    private val _componentPosition: Int
) : CustomPageItem(_link, _position, _componentPosition) {

    override val itemType: Int
        get() = CUSTOM_PAGE_ITEM_TYPE_AMWAY_WALL

    override fun doAreContentsTheSames(other: CustomPageItem): Boolean {
        return other is CustomAmwayItem
                && data == other.data
                && position == other.position
                && componentPosition == other.componentPosition
    }
}

// 内容卡片
data class CustomContentCardItem(
    private val _link: LinkEntity,
    val data: CustomPageData.ContentCard,
    private val _position: Int,
    private val _componentPosition: Int
) : CustomPageItem(_link, _position, _componentPosition) {

    override val itemType: Int
        get() = CUSTOM_PAGE_ITEM_TYPE_CONTENT_CARD

    override val componentStyle: String
        get() = contentCardTypeToComponentName[link.type] ?: ""

    override fun doAreContentsTheSames(other: CustomPageItem): Boolean {
        return other is CustomContentCardItem
                && data == other.data
                && position == other.position
                && componentPosition == other.componentPosition
    }
}

// 通用内容合集
data class CustomCommonContentCollectionItem(
    private val _link: LinkEntity,
    val data: CustomPageData.CommonContentCollection,
    private val _position: Int,
    private val _componentPosition: Int
) : CustomPageItem(_link, _position, _componentPosition) {

    override val itemType: Int
        get() = if (data.layout == COMMON_CONTENT_COLLECTION_LAYOUT_BANNER) {
            // 轮播图右边卡片列表, 至少需要2个卡片才能显示
            if (data.slides.subSlide.size < 2) {
                CUSTOM_PAGE_ITEM_TYPE_COMMON_BANNER
            } else {
                CUSTOM_PAGE_ITEM_TYPE_COMMON_BANNER_WITH_CARDS
            }
        } else {
            commonContentCollection[data.layout] ?: CUSTOM_PAGE_ITEM_TYPE_INVALID
        }

    override val componentStyle: String
        get() = commonContentLayoutToComponentName[data.layout] ?: ""

    override fun doAreItemsTheSame(other: CustomPageItem): Boolean {
        return other is CustomCommonContentCollectionItem
                && data.id == other.data.id
    }

    override fun doAreContentsTheSames(other: CustomPageItem): Boolean {
        return other is CustomCommonContentCollectionItem
                && data == other.data
                && position == other.position
                && componentPosition == other.componentPosition
    }

    // 临时变量，当样式为 通知栏目 时，记录当前显示的位置
    var selectedPosition = 0

}

// 拆分的通用内用合集
data class CustomSplitCommonContentCollectionItem(
    private val _link: LinkEntity,
    val data: CustomPageData.CommonContentCollection,
    private val _position: Int,
    private val _componentPosition: Int,
    val leftPosition: Int,
) : CustomPageItem(_link, _position, _componentPosition) {

    override val itemType
        get() = commonContentCollection[data.layout] ?: CUSTOM_PAGE_ITEM_TYPE_INVALID

    override val componentStyle: String
        get() = commonContentLayoutToComponentName[data.layout] ?: ""

    val isFirstLine: Boolean
        get() = leftPosition == 0

    val isLastLine: Boolean
        get() = leftPosition + 2 >= data.data.size

    override fun doAreItemsTheSame(other: CustomPageItem): Boolean {
        return other is CustomSplitCommonContentCollectionItem
                && data.id == other.data.id
    }

    override fun doAreContentsTheSames(other: CustomPageItem): Boolean {
        return other is CustomSplitCommonContentCollectionItem
                && data == other.data
                && data.data.getOrNull(leftPosition) == other.data.data.getOrNull(leftPosition)
                && data.data.getOrNull(leftPosition + 1) == other.data.data.getOrNull(leftPosition + 1)

    }
}

// PK
data class CustomPKItem(
    private val _link: LinkEntity,
    val data: PKEntity?,
    private val _position: Int,
    private val _componentPosition: Int
) : CustomPageItem(_link, _position, _componentPosition) {

    override val itemType: Int
        get() = CUSTOM_PAGE_ITEM_TYPE_PK

    override fun doAreContentsTheSames(other: CustomPageItem): Boolean {
        return other is CustomPKItem
                && link == other.link
                && data == other.data
                && position == other.position
                && componentPosition == other.componentPosition
    }
}

data class CustomDspPlaceholderItem(
    private val _link: LinkEntity,
    val data: SubjectEntity,
    private val _position: Int,
    private val _componentPosition: Int
) : CustomPageItem(_link, _position, _componentPosition) {

    override val itemType: Int
        get() = CUSTOM_PAGE_ITEM_TYPE_MINI_GAME_RECENT_PLAY

    override fun doAreContentsTheSames(other: CustomPageItem): Boolean {
        return other is CustomDspPlaceholderItem
                && data == other.data
                && position == other.position
                && componentPosition == other.componentPosition
    }
}

object CustomFooterItem : CustomPageItem(LinkEntity(), -1, -1) {
    override val itemType: Int
        get() = CUSTOM_PAGE_ITEM_TYPE_FOOTER
}

object CustomInvalidItem : CustomPageItem(LinkEntity(), -2, -2) {
    override val itemType: Int
        get() = CUSTOM_PAGE_ITEM_TYPE_INVALID
}


