package com.gh.gamecenter.common.view

import android.content.Context
import android.graphics.PorterDuff
import android.graphics.PorterDuffColorFilter
import android.graphics.drawable.Drawable
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.text.TextUtils
import android.util.AttributeSet
import android.view.Gravity
import android.view.View
import android.view.animation.AnimationUtils
import android.widget.TextSwitcher
import android.widget.TextView
import android.widget.ViewSwitcher
import com.gh.gamecenter.common.R
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.common.utils.setDrawableEnd
import com.gh.gamecenter.common.utils.toColor


class TextBannerView @JvmOverloads constructor(context: Context, private val attrs: AttributeSet? = null): TextSwitcher(context, attrs), ViewSwitcher.ViewFactory {
    private var textSize = 12F
    private var index = -1
    private var highLightTextColor = R.color.text_theme.toColor(context)
    private var defaultTextColor = R.color.text_secondary.toColor(context)
    private var highLightDrawableEnd: Drawable? = null
    private var defaultDrawableEnd: Drawable? = null
    private var drawablePadding = 4F.dip2px(context)
    private var loopTime = 2000L
    private var loopOnce = false
    private var loopCount = 0
    private val dataList = arrayListOf<BannerTextData>()

    val currentIndex get() = index
    var onTextUpdateListener: ((Int, Int) -> Unit)? = null

    private val handler = object : Handler(Looper.getMainLooper()) {
        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)
            if (msg.what == KEY_TEXT_BANNER_LOOP) {
                updateNextTextView()
                startBannerLoop()
            }
        }
    }

    init {
        initView()
    }

    private fun initAttributes(attrs: AttributeSet) {
        val ta = context.obtainStyledAttributes(attrs, R.styleable.TextBannerView)
        highLightTextColor = ta.getColor(R.styleable.TextBannerView_tbv_highLightTextColor, highLightTextColor)
        defaultTextColor = ta.getColor(R.styleable.TextBannerView_tbv_defaultTextColor, defaultTextColor)
        textSize = ta.getFloat(R.styleable.TextBannerView_tbv_textSize, 12F)
        highLightDrawableEnd = ta.getDrawable(R.styleable.TextBannerView_tbv_drawableEnd)?.apply {
            colorFilter = PorterDuffColorFilter(highLightTextColor, PorterDuff.Mode.SRC_ATOP)
        }
        defaultDrawableEnd = ta.getDrawable(R.styleable.TextBannerView_tbv_drawableEnd)?.apply {
            colorFilter = PorterDuffColorFilter(defaultTextColor, PorterDuff.Mode.SRC_ATOP)
        }
        drawablePadding = ta.getDimensionPixelSize(R.styleable.TextBannerView_tbv_drawablePadding, drawablePadding)
        loopTime = ta.getInt(R.styleable.TextBannerView_tbv_loop_time, 2000).toLong()
        loopOnce = ta.getBoolean(R.styleable.TextBannerView_tbv_loop_once, false)
        ta.recycle()
    }

    private fun initView() {
        attrs?.let { initAttributes(it) }
        setFactory(this)
        inAnimation = AnimationUtils.loadAnimation(context, R.anim.in_anim)
        outAnimation = AnimationUtils.loadAnimation(context, R.anim.out_anim)
    }

    fun setDataList(list: List<BannerTextData>, defaultIndex: Int = 0) {
        dataList.clear()
        dataList.addAll(list)
        index = defaultIndex
        updateView()
        loopCount = 1
    }

    fun startBannerLoop() {
        stopBannerLoop()
        if (dataList.size > 1 && (loopCount == 1 || !loopOnce)) {
            handler.sendEmptyMessageDelayed(KEY_TEXT_BANNER_LOOP, loopTime + ANIMATION_DURATION)
        }
    }

    fun stopBannerLoop() {
        handler.removeCallbacksAndMessages(null)
    }

    fun updateView() {
        highLightTextColor = R.color.text_theme.toColor(context)
        defaultTextColor = R.color.text_secondary.toColor(context)
        attrs?.let { initAttributes(it) }
        updateCurrentTextView()
    }

    private fun updateNextTextView() {
        val lastIndex = index
        index = (index + 1) % dataList.size
        if (index == 0) loopCount++
        val data = dataList.getOrNull(index) ?: return
        (nextView as? TextView)?.let { updateTextView(it, data) }
        setText(data.text)
        onTextUpdateListener?.invoke(lastIndex, index)
    }

    private fun updateCurrentTextView() {
        val data = dataList.getOrNull(index) ?: return
        (currentView as? TextView)?.let { updateTextView(it, data) }
        setCurrentText(data.text)
    }

    private fun updateTextView(textView: TextView, data: BannerTextData) {
        textView.run {
            setTextColor(if (data.highLight) highLightTextColor else defaultTextColor)
            compoundDrawablePadding = drawablePadding
            setDrawableEnd(if (data.highLight) highLightDrawableEnd else defaultDrawableEnd)
        }
    }

    override fun makeView(): View = TextView(context).apply {
        layoutParams = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT)
        textSize = this@TextBannerView.textSize
        setSingleLine()
        ellipsize = TextUtils.TruncateAt.END
        gravity = Gravity.CENTER_VERTICAL
        includeFontPadding = false
    }

    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        stopBannerLoop()
    }

    data class BannerTextData(
        val text: String = "",
        val highLight: Boolean = false
    )

    companion object {
        private const val KEY_TEXT_BANNER_LOOP = 1
        const val ANIMATION_DURATION = 1000L
    }
}