package com.gh.gamecenter.home.slide

import android.annotation.SuppressLint
import android.graphics.drawable.GradientDrawable
import android.view.MotionEvent
import android.view.View
import androidx.core.graphics.ColorUtils
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.PagerSnapHelper
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2
import com.gh.gamecenter.feature.exposure.ExposureSource
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.BaseRecyclerViewHolder
import com.gh.gamecenter.common.utils.hexStringToIntColor
import com.gh.gamecenter.common.utils.safelyGetInRelease
import com.gh.gamecenter.common.utils.throwExceptionInDebug
import com.gh.gamecenter.common.utils.toColor
import com.gh.gamecenter.common.view.DrawableView
import com.gh.gamecenter.common.view.FixLinearLayoutManager
import com.gh.gamecenter.common.view.ScrollEventListener
import com.gh.gamecenter.common.view.TouchSlopRecyclerView
import com.gh.gamecenter.core.utils.MtaHelper
import com.gh.gamecenter.databinding.HomeSlideListBinding
import com.gh.gamecenter.home.HomeItemData
import kotlin.math.abs

class HomeSlideListViewHolder(
    val binding: HomeSlideListBinding,
    val callback: (colorStr: Int) -> Unit
) :
    BaseRecyclerViewHolder<Any>(binding.root) {

    private var mLastX: Int = 0
    private var mLastY: Int = 0

    private var mSnapHelper: PagerSnapHelper? = null

    @SuppressLint("ClickableViewAccessibility")
    fun bindSlideList(itemData: HomeItemData, basicExposureSource: List<ExposureSource>) {
        val slideList = itemData.slides!!
        val context = binding.recyclerView.context
        var adapter = binding.recyclerView.adapter

        itemData.exposureEventList = itemData.exposureEventList ?: arrayListOf()

        if (adapter is HomeSlideListAdapter) {
            adapter.itemData = itemData
            adapter.checkResetData(slideList)

            val layoutManager = binding.recyclerView.layoutManager
            if (layoutManager != null) {
                val view = mSnapHelper?.findSnapView(layoutManager)
                var curPosition = 0
                if (view != null) {
                    curPosition = adapter.getActualPosition(layoutManager.getPosition(view))
                }
                updateImmersiveColor(
                    slideList.safelyGetInRelease(curPosition)?.placeholderColor?.hexStringToIntColor()
                        ?: R.color.background_white.toColor(binding.root.context)
                )
            }

            // 刷新页面时有可能动画会出现混乱
            binding.recyclerView.postDelayed({ updateZoomAnimation() }, 200)
            return
        }

        mSnapHelper = PagerSnapHelper()
        val layoutManager = FixLinearLayoutManager(context, RecyclerView.HORIZONTAL, false)
        adapter = HomeSlideListAdapter(
            context,
            itemData,
            layoutManager,
            mSnapHelper!!,
            binding.recyclerView,
            basicExposureSource
        )
        (binding.recyclerView.itemAnimator as DefaultItemAnimator).supportsChangeAnimations = false
        binding.recyclerView.layoutManager = layoutManager
        binding.recyclerView.adapter = adapter
        binding.recyclerView.addOnAttachStateChangeListener(object : View.OnAttachStateChangeListener {
            override fun onViewAttachedToWindow(v: View) {
                // do nothing
            }

            override fun onViewDetachedFromWindow(v: View) {
                adapter.stopScroll()
            }
        })
        binding.recyclerView.onFlingListener = null
        binding.recyclerView.isNestedScrollingEnabled = false
        binding.recyclerView.scrollToPosition(adapter.getActualFirstPositionInCenter())
        mSnapHelper?.attachToRecyclerView(binding.recyclerView)
        binding.recyclerView.addOnItemTouchListener(object :
            RecyclerView.SimpleOnItemTouchListener() {
            override fun onInterceptTouchEvent(rv: RecyclerView, e: MotionEvent): Boolean {
                val x = e.x.toInt()
                val y = e.y.toInt()

                when (e.action) {
                    MotionEvent.ACTION_DOWN -> {
                        mLastX = e.x.toInt()
                        mLastY = e.y.toInt()
                        rv.parent.parent.requestDisallowInterceptTouchEvent(true)
                    }
                    MotionEvent.ACTION_UP -> rv.parent.parent.requestDisallowInterceptTouchEvent(
                        false
                    )
                    MotionEvent.ACTION_MOVE -> {
                        val deltaX: Int = x - mLastX
                        val deltaY: Int = y - mLastY
                        val isHorizontalScroll = abs(deltaX) > abs(deltaY)
                        rv.parent.parent.requestDisallowInterceptTouchEvent(isHorizontalScroll)
                    }
                }

                val isStop =
                    e.action == MotionEvent.ACTION_DOWN || e.action == MotionEvent.ACTION_MOVE
                if (isStop) adapter.stopScroll() else adapter.startScroll()

                val touchSlopRecyclerView = binding.recyclerView.parent.parent
                if (touchSlopRecyclerView is TouchSlopRecyclerView) {
                    touchSlopRecyclerView.touchSlopEnabled = isStop
                } else throwExceptionInDebug("TouchSlopRecyclerView not found")
                return false
            }
        })
        updateImmersiveColor(slideList[0].placeholderColor.hexStringToIntColor())

        binding.recyclerView.addOnScrollListener(ScrollEventListener(binding.recyclerView).apply {
            setOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
                var lastStatePosition = -1
                var lastScrollState = RecyclerView.SCROLL_STATE_IDLE

                override fun onPageScrollStateChanged(state: Int) {
                    super.onPageScrollStateChanged(state)

                    if (scrollState == RecyclerView.SCROLL_STATE_IDLE) {
                        val view = mSnapHelper?.findSnapView(layoutManager)
                        var curPosition = 0
                        if (view != null) {
                            curPosition = adapter.getActualPosition(layoutManager.getPosition(view))
                        }
                        if (lastScrollState == RecyclerView.SCROLL_STATE_DRAGGING && curPosition != lastStatePosition) {
                            MtaHelper.onEvent(
                                "首页_新",
                                "轮播_滑动",
                                if (curPosition > lastStatePosition) "左滑" else "右滑"
                            )
                        }
                        lastStatePosition = curPosition
                        lastScrollState = scrollState
                        updateImmersiveColor(
                            slideList.safelyGetInRelease(curPosition)?.placeholderColor?.hexStringToIntColor()
                                ?: R.color.background_white.toColor(binding.root.context)
                        )
                    } else if (scrollState == RecyclerView.SCROLL_STATE_DRAGGING) {
                        lastScrollState = scrollState
                    }
                }

                override fun onPageScrolled(
                    position: Int,
                    positionOffset: Float,
                    positionOffsetPixels: Int
                ) {
                    val currentPosition = adapter.getActualPosition(position)
                    val nextPosition = adapter.getActualPosition(position + 1)

                    val currentColor =
                        slideList.safelyGetInRelease(currentPosition)?.placeholderColor?.hexStringToIntColor()
                            ?: R.color.background_white.toColor(binding.root.context)
                    val nextColor = slideList.safelyGetInRelease(nextPosition)?.placeholderColor?.hexStringToIntColor()
                        ?: currentColor

                    val colorInBetween =
                        ColorUtils.blendARGB(currentColor, nextColor, positionOffset)

                    updateZoomAnimation()
                    updateImmersiveColor(colorInBetween)
                }
            })
        })
    }

    private fun updateImmersiveColor(color: Int) {
        callback.invoke(color)
        val gradientDrawable = DrawableView.getGradientDrawable(
            color,
            R.color.background_white.toColor(binding.root.context), GradientDrawable.Orientation.TOP_BOTTOM, 0f
        )
        binding.placeholderView.background = gradientDrawable
    }

    // 缩放控制
    fun updateZoomAnimation() {
        val childCount = binding.recyclerView.childCount
        val width = binding.recyclerView.getChildAt(0)?.width ?: return
        val padding = (binding.recyclerView.width - width) / 2

        for (j in 0 until childCount) {
            val v = binding.recyclerView.getChildAt(j)
            var rate = 0f
            if (v.left <= padding) { // left
                rate = if (v.left >= padding - v.width) {
                    (padding - v.left) * 1f / v.width
                } else {
                    1f
                }
                v.scaleY = 1 - rate * 0.1f
            } else { // right
                if (v.left <= binding.recyclerView.width - padding) {
                    rate = (binding.recyclerView.width - padding - v.left) * 1f / v.width
                }
                v.scaleY = 0.9f + rate * 0.1f
            }
        }
    }
}