package com.gh.common.view

import android.content.Context
import android.util.AttributeSet
import android.view.*
import android.widget.LinearLayout
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2
import com.facebook.drawee.view.SimpleDraweeView
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.common.utils.ImageUtils
import com.gh.gamecenter.common.utils.rxTimer
import com.gh.gamecenter.R
import com.gh.gamecenter.entity.SettingsEntity
import io.reactivex.disposables.Disposable
import kotlin.math.abs


/**
 * 视频流广告轮播控件
 */
class AdBannerView : LinearLayout {

    private lateinit var mViewPager2: ViewPager2
    private var mDatas = ArrayList<SettingsEntity.Advertisement>()
    var isAutoPlay = true
    private var currentPage = 0
    private var autoDurationTime = 6000L
    private var mRxTimer: Disposable? = null
    private var lastX: Float = 0F
    private var lastY: Float = 0F
    private var startX: Float = 0F
    private var startY: Float = 0F
    private val mTouchSlop = ViewConfiguration.get(context).scaledTouchSlop
    private val bannerWidth = DisplayUtils.dip2px(52f)
    var onItemClick: ((position: Int) -> Unit)? = null
    private lateinit var mIndicatorLayout: LinearLayout

    constructor(context: Context) : super(context)
    constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)

    init {
        initViews()
    }

    private fun initViews() {
        orientation = VERTICAL
        mViewPager2 = ViewPager2(context).apply {
            layoutParams = ViewGroup.LayoutParams(bannerWidth, bannerWidth)
            orientation = ViewPager2.ORIENTATION_HORIZONTAL
            registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
                override fun onPageSelected(position: Int) {
                    super.onPageSelected(position)
                    currentPage = position
                    slideIndicator(currentPage % mDatas.size)
                }
            })
        }
        val recyclerView = mViewPager2.getChildAt(0) as RecyclerView
        recyclerView.overScrollMode = RecyclerView.OVER_SCROLL_NEVER
        addView(mViewPager2)
        mIndicatorLayout = LinearLayout(context).apply {
            orientation = HORIZONTAL
            gravity = Gravity.CENTER
            val params = LayoutParams(LayoutParams.MATCH_PARENT, DisplayUtils.dip2px(5F))
            params.topMargin = DisplayUtils.dip2px(8f)
            layoutParams = params
        }
        addView(mIndicatorLayout)
    }


    fun start(datas: ArrayList<SettingsEntity.Advertisement>) {
        if (datas.isNullOrEmpty()) throw IllegalArgumentException("广告列表不能为空")
        val adapter = mViewPager2.adapter
        mDatas = datas
        if (adapter == null) {
            val bannerAdapter = AdBannerAdapter()
            mViewPager2.adapter = bannerAdapter
        } else {
            adapter.notifyDataSetChanged()
        }
        currentPage = (mViewPager2.adapter as AdBannerAdapter).getActualFirstPositionInCenter()
        mViewPager2.setCurrentItem(currentPage, false)
        if (mDatas.size > 1) {
            addIndicator()
            slideIndicator(currentPage % mDatas.size)
            autoPlay()
        }
    }

    private fun autoPlay() {
        if (isAutoPlay && mDatas.size > 1) {
            if (mRxTimer != null && !mRxTimer!!.isDisposed) {
                mRxTimer?.dispose()
                mRxTimer = null
            }
            mRxTimer = rxTimer(autoDurationTime) {
                slidePage()
            }
        }
    }


    private fun slidePage() {
        currentPage++
        mViewPager2.setCurrentItem(currentPage, true)
    }

    fun resumePage() {
        autoPlay()
    }

    fun pausePage() {
        if (mRxTimer != null && !mRxTimer!!.isDisposed) {
            mRxTimer?.dispose()
            mRxTimer = null
        }
    }

    private fun addIndicator() {
        mIndicatorLayout.removeAllViews()
        mDatas.forEach { _ ->
            val view = View(context).apply {
                background = ContextCompat.getDrawable(context, R.drawable.selector_video_detail_ad_indicator)
                val params = LayoutParams(DisplayUtils.dip2px(4F), DisplayUtils.dip2px(4F))
                params.leftMargin = DisplayUtils.dip2px(2F)
                params.rightMargin = DisplayUtils.dip2px(2F)
                layoutParams = params
            }
            mIndicatorLayout.addView(view)
        }
    }

    private fun slideIndicator(position: Int) {
        for (i in 0 until mIndicatorLayout.childCount) {
            val childAt = mIndicatorLayout.getChildAt(i)
            childAt.isSelected = i == position
        }
    }

    override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
        val action = ev.action
        if (action == MotionEvent.ACTION_DOWN) {
            lastX = ev.rawX
            startX = lastX
            lastY = ev.rawY
            startY = lastY
        } else if (action == MotionEvent.ACTION_MOVE) {
            lastX = ev.rawX
            lastY = ev.rawY
            val distanceX = abs(lastX - startX)
            val distanceY = abs(lastY - startY)
            val disallowIntercept: Boolean
            disallowIntercept = if (mViewPager2.orientation == ViewPager2.ORIENTATION_HORIZONTAL) {
                distanceX > mTouchSlop && distanceX > distanceY
            } else {
                distanceY > mTouchSlop && distanceY > distanceX
            }
            parent.requestDisallowInterceptTouchEvent(disallowIntercept)
        } else if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
            return abs(lastX - startX) > mTouchSlop || abs(lastY - startY) > mTouchSlop
        }
        return super.onInterceptTouchEvent(ev)
    }

    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        if (mRxTimer != null && !mRxTimer!!.isDisposed) {
            mRxTimer?.dispose()
            mRxTimer = null
        }
    }

    fun getAdDatas(): ArrayList<SettingsEntity.Advertisement> {
        return mDatas
    }


    private inner class AdBannerAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
            return object :
                RecyclerView.ViewHolder(LayoutInflater.from(context).inflate(R.layout.item_ad_banner, parent, false)) {}
        }

        override fun getItemCount(): Int = if (mDatas.size == 1) mDatas.size else Int.MAX_VALUE

        override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
            val ad = mDatas[position % mDatas.size]
            val view = holder.itemView as SimpleDraweeView
            ImageUtils.display(view, ad.image)
            holder.itemView.setOnClickListener {
                onItemClick?.invoke(position % mDatas.size)
            }
        }

        fun getActualFirstPositionInCenter(): Int {
            if (mDatas.size == 1) return 0
            var index = itemCount / 2
            if (index % mDatas.size != 0) {
                index -= (index % mDatas.size)
            }
            return index - 1
        }
    }

}