package com.gh.gamecenter.forum.home.follow.adapter

import android.view.ViewGroup
import androidx.lifecycle.LifecycleOwner
import androidx.recyclerview.widget.DiffUtil.ItemCallback
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.gh.gamecenter.R
import com.gh.gamecenter.common.baselist.LoadStatus
import com.gh.gamecenter.common.entity.LinkEntity
import com.gh.gamecenter.common.syncpage.ISyncAdapterHandler
import com.gh.gamecenter.common.utils.SensorsBridge
import com.gh.gamecenter.common.utils.toBinding
import com.gh.gamecenter.common.utils.toColor
import com.gh.gamecenter.entity.FollowDynamicEntity
import com.gh.gamecenter.entity.FollowUserEntity
import com.gh.gamecenter.eventbus.EBUserFollow
import com.gh.gamecenter.feature.entity.ConcernEntity
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.entity.LibaoEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.forum.home.follow.*
import com.gh.gamecenter.forum.home.follow.FollowItem.Companion.FOLLOW_ITEM_TYPE_ARTICLE
import com.gh.gamecenter.forum.home.follow.FollowItem.Companion.FOLLOW_ITEM_TYPE_COMMON_BANNER
import com.gh.gamecenter.forum.home.follow.FollowItem.Companion.FOLLOW_ITEM_TYPE_COMMON_BANNER_WITH_CARDS
import com.gh.gamecenter.forum.home.follow.FollowItem.Companion.FOLLOW_ITEM_TYPE_COMMON_HORIZONTAL_SLIDE
import com.gh.gamecenter.forum.home.follow.FollowItem.Companion.FOLLOW_ITEM_TYPE_COMMON_VERTICAL_TWO_CARDS
import com.gh.gamecenter.forum.home.follow.FollowItem.Companion.FOLLOW_ITEM_TYPE_EMPTY
import com.gh.gamecenter.forum.home.follow.FollowItem.Companion.FOLLOW_ITEM_TYPE_FOOTER
import com.gh.gamecenter.forum.home.follow.FollowItem.Companion.FOLLOW_ITEM_TYPE_GIFT_PACK
import com.gh.gamecenter.forum.home.follow.FollowItem.Companion.FOLLOW_ITEM_TYPE_HEADER
import com.gh.gamecenter.forum.home.follow.FollowItem.Companion.FOLLOW_ITEM_TYPE_NAVIGATION
import com.gh.gamecenter.forum.home.follow.FollowItem.Companion.FOLLOW_ITEM_TYPE_POST_CARD
import com.gh.gamecenter.forum.home.follow.FollowItem.Companion.FOLLOW_ITEM_TYPE_RECOMMEND
import com.gh.gamecenter.forum.home.follow.FollowItem.Companion.FOLLOW_ITEM_TYPE_RECOMMEND_USER
import com.gh.gamecenter.forum.home.follow.viewholder.*
import com.gh.gamecenter.forum.home.follow.viewmodel.FollowHomeViewModel
import com.gh.gamecenter.home.custom.OnViewHolderAttachListener
import com.gh.gamecenter.home.custom.model.CustomPageData

class FollowHomeAdapter(
    private val lifecycleOwner: LifecycleOwner,
    private val viewModel: FollowHomeViewModel,
    private val pageConfiguration: FollowPageConfiguration
) : ListAdapter<FollowItem, ViewHolder>(createItemCallback()), ISyncAdapterHandler {

    private var loadStatus: LoadStatus? = null

    private var _recyclerView: RecyclerView? = null

    override fun submitList(list: List<FollowItem>?) {
        val dataWithFooter = if (list.isNullOrEmpty()) {
            ArrayList(list)
        } else {
            list + FollowFooterItem
        }
        super.submitList(dataWithFooter)
    }

    fun setLoadStatus(status: LoadStatus) {
        loadStatus = status
        notifyItemChanged(itemCount - 1)
    }

    override fun getItemViewType(position: Int): Int {
        return currentList[position].itemType
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int, payloads: MutableList<Any>) {
        var change: EBUserFollow? = null
        var readStatusUpdate: ReadStatusUpdate? = null
        payloads.forEach {
            if (it is EBUserFollow) {
                change = it
            }
            if (it is ReadStatusUpdate) {
                readStatusUpdate = it
            }

        }
        when {
            change != null -> {  // 局部刷新，关注/取消关注
                (holder as? FollowRecommendListViewHolder)?.updateFollowed(change!!)
            }

            readStatusUpdate != null -> {  // 局部刷新 关注用户是否有新消息
                (holder as? FollowHomeHeaderViewHolder)?.updateReadStatus(readStatusUpdate!!.ids)
            }

            else -> {
                super.onBindViewHolder(holder, position, payloads)
            }

        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder =
        when (viewType) {
            FOLLOW_ITEM_TYPE_HEADER -> {
                FollowHomeHeaderViewHolder(parent.toBinding(), object : FollowHomeHeaderViewHolder.OnEventListener {
                    override fun onItemClick(position: Int, data: List<FollowUserEntity>) {
                        viewModel.viewItemFollowed(position, data)
                    }

                    override fun onAllClick() {
                        viewModel.viewAllFollowed()
                    }

                    override fun onLoginClick() {
                        viewModel.login()
                    }

                })
            }

            FOLLOW_ITEM_TYPE_RECOMMEND_USER -> {
                FollowRecommendListViewHolder(parent.toBinding(),
                    object : FollowRecommendListAdapter.OnChildEventListener {
                        override fun onItemClick(childPosition: Int, userId: String) {
                            SensorsBridge.trackFollowPageRecommendedUserCardClick(userId, childPosition + 1)
                            viewModel.navigateToUserHomePage(userId)
                        }

                        override fun onFollowClick(childPosition: Int, userId: String, isFollow: Boolean) {
                            SensorsBridge.trackRecommendedUserFollowButtonClick(userId, childPosition + 1)
                            viewModel.followUser(userId, isFollow)
                        }

                    })
            }

            FOLLOW_ITEM_TYPE_COMMON_BANNER -> {
                FollowHomeSlideListViewHolder(
                    parent.toBinding(),
                    lifecycleOwner,
                    object : FollowHomeSlideListViewHolder.OnChildEventListener {
                        override fun navigateToLinkPage(
                            position: Int,
                            link: LinkEntity,
                            data: CustomPageData.CommonContentCollection,
                            text: String,
                            exposureEvent: ExposureEvent?
                        ) {
                            viewModel.navigateToLinkPageInCommonContent(position, link, data, text, exposureEvent)
                        }

                        override fun navigateToGameDetailPage(position: Int, game: GameEntity, text: String) {
                            viewModel.navigateToGameDetailPage(position, game, text)
                        }

                    })
            }

            FOLLOW_ITEM_TYPE_COMMON_BANNER_WITH_CARDS -> {
                FollowHomeSlideWithCardsViewHolder(
                    parent.toBinding(),
                    viewModel.commonContentCollectionUseCase,
                    lifecycleOwner,
                    object : FollowHomeSlideWithCardsViewHolder.OnChildEventListener {
                        override fun navigateToGameDetailPage(
                            childPosition: Int,
                            gameEntity: GameEntity,
                            text: String
                        ) {
                            viewModel.navigateToGameDetailPage(childPosition, gameEntity, text)
                        }

                        override fun navigateToLinkPage(
                            position: Int,
                            link: LinkEntity,
                            data: CustomPageData.CommonContentCollection,
                            text: String,
                            exposureEvent: ExposureEvent?
                        ) {
                            viewModel.navigateToLinkPageInCommonContent(position, link, data, text, exposureEvent)
                        }

                    })
            }

            FOLLOW_ITEM_TYPE_NAVIGATION -> {
                FollowNavigationViewHolder(parent.toBinding(),
                    object : FollowNavigationViewHolder.OnChildEventListener {
                        override fun navigateToLinkPage(
                            position: Int,
                            link: LinkEntity,
                            data: CustomPageData.CommonContentCollection,
                            text: String,
                            exposureEvent: ExposureEvent?
                        ) {
                            viewModel.navigateToLinkPageInCommonContent(position, link, data, text, exposureEvent)
                        }

                    })
            }

            FOLLOW_ITEM_TYPE_RECOMMEND -> {
                FollowHomeRecommendItemViewHolder(
                    parent.toBinding(),
                    object : FollowHomeRecommendItemViewHolder.OnChildEventListener {
                        override fun navigateToLinkPage(
                            position: Int,
                            link: LinkEntity,
                            data: CustomPageData.CommonContentCollection,
                            text: String,
                            exposureEvent: ExposureEvent?
                        ) {
                            viewModel.navigateToLinkPageInCommonContent(position, link, data, text, exposureEvent)
                        }

                    })
            }

            FOLLOW_ITEM_TYPE_COMMON_HORIZONTAL_SLIDE ->
                FollowCommonCollectionViewHolder(
                    parent.toBinding(),
                    object : FollowCommonCollectionViewHolder.OnChildEventListener {
                        override fun navigateToLinkPage(
                            position: Int,
                            link: LinkEntity,
                            data: CustomPageData.CommonContentCollection,
                            text: String,
                            exposureEvent: ExposureEvent?
                        ) {
                            viewModel.navigateToLinkPageInCommonContent(position, link, data, text, exposureEvent)
                        }

                        override fun navigateToCommonCollectionDetailPage(data: CustomPageData.CommonContentCollection) {
                            viewModel.navigateToCommonCollectionDetailPage(data)
                        }

                    })

            FOLLOW_ITEM_TYPE_COMMON_VERTICAL_TWO_CARDS ->
                FollowCommonCollection12ViewHolder(
                    parent.toBinding(),
                    object : FollowCommonCollection12ViewHolder.OnChildEventListener {
                        override fun navigateToLinkPage(
                            position: Int,
                            link: LinkEntity,
                            data: CustomPageData.CommonContentCollection,
                            text: String,
                            exposureEvent: ExposureEvent?
                        ) {
                            viewModel.navigateToLinkPageInCommonContent(position, link, data, text, exposureEvent)
                        }

                        override fun navigateToCommonCollectionDetailPage(data: CustomPageData.CommonContentCollection) {
                            viewModel.navigateToCommonCollectionDetailPage(data)
                        }

                    })

            FOLLOW_ITEM_TYPE_POST_CARD -> {
                FollowPostCardViewHolder(
                    parent.toBinding(),
                    pageConfiguration.entrance,
                    pageConfiguration.path
                )
            }

            FOLLOW_ITEM_TYPE_GIFT_PACK -> {
                GiftPackViewHolder(parent.toBinding(), object : GiftPackViewHolder.OnChildEventListener {
                    override fun onGameClick(game: GameEntity) {
                        viewModel.navigateToGameDetailPage(0, game, "礼包")
                    }

                    override fun onGiftPackageClick(libaoEntity: LibaoEntity) {
                        SensorsBridge.trackFollowPageContentClick("游戏礼包", libaoEntity.name ?: "")
                        viewModel.navigateToLibaoDetailPage(libaoEntity)
                    }


                    override fun onCopy(code: String) {
                        viewModel.copyExchangeCode(code)
                    }

                })
            }

            FOLLOW_ITEM_TYPE_ARTICLE -> {
                GameArticleViewHolder(parent.toBinding(), object : GameArticleViewHolder.OnChildEventListener {
                    override fun onGameCLick(game: GameEntity) {
                        viewModel.navigateToGameDetailPage(0, game, "关注-文章")
                    }

                    override fun onArticleClick(article: FollowDynamicEntity.Article) {
                        SensorsBridge.trackFollowPageContentClick("文章", article.title)
                        viewModel.navigateToNewsDetailPage(article.id)
                    }

                    override fun onComment(article: FollowDynamicEntity.Article) {
                        SensorsBridge.trackFollowPageContentClick("文章", article.title)
                        viewModel.navigateToArticleCommentDetailPage(article.id)
                    }

                    override fun onShare(concernEntity: ConcernEntity) {
                        viewModel.onShareArticle(concernEntity)
                    }

                })
            }

            FOLLOW_ITEM_TYPE_FOOTER -> FollowFooterViewHolder(parent.toBinding())

            FOLLOW_ITEM_TYPE_EMPTY -> {
                FollowHomeEmptyViewHolder(parent.toBinding())
            }

            else -> FollowInvalidViewHolder(parent.toBinding())
        }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        when (holder) {

            is FollowHomeHeaderViewHolder -> {
                getRealTypeItem<FollowUserItem>(position) {
                    holder.bind(it.isLogin, it.data)
                }
            }

            is FollowRecommendListViewHolder -> {
                getRealTypeItem<FollowRecommendUsersItem>(position) {
                    holder.bindView(it.data)
                }

            }

            is FollowHomeSlideListViewHolder -> {
                getRealTypeItem<FollowCommonCollectionItem>(position) {
                    holder.bindView(it.data)
                }

            }

            is FollowHomeSlideWithCardsViewHolder -> {
                getRealTypeItem<FollowCommonCollectionItem>(position) {
                    holder.bindView(it.data)
                }

            }

            is FollowNavigationViewHolder -> {
                getRealTypeItem<FollowCommonCollectionItem>(position) {
                    holder.bindView(it.data)
                }
            }

            is FollowHomeRecommendItemViewHolder -> {
                getRealTypeItem<FollowCommonCollectionItem>(position) {
                    holder.bindView(it.data)
                }
            }

            is FollowCommonCollectionViewHolder -> {
                getRealTypeItem<FollowCommonCollectionItem>(position) {
                    holder.bindView(it.data)
                }

            }

            is FollowCommonCollection12ViewHolder -> {
                getRealTypeItem<FollowSplitCommonContentCollectionItem>(position) {
                    holder.bind(it.data, it.leftPosition)
                }
            }

            is FollowPostCardViewHolder -> {
                getRealTypeItem<FollowPostCardItem>(position) {
                    setItemViewBackground(holder)
                    holder.bind(it.data, position)
                }

            }

            is GameArticleViewHolder -> {
                getRealTypeItem<FollowArticleItem>(position) {
                    setItemViewBackground(holder)
                    holder.bind(it.data)
                }
            }

            is GiftPackViewHolder -> {
                getRealTypeItem<FollowGiftPackItem>(position) {
                    setItemViewBackground(holder)
                    holder.bind(it.libao, it.time)
                }
            }

            is FollowFooterViewHolder -> {
                holder.initFooterViewHolder(
                    loadStatus == LoadStatus.LIST_LOADING,
                    loadStatus == LoadStatus.LIST_FAILED,
                    loadStatus == LoadStatus.LIST_OVER,
                    R.string.load_over_with_click_hint
                ) {
                    if (loadStatus == LoadStatus.LIST_OVER) {
                        _recyclerView?.scrollToPosition(0)
                    } else if (loadStatus == LoadStatus.LIST_FAILED) {
                        viewModel.loadMore()
                        notifyItemChanged(itemCount - 1)
                    }
                }
            }

            else -> Unit
        }
    }

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

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

    override fun onViewAttachedToWindow(holder: ViewHolder) {
        if (holder is OnViewHolderAttachListener) {
            holder.onViewAttach(_recyclerView)
        }

    }

    override fun onViewDetachedFromWindow(holder: ViewHolder) {
        if (holder is OnViewHolderAttachListener) {
            holder.onViewDetach(_recyclerView)
        }

    }

    override fun getSyncData(position: Int): Pair<String, Any>? {
        if (position >= itemCount) return null
        val item = getItem(position)
        return when {
            item is FollowPostCardItem -> {
                Pair(item.data.id, item.data.count)
            }

            else -> null
        }
    }

    private inline fun <T> getRealTypeItem(position: Int, block: (T) -> Unit) {
        val item = getItem(position)
        (item as? T)?.let(block)
    }

    fun notifyFollowUserChanged(change: EBUserFollow) {
        val position = currentList.indexOfFirst { it is FollowRecommendUsersItem }
        notifyItemChanged(position, change)
    }

    fun notifyFollowUserReadStatus(ids: List<String>) {
        val position = currentList.indexOfFirst { it is FollowUserItem }
        notifyItemChanged(position, ReadStatusUpdate(ids))
    }

    private val onLoadMoreListener = object : RecyclerView.OnScrollListener() {
        override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
            super.onScrollStateChanged(recyclerView, newState)
            if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                val layoutManger = recyclerView.layoutManager
                if (layoutManger is LinearLayoutManager) {
                    val lastVisibleItemPosition = layoutManger.findLastVisibleItemPosition()
                    if (lastVisibleItemPosition == itemCount - 1 && loadStatus != LoadStatus.LIST_OVER && loadStatus != LoadStatus.LIST_LOADING) {
                        viewModel.loadMore()
                    }
                }
            }
        }

    }

    companion object {

        fun createItemCallback() = object : ItemCallback<FollowItem>() {
            override fun areItemsTheSame(oldItem: FollowItem, newItem: FollowItem): Boolean {
                return oldItem.areItemsTheSame(newItem)
            }

            override fun areContentsTheSame(oldItem: FollowItem, newItem: FollowItem): Boolean {
                return oldItem.areContentsTheSame(newItem)
            }
        }

        fun setItemViewBackground(viewHolder: ViewHolder) {
            if (viewHolder.bindingAdapterPosition == 1) {
                viewHolder.itemView.setBackgroundResource(com.gh.gamecenter.common.R.drawable.background_shape_white_radius_12_top_only)
            } else {
                viewHolder.itemView.setBackgroundColor(com.gh.gamecenter.common.R.color.ui_surface.toColor(viewHolder.itemView.context))
            }
        }
    }

    data class ReadStatusUpdate(
        val ids: List<String>
    )

}