package com.gh.gamecenter.search.adapter

import android.util.SparseArray
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.gh.common.exposure.IExposable
import com.gh.gamecenter.SearchType
import com.gh.gamecenter.common.baselist.LoadStatus
import com.gh.gamecenter.common.exposure.ExposureSource
import com.gh.gamecenter.common.utils.toBinding
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.home.custom.model.CustomPageData
import com.gh.gamecenter.search.viewholder.SearchGameListFooterViewHolder
import com.gh.gamecenter.search.viewholder.SearchGameListViewHolder
import com.gh.gamecenter.search.viewmodel.SearchGameListViewModel

class SearchGameListAdapter(
    private val viewModel: SearchGameListViewModel,
    private val location: String,
) : ListAdapter<CustomPageData.LinkColumnCollection.CustomSubjectEntity, ViewHolder>(
    createDiffUtil()
), IExposable {

    private var type = SearchType.DEFAULT.value
    private var key = ""

    private var exposureEventArray: SparseArray<ExposureEvent>? = null

    private var _recyclerView: RecyclerView? = null

    private var _loadStatus = LoadStatus.INIT

    fun submitList(data: List<CustomPageData.LinkColumnCollection.CustomSubjectEntity>?, key: String, type: String) {
        exposureEventArray = SparseArray(data?.size ?: 0)
        this.key = key
        this.type = type
        submitList(data)
    }

    fun updateStatus(loadStatus: LoadStatus) {
        _loadStatus = loadStatus
        if (itemCount > 0) {
            _recyclerView?.post {
                notifyItemChanged(itemCount - 1)
            }
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        return if (viewType == ITEM_TYPE_CONTENT) {
            SearchGameListViewHolder(
                parent.toBinding(),
                location,
                exposureEventArray,
                object : SearchGameListViewHolder.SearchGameListListener {

                    override fun navigateToGameDetailPage(
                        gameId: String,
                        position: Int,
                        collection: CustomPageData.LinkColumnCollection.CustomSubjectEntity
                    ) {
                        viewModel.navigateToGameDetailPage(gameId, position, collection)
                    }

                    override fun navigateToHomePage(
                        userId: String,
                        position: Int,
                        collection: CustomPageData.LinkColumnCollection.CustomSubjectEntity
                    ) {
                        viewModel.navigateToHomePage(userId, position, collection)
                    }

                    override fun navigateGameCollectionDetailPage(
                        position: Int,
                        collection: CustomPageData.LinkColumnCollection.CustomSubjectEntity,
                        exposureSourceList: List<ExposureSource>
                    ) {
                        viewModel.navigateGameCollectionDetailPage(position, collection, exposureSourceList)
                    }

                })
        } else {
            SearchGameListFooterViewHolder(parent.toBinding(), object : SearchGameListFooterViewHolder.FooterListener {
                override fun loadMore() {
                    viewModel.onLoadMore()
                }

                override fun retry() {
                    viewModel.retry()
                }

                override fun toTop() {
                    _recyclerView?.scrollToPosition(0)
                }

            })
        }
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        when (holder) {
            is SearchGameListViewHolder -> {
                holder.bind(getItem(position), key, type)
            }

            is SearchGameListFooterViewHolder -> {
                holder.bind(_loadStatus)
            }
        }
    }


    override fun getItemCount(): Int {
        val dataCount = super.getItemCount()

        return if (dataCount > 0) {
            dataCount + 1
        } else {
            0
        }
    }

    override fun getItemViewType(position: Int): Int {
        return if (position < itemCount - 1) {
            ITEM_TYPE_CONTENT
        } else {
            ITEM_TYPE_FOOTER
        }
    }

    override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
        _recyclerView = recyclerView
    }

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

    companion object {

        private const val ITEM_TYPE_CONTENT = 0
        private const val ITEM_TYPE_FOOTER = 1

        fun createDiffUtil() =
            object : DiffUtil.ItemCallback<CustomPageData.LinkColumnCollection.CustomSubjectEntity>() {
                override fun areItemsTheSame(
                    oldItem: CustomPageData.LinkColumnCollection.CustomSubjectEntity,
                    newItem: CustomPageData.LinkColumnCollection.CustomSubjectEntity
                ): Boolean {
                    return oldItem.id == newItem.id
                }

                override fun areContentsTheSame(
                    oldItem: CustomPageData.LinkColumnCollection.CustomSubjectEntity,
                    newItem: CustomPageData.LinkColumnCollection.CustomSubjectEntity
                ): Boolean {
                    return oldItem.id == newItem.id
                            && oldItem.user == newItem.user
                            && oldItem.count == newItem.count
                            && oldItem.games.size == newItem.games.size
                            && oldItem.adIconActive == newItem.adIconActive
                            && oldItem.intro == newItem.intro
                            && oldItem.title == newItem.title
                            && oldItem.image == newItem.image
                            && oldItem.tags.size == newItem.tags.size
                }

            }
    }

    override fun getEventByPosition(pos: Int): ExposureEvent? {
        return exposureEventArray?.get(pos)
    }

    override fun getEventListByPosition(pos: Int): List<ExposureEvent>? = null
}