package com.gh.gamecenter.home.custom.adapter

import android.content.Context
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.PagerSnapHelper
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.gh.common.databind.BindingAdapters
import com.gh.common.exposure.ExposureManager
import com.gh.common.exposure.ExposureTraceUtils
import com.gh.common.util.DirectUtils
import com.gh.gamecenter.common.entity.LinkEntity
import com.gh.gamecenter.common.utils.DataLogUtils
import com.gh.gamecenter.common.utils.goneIf
import com.gh.gamecenter.common.utils.toBinding
import com.gh.gamecenter.core.utils.PageSwitchDataHelper
import com.gh.gamecenter.entity.HomeSlide
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.exposure.ExposureType
import com.gh.gamecenter.home.custom.viewholder.CustomHomeSlideListItemViewHolder
import com.gh.gamecenter.home.custom.viewholder.CustomHomeSubSlideListItemViewHolder
import com.lightgame.download.DownloadEntity

class CustomHomeSlideListAdapter(
    context: Context,
    val snapHelper: PagerSnapHelper,
    private val layoutManager: LinearLayoutManager,
    private val hasCards: Boolean = false,
    private val listener: OnEventListener
) : CustomBaseChildAdapter<HomeSlide, ViewHolder>(context) {

    private var recyclerView: RecyclerView? = null

    override fun checkResetData(updates: List<HomeSlide>?) {
        val isSameSize = updates?.size == dataList.size
        _dataList.clear()
        updates?.let(_dataList::addAll)
        if (isSameSize) {
            val view = snapHelper.findSnapView(layoutManager) ?: return
            val centerPosition = layoutManager.getPosition(view)
            val startPosition = if (centerPosition > 0) centerPosition - 1 else centerPosition
            notifyItemRangeChanged(startPosition, 3)
        } else {
            notifyDataSetChanged()
        }
    }

    val dataCount: Int
        get() = dataList.size

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        return if (hasCards) {
            CustomHomeSubSlideListItemViewHolder(parent.toBinding())
        } else {
            CustomHomeSlideListItemViewHolder(parent.toBinding())
        }
    }

    override fun getItemCount() = if (dataCount <= 1) dataCount else Int.MAX_VALUE

    override fun getItem(position: Int): HomeSlide {
        return dataList[getDataPosition(position)]
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val actualPosition = getDataPosition(position)
        if (actualPosition > dataList.size) {
            holder.itemView.post {
                notifyItemChanged(position)
            }
            return
        }

        val homeSlide = dataList[actualPosition]
        val game = homeSlide.linkGame

        if (holder is CustomHomeSlideListItemViewHolder) {
            holder.bindSlideListItem(homeSlide)
            setOnClickListener(
                holder.binding.root,
                holder.binding.includeGame.root,
                homeSlide,
                actualPosition,
                game?.exposureEvent
            )
            BindingAdapters.setGameTags(holder.binding.includeGame.gameTags, homeSlide.linkGame?.tagStyle, 3)
            holder.binding.unknownBackground.goneIf(DirectUtils.directLinkTypes.contains(homeSlide.linkType))
        }

        if (holder is CustomHomeSubSlideListItemViewHolder) {
            holder.bindSubSlideListItem(homeSlide)
            setOnClickListener(holder.binding.root, holder.binding.gameGroup, homeSlide, actualPosition, game?.exposureEvent)
        }
    }

    override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
        this.recyclerView = recyclerView
    }

    override fun onDetachedFromRecyclerView(recyclerView: RecyclerView) {
        this.recyclerView = null
    }

    private fun setOnClickListener(
        rootView: View,
        gameView: View,
        homeSlide: HomeSlide,
        actualPosition: Int,
        exposureEvent: ExposureEvent?
    ) {
        rootView.setOnClickListener {
            val actualPositionString = (actualPosition + 1).toString()

            PageSwitchDataHelper.pushCurrentPageData(
                hashMapOf(
                    Pair(PageSwitchDataHelper.PAGE_BUSINESS_TYPE, "首页轮播图")
                )
            )

            DataLogUtils.uploadLunbotuLog(
                context,
                homeSlide.linkType,
                homeSlide.linkText,
                homeSlide.title,
                actualPositionString,
                "新首页"
            )
            exposureEvent?.let {
                val clickEvent = ExposureEvent(
                    payload = it.payload,
                    source = it.source,
                    eTrace = ExposureTraceUtils.appendTrace(it),
                    event = ExposureType.CLICK
                )
                if (homeSlide.transformLinkEntity().type != "game") {
                    ExposureManager.log(clickEvent)
                }
            }
            listener.navigateToLinkPage(homeSlide.transformLinkEntity(), "轮播图", exposureEvent)
        }
        gameView.setOnClickListener {
            val actualPositionString = (actualPosition + 1).toString()
            val linkGame = homeSlide.linkGame
            DataLogUtils.uploadLunbotuLog(
                context,
                homeSlide.linkType,
                homeSlide.linkText,
                homeSlide.title,
                actualPositionString,
                "新首页"
            )
            if (linkGame != null) {
                listener.navigateToGameDetailPage(actualPosition, linkGame, "轮播图", homeSlide.transformLinkEntity())
            }
        }
    }

    fun notifyItemByDownload(downloadEntity: DownloadEntity?) {
        if (downloadEntity == null) {
            notifyDataSetChanged()
        } else {
            val layoutManager = recyclerView?.layoutManager
            if (layoutManager is LinearLayoutManager) {
                val snapView = snapHelper.findSnapView(layoutManager)
                if (snapView != null) {
                    val position = layoutManager.getPosition(snapView)
                    if (position != -1) {
                        for (index in getCheckPositions(getDataPosition(position))) {
                            if (index >= 0 && index < dataList.size) {
                                val game = dataList[index].linkGame
                                if (game != null && game.id == downloadEntity.gameId) {
                                    notifyItemChanged(position)
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    fun scrollToNextPage() {
        recyclerView?.let {
            val layoutManager = it.layoutManager
            if (layoutManager is LinearLayoutManager) {
                val snapView = snapHelper.findSnapView(layoutManager)
                if (snapView != null) {
                    it.smoothScrollToPosition(layoutManager.getPosition(snapView) + 1)
                }
            }
        }
    }

    private fun getCheckPositions(actualPosition: Int): List<Int> {
        return arrayListOf(actualPosition - 1, actualPosition, actualPosition + 1)
    }

    /**
     * 当初始位置过大时(原定Int.Max_value/2)，可能会出现无法继续向右滚动 原因未知
     * bug：https://jira.shanqu.cc/browse/GHZSCY-6045
     */
    fun getInitPosition() = if (dataCount > 1) {
        100000 - (100000 % dataCount)
    } else {
        dataCount
    }

    fun getDataPosition(position: Int): Int {
        return if (dataCount > 0) {
            position % dataCount
        } else {
            position
        }
    }

    fun getActualSize() = dataList.size

    interface OnEventListener {
        fun navigateToGameDetailPage(actualPosition: Int, game: GameEntity, text: String, link: LinkEntity?)

        fun navigateToLinkPage(link: LinkEntity, text: String, exposureEvent: ExposureEvent?)
    }
}