package com.gh.gamecenter.gamecollection.square

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Color
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.PagerSnapHelper
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2
import com.gh.gamecenter.common.base.activity.BaseActivity
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.common.utils.ImageUtils.display
import com.gh.common.exposure.*
import com.gh.common.util.NewLogUtils
import com.gh.gamecenter.GameDetailActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.common.viewholder.FooterViewHolder
import com.gh.gamecenter.common.baselist.ListAdapter
import com.gh.gamecenter.common.baselist.LoadStatus
import com.gh.gamecenter.common.entity.ExposureEntity
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.view.ScrollEventListener
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.databinding.GameCollectionSquareItemBinding
import com.gh.gamecenter.databinding.ItemGameCollectionBannerBinding
import com.gh.gamecenter.entity.AmwayCommentEntity
import com.gh.gamecenter.entity.CarouselEntity
import com.gh.gamecenter.entity.GamesCollectionEntity
import com.gh.gamecenter.feature.exposure.ExposureType
import com.gh.gamecenter.gamecollection.detail.GameCollectionDetailActivity
import com.lightgame.view.NoScrollableViewPager
import java.lang.ref.WeakReference

class GameCollectionSquareAdapter(
    context: Context,
    private val isHome: Boolean = false,
    private val mViewModel: GameCollectionSquareViewModel,
    private var mBasicExposureSource: List<ExposureSource>,
    private val mOuterSequence: Int = -1
) :
    ListAdapter<GameCollectionListItemData>(context), IExposable {

    fun setAmwayList(amwayList: List<AmwayCommentEntity>) {
        if (isHome && mEntityList.isNotEmpty() && mEntityList[0].amwayListItem == null) {
            mEntityList[0].amwayListItem = amwayList
            notifyItemChanged(0)
        }
    }

    fun setBannerList(bannerList: List<CarouselEntity>) {
        if (isHome && mEntityList.isNotEmpty() && mEntityList[0].carouselListItem == null) {
            mEntityList[0].carouselListItem = bannerList
            notifyItemChanged(0)
        }
    }

    override fun areItemsTheSame(oldItem: GameCollectionListItemData?, newItem: GameCollectionListItemData?) =
        oldItem == newItem

    override fun areContentsTheSame(oldItem: GameCollectionListItemData?, newItem: GameCollectionListItemData?) =
        oldItem == newItem

    override fun getItemViewType(position: Int): Int {
        return if (position == itemCount - 1) {
            ItemViewType.ITEM_FOOTER
        } else {
            when {
                isHome && position == 0 -> ItemViewType.ITEM_HEADER

                else -> ItemViewType.ITEM_BODY
            }
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        return when (viewType) {
            ItemViewType.ITEM_HEADER -> GameCollectionBannerItemViewHolder(parent.toBinding())
            ItemViewType.ITEM_BODY -> GameCollectionSquareItemViewHolder(parent.toBinding())
            ItemViewType.ITEM_FOOTER -> FooterViewHolder(
                mLayoutInflater.inflate(
                    R.layout.refresh_footerview,
                    parent,
                    false
                )
            )
            else -> GameCollectionSquareItemViewHolder(parent.toBinding())
        }
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        when (holder) {
            is GameCollectionBannerItemViewHolder -> {
                val itemData = mEntityList[position]
                holder.bindBanner(itemData, mBasicExposureSource)
            }
            is GameCollectionSquareItemViewHolder -> {
                val itemData = mEntityList[position]
                val filterTagName = mViewModel.selectedTagName
                val exposureEventList = arrayListOf<ExposureEvent>()

                itemData.gameCollectionItem?.games?.take(3)?.forEachIndexed { index, game ->
                    exposureEventList.add(
                        ExposureEvent.createEventWithSourceConcat(
                            game.toGameEntity().apply {
                                isAdData = itemData.gameCollectionItem?.adIconActive ?: false
                                outerSequence = mOuterSequence;
                                sequence = itemData.gameStartPosition + index + 1
                            },
                            mBasicExposureSource,
                            listOf(
                                ExposureSource(
                                    "游戏单",
                                    if (isHome) "${itemData.gameCollectionItem?.title} + ${itemData.gameCollectionItem?.id}" else "${itemData.gameCollectionItem?.title} + ${itemData.gameCollectionItem?.id} + $filterTagName"
                                )
                            )
                        )
                    )
                }
                itemData.exposureEventList = exposureEventList
                itemData.gameCollectionItem?.let {
                    holder.bindGameCollection(mViewModel, it, itemData, isHome)
                }
            }
            is FooterViewHolder -> {
                holder.initItemPadding()
                holder.initFooterViewHolder(mViewModel, mIsLoading, mIsNetworkError, mIsOver)
                holder.hint.setTextColor(ContextCompat.getColor(mContext, R.color.text_B3B3B3))
                val lp = holder.itemView.layoutParams as RecyclerView.LayoutParams
                lp.height = DisplayUtils.dip2px(48F)
                lp.width = ViewGroup.LayoutParams.MATCH_PARENT
                holder.itemView.layoutParams = lp
            }
        }
    }

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

    class GameCollectionBannerItemViewHolder(val binding: ItemGameCollectionBannerBinding) :
        RecyclerView.ViewHolder(binding.root) {
        private lateinit var mBannerAdapter: GameCollectionBannerAdapter
        private lateinit var mSnapHelper: PagerSnapHelper
        private lateinit var mBannerLayoutManager: LinearLayoutManager
        private val mLooperHandle = LooperHandle(this)
        private val mSlideLooperKey = 111

        fun bindBanner(itemData: GameCollectionListItemData, mBasicExposureSource: List<ExposureSource>) {
            val context = binding.root.context
            val bannerList = itemData.carouselListItem ?: emptyList()
            val amwayListItem = itemData.amwayListItem

            if (::mBannerAdapter.isInitialized) {
                mBannerAdapter.submitList(bannerList, amwayListItem)
                itemData.exposureEventList = getExposureEventList(bannerList, mBasicExposureSource)

                if (mBannerAdapter.mBannerList.size != bannerList.size) {
                    binding.bannerIndicator.run {
                        mPageSize = mBannerAdapter.getActualSize()
                        notifyDataChanged()
                    }
                    if (mBannerAdapter.getActualSize() > 1) {
                        binding.bannerRv.scrollToPosition(mBannerAdapter.getActualFirstPositionInCenter())
                    }
                    startAutoPlay()
                }
                return
            }
            mSnapHelper = PagerSnapHelper()
            mBannerLayoutManager = LinearLayoutManager(context, RecyclerView.HORIZONTAL, false)
            mBannerAdapter = GameCollectionBannerAdapter(
                context,
                true,
                bannerList,
                amwayListItem,
                "顶部tab-游戏单广场",
                mBasicExposureSource
            )
            binding.bannerIndicator.run {
                mPageSize = mBannerAdapter.getActualSize()
                notifyDataChanged()
            }
            binding.bannerRv.run {
                adapter = mBannerAdapter
                layoutManager = mBannerLayoutManager
                mSnapHelper.attachToRecyclerView(this)
                addOnItemTouchListener(object : RecyclerView.SimpleOnItemTouchListener() {
                    override fun onInterceptTouchEvent(rv: RecyclerView, e: MotionEvent): Boolean {
                        val viewPager = parent.parent.parent.parent.parent.parent.parent.parent
                        when (e.action) {
                            MotionEvent.ACTION_DOWN -> {
                                if (viewPager is NoScrollableViewPager) {
                                    viewPager.setScrollable(false)
                                }
                            }
                            MotionEvent.ACTION_UP -> {
                                if (viewPager is NoScrollableViewPager) {
                                    viewPager.setScrollable(true)
                                }
                            }
                        }

                        val isStop = e.action == MotionEvent.ACTION_DOWN || e.action == MotionEvent.ACTION_MOVE
                        if (isStop) stopAutoPlay() else startAutoPlay()
                        return false
                    }
                })
                addOnScrollListener(ScrollEventListener(this).apply {
                    setOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
                        override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
                            super.onPageScrolled(position, positionOffset, positionOffsetPixels)
                            binding.bannerIndicator.onPageScrolled(
                                mBannerAdapter.getActualPosition(position),
                                positionOffset
                            )
                        }
                    })
                })
                if (mBannerAdapter.getActualSize() > 1) {
                    scrollToPosition(mBannerAdapter.getActualFirstPositionInCenter())
                }
                startAutoPlay()
            }
            itemData.exposureEventList = getExposureEventList(bannerList, mBasicExposureSource)
        }

        private fun getExposureEventList(bannerList: List<CarouselEntity>, mBasicExposureSource: List<ExposureSource>) =
            arrayListOf<ExposureEvent>().apply {
                bannerList.forEachIndexed { index, entity ->
                    val exposureEvent = ExposureEvent(
                        payload = ExposureEntity(
                            carouselId = entity.id,
                            sequence = index
                        ),
                        source = ArrayList(mBasicExposureSource).apply {
                            add(ExposureSource(k = "轮播图"))
                        },
                        event = ExposureType.EXPOSURE
                    )
                    add(exposureEvent)
                }
            }

        private fun scrollToNextPage() {
            val snapView = mSnapHelper.findSnapView(mBannerLayoutManager)
            if (snapView != null) {
                mBannerLayoutManager.smoothScrollToPosition(
                    binding.bannerRv,
                    null,
                    mBannerLayoutManager.getPosition(snapView) + 1
                )
            }
        }

        private fun startAutoPlay() {
            if (mBannerAdapter.getActualSize() <= 1) return
            stopAutoPlay()
            mLooperHandle.sendEmptyMessageDelayed(mSlideLooperKey, GameCollectionSquareFragment.BANNER_LOOP_TIME)
        }

        private fun stopAutoPlay() {
            mLooperHandle.removeMessages(mSlideLooperKey)
        }

        class LooperHandle(viewHolder: GameCollectionBannerItemViewHolder) : Handler(Looper.getMainLooper()) {
            private val mWeakReference: WeakReference<GameCollectionBannerItemViewHolder> = WeakReference(viewHolder)

            override fun handleMessage(msg: Message) {
                super.handleMessage(msg)
                val viewHolder = mWeakReference.get()
                if (viewHolder != null && msg.what == viewHolder.mSlideLooperKey) {
                    viewHolder.scrollToNextPage()
                    viewHolder.startAutoPlay()
                }
            }
        }
    }

    class GameCollectionSquareItemViewHolder(val binding: GameCollectionSquareItemBinding) :
        RecyclerView.ViewHolder(binding.root) {
        @SuppressLint("SetTextI18n")
        fun bindGameCollection(
            viewModel: GameCollectionSquareViewModel,
            gamesCollectionEntity: GamesCollectionEntity,
            itemData: GameCollectionListItemData,
            isHome: Boolean
        ) {
            binding.run {
                val context = root.context
                display(poster, gamesCollectionEntity.cover)
                display(userIv, gamesCollectionEntity.user?.icon)
                titleTv.text = gamesCollectionEntity.title
                gamesCollectionEntity.games?.take(3)?.forEachIndexed { index, game ->
                    when (index) {
                        0 -> iconIvOne.displayGameIcon(game.toGameEntity())
                        1 -> iconIvTwo.displayGameIcon(game.toGameEntity())
                        2 -> iconIvThree.displayGameIcon(game.toGameEntity())
                    }
                }
                gamesCollectionEntity.games?.size?.let {
                    iconIvOne.goneIf(it == 0)
                    iconIvTwo.goneIf(it < 2)
                    iconIvThree.goneIf(it < 3)
                }
                gamesCollectionEntity.count?.game?.let {
                    countTv.goneIf(it < 4 || gamesCollectionEntity.games?.size == 0)
                    countTv.text = "+ ${it - 3}"
                }
                gamesCollectionEntity.count?.hot?.let {
                    hotTv.text = if (it > 10000) "10000+" else it.toString()
                }
                userTv.text = gamesCollectionEntity.user?.name
                playedGameProgress.max = gamesCollectionEntity.count?.game ?: 0
                playedGameProgress.progress = gamesCollectionEntity.count?.playedGame ?: 0
                playedGameTv.text =
                    "玩过 ${gamesCollectionEntity.count?.playedGame ?: 0} / ${gamesCollectionEntity.count?.game ?: 0} 款"
                stampIv.goneIf(gamesCollectionEntity.stamp.isEmpty())
                stampIv.setBackgroundResource(if (gamesCollectionEntity.stamp == "official") R.drawable.ic_official else R.drawable.ic_chosen)
                tagContainer.removeAllViews()
                if (!gamesCollectionEntity.tags.isNullOrEmpty()) {
                    for ((index, tagEntity) in gamesCollectionEntity.tags!!.withIndex()) {
                        // 添加分隔线
                        if (index != 0) tagContainer.addView(View(context).apply {
                            layoutParams = ViewGroup.LayoutParams(1F.dip2px(), 14F.dip2px())
                            setBackgroundColor(Color.parseColor("#33FFFFFF"))
                        })
                        // 添加标签
                        tagContainer.addView(TextView(context).apply {
                            layoutParams = LinearLayout.LayoutParams(
                                LinearLayout.LayoutParams.WRAP_CONTENT,
                                LinearLayout.LayoutParams.WRAP_CONTENT
                            )
                            setPadding(if (index == 0) 0 else 6F.dip2px(), 0, 6F.dip2px(), 0)
                            text = tagEntity.name
                            setTextColor(R.color.white.toColor())
                            textSize = 10F
                        })
                    }
                }
                tagContainer.visibleIf(!CheckLoginUtils.isLogin() || gamesCollectionEntity.count?.game == 0)
                playedGamesContainer.visibleIf(CheckLoginUtils.isLogin() && gamesCollectionEntity.count?.game != 0)
                adLabelTv.goneIf(!gamesCollectionEntity.adIconActive)
                iconIvOne.setOnClickListener {
                    val game = gamesCollectionEntity.games?.get(0)
                    NewLogUtils.logClickGameCollectionGameIcon(
                        gamesCollectionEntity.title,
                        gamesCollectionEntity.id,
                        game?.name ?: "",
                        game?.id ?: ""
                    )
                    game?.id?.let { id ->
                        GameDetailActivity.startGameDetailActivity(
                            context,
                            id,
                            BaseActivity.mergeEntranceAndPath(viewModel.entrance, "游戏单广场"),
                            itemData.exposureEventList?.safelyGetInRelease(0)
                        )
                    }
                }
                iconIvTwo.setOnClickListener {
                    val game = gamesCollectionEntity.games?.get(1)
                    NewLogUtils.logClickGameCollectionGameIcon(
                        gamesCollectionEntity.title,
                        gamesCollectionEntity.id,
                        game?.name ?: "",
                        game?.id ?: ""
                    )
                    game?.id?.let { id ->
                        GameDetailActivity.startGameDetailActivity(
                            context,
                            id,
                            BaseActivity.mergeEntranceAndPath(viewModel.entrance, "游戏单广场"),
                            itemData.exposureEventList?.safelyGetInRelease(1)
                        )
                    }
                }
                iconIvThree.setOnClickListener {
                    val game = gamesCollectionEntity.games?.get(2)
                    NewLogUtils.logClickGameCollectionGameIcon(
                        gamesCollectionEntity.title,
                        gamesCollectionEntity.id,
                        game?.name ?: "",
                        game?.id ?: ""
                    )
                    game?.id?.let { id ->
                        GameDetailActivity.startGameDetailActivity(
                            context,
                            id,
                            BaseActivity.mergeEntranceAndPath(viewModel.entrance, "游戏单广场"),
                            itemData.exposureEventList?.safelyGetInRelease(2)
                        )
                    }
                }
                userContainer.setOnClickListener {
                    NewLogUtils.logClickGameCollectionAuthor(gamesCollectionEntity.title, gamesCollectionEntity.id)
                    DirectUtils.directToHomeActivity(
                        context,
                        gamesCollectionEntity.user?.id,
                        0,
                        viewModel.entrance,
                        "游戏单广场"
                    )
                }
                root.setOnClickListener {
                    NewLogUtils.logEnterGameCollectionDetail(gamesCollectionEntity.title, gamesCollectionEntity.id)
                    context.startActivity(
                        GameCollectionDetailActivity.getIntent(
                            context,
                            gamesCollectionEntity.id,
                            !isHome
                        )
                    )
                }
            }
        }
    }

    override fun getEventByPosition(pos: Int): ExposureEvent? {
        return mEntityList[pos].exposureEvent
    }

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

    override fun loadChange(status: LoadStatus?) {
        when (status) {
            LoadStatus.INIT_OVER, LoadStatus.LIST_OVER -> {
                mIsOver = true
                mIsNetworkError = false
                mIsLoading = false
            }
            LoadStatus.LIST_FAILED -> {
                mIsOver = false
                mIsNetworkError = true
                mIsLoading = false
            }
            LoadStatus.LIST_LOADED -> {
                mIsNetworkError = false
                mIsOver = false
                mIsLoading = false
            }
            LoadStatus.LIST_LOADING -> {
                mIsNetworkError = false
                mIsOver = false
                mIsLoading = true
            }
            LoadStatus.INIT -> {
                if (mEntityList != null) mEntityList.clear()
                mIsNetworkError = false
                mIsOver = false
                mIsLoading = false
                notifyDataSetChanged()
                return
            }
            else -> {
                //do nothing
            }
        }

        if (itemCount > 0 && status != LoadStatus.LIST_LOADED) notifyItemChanged(itemCount - 1)
    }
}