package com.gh.gamecenter.common.view

import android.annotation.SuppressLint
import android.content.Context
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.ViewGroup
import androidx.core.view.forEach
import com.google.android.material.tabs.TabLayout

class NoDefaultMinWidthTabLayout @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
    TabLayout(context, attrs) {
    private var isTouched = false
    private var scrollState = OnScrollListener.SCROLL_STATE_IDLE
    val isScrollStateIdle: Boolean
        get() = scrollState == OnScrollListener.SCROLL_STATE_IDLE

    var onScrollListener: OnScrollListener? = null

    private val handler = Handler(Looper.getMainLooper(), object : Handler.Callback {
        private var lastY = Int.MIN_VALUE

        override fun handleMessage(msg: Message): Boolean {
            if (msg.what == MSG_SCROLL) {
                val scrollY = scrollY
                if (!isTouched && lastY == scrollY) {
                    lastY = Int.MIN_VALUE
                    setScrollState(OnScrollListener.SCROLL_STATE_IDLE)
                } else {
                    lastY = scrollY
                    checkScrollIdle()
                }
                return true
            }
            return false
        }
    })

    private fun checkScrollIdle() {
        handler.removeMessages(MSG_SCROLL)
        handler.sendEmptyMessageDelayed(MSG_SCROLL, CHECK_SCROLL_IDLE_DELAY_MILLIS)
    }

    override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
        when (ev.action) {
            MotionEvent.ACTION_DOWN -> {
                isTouched = true
            }
            MotionEvent.ACTION_UP -> {
                isTouched = false
                checkScrollIdle()
            }
        }
        return super.onInterceptTouchEvent(ev)
    }

    @SuppressLint("ClickableViewAccessibility")
    override fun onTouchEvent(ev: MotionEvent): Boolean {
        when (ev.action) {
            MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                isTouched = false
                checkScrollIdle()
            }
        }
        return super.onTouchEvent(ev)
    }

    override fun onScrollChanged(l: Int, t: Int, oldl: Int, oldt: Int) {
        super.onScrollChanged(l, t, oldl, oldt)
        if (isTouched) {
            setScrollState(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL)
        } else {
            setScrollState(OnScrollListener.SCROLL_STATE_FLING)
            checkScrollIdle()
        }
        onScrollListener?.onScroll(this, isTouched, l, t, oldl, oldt)
    }

    private fun setScrollState(state: Int) {
        if (scrollState != state) {
            scrollState = state
            onScrollListener?.onScrollStateChanged(this, state)
        }
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        if (tabCount > 5) {
            val tabLayout = getChildAt(0) as ViewGroup
            val childCount = tabLayout.childCount
            if (childCount > 0) {
                val widthPixels = MeasureSpec.getSize(widthMeasureSpec)
                val tabMinWidth = widthPixels / childCount
                var remainderPixels = widthPixels % childCount
                tabLayout.forEach {
                    if (remainderPixels > 0) {
                        it.minimumWidth = tabMinWidth + 1
                        remainderPixels--
                    } else {
                        it.minimumWidth = tabMinWidth
                    }
                }
            }
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
    }

    companion object {
        private const val CHECK_SCROLL_IDLE_DELAY_MILLIS = 80L
        private const val MSG_SCROLL = 1
    }

    abstract class OnScrollListener {
        open fun onScrollStateChanged(view: NoDefaultMinWidthTabLayout, scrollState: Int) {}
        open fun onScroll(view: NoDefaultMinWidthTabLayout, isTouchScroll: Boolean, l: Int, t: Int, oldl: Int, oldt: Int) {}

        companion object {
            const val SCROLL_STATE_IDLE = 0
            const val SCROLL_STATE_TOUCH_SCROLL = 1
            const val SCROLL_STATE_FLING = 2
        }
    }
}