package com.gh.gamecenter.catalog

import android.annotation.SuppressLint
import android.content.Context
import android.util.SparseArray
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.LinearLayout
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.gh.gamecenter.common.base.BaseRecyclerViewHolder
import com.gh.gamecenter.common.constant.ItemViewType
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.exposure.ExposureSource
import com.gh.common.exposure.IExposable
import com.gh.common.util.*
import com.gh.gamecenter.R
import com.gh.gamecenter.common.viewholder.FooterViewHolder
import com.gh.gamecenter.common.baselist.ListAdapter
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.utils.PageSwitchDataHelper
import com.gh.gamecenter.databinding.*
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.entity.SpecialCatalogEntity
import com.gh.gamecenter.subject.SubjectActivity.Companion.startSubjectActivity

class SpecialCatalogAdapter(
    context: Context,
    private val mCatalogViewModel: SpecialCatalogViewModel,
    private val mLastPageDataMap: HashMap<String, String>? = null
) : ListAdapter<SpecialCatalogItemData>(context), IExposable {

    private val mExposureEventSparseArray: SparseArray<ExposureEvent> = SparseArray()
    var isAutoScroll = true
    var isBannerSizeMoreThanOne = false

    override fun getItemCount() = if (mEntityList.isNullOrEmpty()) 0 else mEntityList.size + FOOTER_ITEM_COUNT

    override fun areItemsTheSame(oldItem: SpecialCatalogItemData?, newItem: SpecialCatalogItemData?): Boolean {
        return when {
            oldItem?.banner != null && newItem?.banner != null -> {
                var oldIds = ""
                var newIds = ""
                oldItem.banner.data.forEach { oldIds += it.id }
                newItem.banner.data.forEach { newIds += it.id }
                oldIds == newIds

            }

            oldItem?.header != null && newItem?.header != null -> {
                oldItem.header.id == newItem.header.id
            }

            oldItem?.bigImage != null && newItem?.bigImage != null -> {
                oldItem.bigImage.id == newItem.bigImage.id
            }

            oldItem?.subject != null && newItem?.subject != null -> {
                oldItem.subject.id == newItem.subject.id
            }

            oldItem?.subjectCollection != null && newItem?.subjectCollection != null -> {
                oldItem.subjectCollection.id == newItem.subjectCollection.id
            }

            else -> super.areItemsTheSame(oldItem, newItem)
        }
    }

    override fun areContentsTheSame(oldItem: SpecialCatalogItemData?, newItem: SpecialCatalogItemData?): Boolean {
        return when {
            oldItem?.banner != null && newItem?.banner != null -> {
                var oldIds = ""
                var newIds = ""
                oldItem.banner.data.forEach { oldIds += it.id }
                newItem.banner.data.forEach { newIds += it.id }
                oldIds == newIds

            }

            oldItem?.bigImage != null && newItem?.bigImage != null -> {
                oldItem.bigImage.id == newItem.bigImage.id
            }

            oldItem?.subject != null && newItem?.subject != null -> {
                oldItem.subject.id == newItem.subject.id
            }

            oldItem?.subjectCollection != null && newItem?.subjectCollection != null -> {
                oldItem.subjectCollection.id == newItem.subjectCollection.id
            }

            else -> super.areItemsTheSame(oldItem, newItem)
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        val view: View
        return when (viewType) {
            ItemViewType.ITEM_FOOTER -> {
                view = mLayoutInflater.inflate(R.layout.refresh_footerview, parent, false)
                FooterViewHolder(view)
            }

            TYPE_BANNER -> CatalogBannerItemHolder(parent.toBinding())

            TYPE_HEADER -> CatalogHeaderItemHolder(parent.toBinding())

            TYPE_BIG_IMAGE -> CatalogImageItemHolder(parent.toBinding())

            TYPE_SUBJECT -> CatalogSubjectItemHolder(parent.toBinding())

            TYPE_SUBJECT_COLLECTION -> CatalogSubjectCollectionItemHolder(parent.toBinding())

            else -> throw NullPointerException()
        }
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        when (holder) {
            is CatalogBannerItemHolder -> {
                val itemData = mEntityList[position]!!
                isBannerSizeMoreThanOne = itemData.banner!!.data.size > 1
                holder.bindBanners(itemData, mLastPageDataMap)
            }

            is CatalogImageItemHolder -> {
                val imageEntity = mEntityList[position].bigImage!!
                holder.binding.run {
                    image.layoutParams = image.layoutParams.apply {
                        val imageWidth = mContext.resources.displayMetrics.widthPixels - (80F + 16F + 16F).dip2px()
                        height = imageWidth / 2
                    }

                    ImageUtils.display(image, imageEntity.image.url)
                    title.text = imageEntity.image.title

                    var exposureEvent: ExposureEvent? = null
                    if (imageEntity.link.type == "game") {
                        exposureEvent = ExposureEvent.createEventWithSourceConcat(
                            GameEntity(id = imageEntity.link.link, name = imageEntity.link.text).apply {
                                outerSequence = mEntityList[position].position
                            },
                            mCatalogViewModel.basicExposureSource,
                            listOf(ExposureSource("精选页图片", ""))
                        ).apply {
                            mLastPageDataMap?.let {
                                payload.sourcePage = it[PageSwitchDataHelper.PAGE_BUSINESS_TYPE]
                                payload.sourcePageId = it[PageSwitchDataHelper.PAGE_BUSINESS_ID]
                                payload.sourcePageName = it[PageSwitchDataHelper.PAGE_BUSINESS_NAME]
                            }
                        }
                        mExposureEventSparseArray.append(position, exposureEvent)
                    }
                    root.setOnClickListener {
                        DirectUtils.directToLinkPage(mContext, imageEntity.link, "新分类-精选分类", "图片", exposureEvent)
                        mCatalogViewModel.logSpecialCatalogContentClick(
                            "图片",
                            imageEntity.image.title,
                            mEntityList[position].position
                        )
                    }
                }
            }

            is CatalogHeaderItemHolder -> {
                val entity = mEntityList[position].header!!
                val specialLink = entity.link
                holder.binding.run {
                    headTitle.text = specialLink.text
                    headTitle.setTextColor(R.color.text_title.toColor(mContext))
                    headMore.setTextColor(R.color.theme_font.toColor(mContext))
                    headMore.setOnClickListener {
                        if (entity.type == "专题合集") {
                            DirectUtils.directToColumnCollection(
                                mContext, specialLink.link ?: "", -1, "(游戏-专题:" + specialLink.text + "-全部)"
                            )
                        } else {
                            startSubjectActivity(
                                mContext,
                                specialLink.link,
                                specialLink.text,
                                false,
                                "(游戏-专题:" + specialLink.text + "-全部)"
                            )
                        }
                        mCatalogViewModel.logSpecialCatalogContentClick(
                            entity.type, specialLink.text
                                ?: "", mEntityList[position].position
                        )
                    }
                }
            }

            is CatalogSubjectItemHolder -> {
                val subject = mEntityList[position].subject!!

                val exposureList = arrayListOf<ExposureEvent>()
                for ((index, game) in subject.link.data.withIndex()) {
                    game.sequence = index
                    game.subjectName = subject.link.text
                    game.outerSequence = mEntityList[position].position

                    val exposureEvent = ExposureEvent.createEventWithSourceConcat(
                        game,
                        mCatalogViewModel.basicExposureSource,
                        listOf(ExposureSource("精选页专题", subject.link.text ?: ""))
                    ).apply {
                        mLastPageDataMap?.let {
                            payload.sourcePage = it[PageSwitchDataHelper.PAGE_BUSINESS_TYPE]
                            payload.sourcePageId = it[PageSwitchDataHelper.PAGE_BUSINESS_ID]
                            payload.sourcePageName = it[PageSwitchDataHelper.PAGE_BUSINESS_NAME]
                        }
                    }
                    exposureList.add(exposureEvent)

                    game.exposureEvent = exposureEvent
                }
                mEntityList[position].exposureEventList = exposureList

                holder.bindSubject(subject.link.data, mEntityList[position].position)
            }

            is CatalogSubjectCollectionItemHolder -> {
                val subjectCollection = mEntityList[position].subjectCollection!!

                for (subject in subjectCollection.link.data) {
                    subject.subjectName = subjectCollection.link.text
                }

                holder.bindSubjectCollection(subjectCollection.link.data, mEntityList[position].position)
            }

            is FooterViewHolder -> {
                holder.initFooterViewHolder(mIsLoading, mIsNetworkError, mIsOver)
            }
        }
    }

    override fun getItemViewType(position: Int): Int {
        return if (position == itemCount - 1) {
            ItemViewType.ITEM_FOOTER
        } else {
            val item = mEntityList[position]
            when {
                item.banner != null -> TYPE_BANNER
                item.header != null -> TYPE_HEADER
                item.bigImage != null -> TYPE_BIG_IMAGE
                item.subject != null -> TYPE_SUBJECT
                else -> TYPE_SUBJECT_COLLECTION
            }
        }
    }

    override fun getEventByPosition(pos: Int): ExposureEvent? = mExposureEventSparseArray.get(pos)

    override fun getEventListByPosition(pos: Int): List<ExposureEvent>? = mEntityList[pos].exposureEventList

    inner class CatalogBannerItemHolder(val binding: CatalogBannerItemBinding) :
        BaseRecyclerViewHolder<Any>(binding.root) {

        fun bindBanners(itemData: SpecialCatalogItemData, lastPageDataMap: HashMap<String, String>?) {
            val banners = itemData.banner!!.data
            val pagerAdapter = binding.viewPager.adapter
            when {
                banners.isNotEmpty()
                        && (pagerAdapter == null
                        || pagerAdapter is BannerAdapter
                        && pagerAdapter.getDataSize() != banners.size) -> initBanners(
                    itemData,
                    banners,
                    lastPageDataMap
                )
                banners.isNotEmpty() && pagerAdapter != null -> (pagerAdapter as BannerAdapter).checkResetData(itemData)
                banners.isEmpty() -> binding.viewPager.adapter = null
            }

            itemView.visibility = if (banners.isEmpty()) View.GONE else View.VISIBLE
            if (isAutoScroll) {
                binding.viewPager.startAutoScroll()
            } else {
                binding.viewPager.stopAutoScroll()
            }
        }

        private fun initBanners(
            itemData: SpecialCatalogItemData,
            banners: List<SpecialCatalogEntity.Banner>,
            lastPageDataMap: HashMap<String, String>?
        ) {
            binding.root.layoutParams = binding.root.layoutParams.apply {
                val rootWidth = mContext.resources.displayMetrics.widthPixels - (80F + 16F + 16F).dip2px()
                height = rootWidth / 2
            }
            initIndicator(banners)
            initViewPager(itemData, banners, lastPageDataMap)
        }

        private fun initIndicator(banners: List<SpecialCatalogEntity.Banner>) {
            binding.indicatorContainer.run {
                if (banners.size > 1) {
                    removeAllViews()
                    var i = 0
                    val size = banners.size
                    while (i < size) {
                        addView(getIndicatorItemView(i))
                        i++
                    }
                }
            }
        }

        private fun getIndicatorItemView(index: Int): View {
            val view = View.inflate(mContext, R.layout.banner_indicator_item, null)
            view.findViewById<ImageView>(R.id.selectedIv).visibility = if (index == 0) View.VISIBLE else View.GONE
            view.findViewById<ImageView>(R.id.unSelectIv).visibility = if (index == 0) View.GONE else View.VISIBLE
            view.layoutParams = LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.WRAP_CONTENT,
                LinearLayout.LayoutParams.WRAP_CONTENT
            ).apply {
                if (index != 0) leftMargin = 4F.dip2px() else 0F.dip2px()
            }
            return view
        }

        private fun initViewPager(
            itemData: SpecialCatalogItemData,
            banners: List<SpecialCatalogEntity.Banner>,
            lastPageDataMap: HashMap<String, String>?
        ) {
            binding.viewPager.run {
                adapter = BannerAdapter(
                    mContext,
                    mCatalogViewModel,
                    itemData,
                    mCatalogViewModel.basicExposureSource,
                    lastPageDataMap
                )
                if (banners.size > 1) {
                    currentItem = banners.size * 10
                    interval = 3000L
                    startAutoScroll()

                    doOnPageSelected {
                        changeIndicatorForIndex(it)
                    }
                }

                setListener()
            }
        }

        private fun changeIndicatorForIndex(index: Int) {
            var j = 0
            val childCount = binding.indicatorContainer.childCount
            while (j < childCount) {
                binding.indicatorContainer.getChildAt(j).findViewById<ImageView>(R.id.selectedIv).visibility =
                    if (j == index % childCount) View.VISIBLE else View.GONE
                binding.indicatorContainer.getChildAt(j).findViewById<ImageView>(R.id.unSelectIv).visibility =
                    if (j == index % childCount) View.GONE else View.VISIBLE
                j++
            }
        }

        @SuppressLint("ClickableViewAccessibility")
        private fun setListener() {
            binding.viewPager.run {
                setOnTouchListener { _, event ->
                    if (isBannerSizeMoreThanOne && isAutoScroll) {
                        if (event.action == MotionEvent.ACTION_DOWN || event.action == MotionEvent.ACTION_MOVE) {
                            stopAutoScroll()
                        } else {
                            startAutoScroll()
                        }
                    }
                    false
                }
            }
        }
    }

    inner class CatalogImageItemHolder(val binding: CatalogImageItemBinding) : BaseRecyclerViewHolder<Any>(binding.root)

    inner class CatalogHeaderItemHolder(val binding: CatalogHeaderItemBinding) :
        BaseRecyclerViewHolder<Any>(binding.root)

    inner class CatalogSubjectItemHolder(val binding: CatalogSubjectItemBinding) :
        BaseRecyclerViewHolder<Any>(binding.root) {

        fun bindSubject(gameList: List<GameEntity>, position: Int) {
            binding.gameList.run {
                var subjectAdapter = adapter
                if (subjectAdapter is SpecialCatalogSubjectAdapter) {
                    subjectAdapter.checkResetData(gameList)
                    subjectAdapter.updatePosition(position)
                    return
                }
                subjectAdapter = SpecialCatalogSubjectAdapter(context, mCatalogViewModel, gameList).apply {
                    updatePosition(position)
                }
                layoutManager = GridLayoutManager(context, 3)
                adapter = subjectAdapter
            }
        }
    }

    inner class CatalogSubjectCollectionItemHolder(val binding: CatalogSubjectCollectionItemBinding) :
        BaseRecyclerViewHolder<Any>(binding.root) {

        fun bindSubjectCollection(subjectCollection: List<GameEntity>, position: Int) {
            binding.subjectCollectionList.run {
                var collectionAdapter = adapter
                if (collectionAdapter is SpecialCatalogSubjectCollectionAdapter) {
                    collectionAdapter.checkResetData(subjectCollection)
                    collectionAdapter.updatePosition(position)
                    return
                }
                collectionAdapter =
                    SpecialCatalogSubjectCollectionAdapter(context, mCatalogViewModel, subjectCollection).apply {
                        updatePosition(position)
                    }
                layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
                adapter = collectionAdapter
            }
        }
    }

    companion object {
        private const val TYPE_HEADER = 900

        private const val TYPE_BIG_IMAGE = 901

        private const val TYPE_SUBJECT = 902

        private const val TYPE_SUBJECT_COLLECTION = 903

        private const val TYPE_BANNER = 904
    }
}