package com.adealink.weparty.commonui.text

import android.content.Context
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.util.AttributeSet
import androidx.appcompat.widget.AppCompatTextView
import kotlin.math.ceil
import kotlin.math.floor

/**
 * 参考：https://www.cnblogs.com/dingxiansen/p/8658991.html
 * 整数递增（支持负数）
 *
 * 数值之间的
 */
class IncreaseNumTextView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0,
) : AppCompatTextView(context, attrs, defStyleAttr) {

    private var startNum = 0L
    private var endNum = 0L

    private var increaseNum = 0f
    private var increaseStep = 0f
    private var duration = DEFAULT_DURATION
    private var frequency = DEFAULT_FREQUENCY_PER_SECOND
    private var frequencyDelay = 0L
    private var increaseCountIndex = 0
    private var increaseCount = 0
    private var isAnim = false

    private var increaseListener: IncreaseListener? = null

    fun setIncreaseNum(startNum: Long, endNum: Long, duration: Long) {
        if (isAnim) {
            stopAnim()
        }
        this.startNum = startNum
        this.endNum = endNum
        this.duration = duration
    }

    fun setFrequency(frequency: Int) {
        this.frequency = frequency
    }

    fun setListener(listener: IncreaseListener) {
        this.increaseListener = listener
    }

    fun startIncrease() {
        if (isAnim) {
            stopAnim()
        }
        startAnim()
    }

    fun stopIncrease(toFinalNum: Boolean) {
        stopAnim()
        if (toFinalNum) {
            text = increaseListener?.onTransform(endNum) ?: endNum.toString()
        }
    }

    private fun startAnim() {
        this.increaseCount = ceil(((duration / 1000f) * frequency).toDouble()).toInt()
        this.increaseCountIndex = 0
        this.increaseStep = (endNum - startNum).toFloat() / increaseCount
        this.frequencyDelay = 1000L / frequency
        handler.sendEmptyMessage(MSG_START_ANIM)
    }

    private fun stopAnim() {
        handler.removeCallbacksAndMessages(null)
    }

    private val handler = object : Handler(Looper.getMainLooper()) {
        override fun handleMessage(msg: Message) {
            when (msg.what) {
                MSG_START_ANIM -> {
                    increaseListener?.onIncreaseStart()
                    text = performNextIncreaseNum()
                    sendEmptyMessageDelayed(MSG_RUN_ANIM, frequencyDelay)
                }
                else -> {
                    if (increaseCountIndex > increaseCount) {
                        removeCallbacksAndMessages(null)
                        increaseListener?.onIncreaseComplete()
                    } else {
                        text = performNextIncreaseNum()
                        sendEmptyMessageDelayed(MSG_RUN_ANIM, frequencyDelay)
                    }
                }
            }
        }
    }

    private fun performNextIncreaseNum(): String {
        increaseNum += increaseStep
        if (increaseNum > endNum) {
            increaseNum = endNum.toFloat()
        }
        increaseCountIndex++

        val nextNum = floor(increaseNum).toLong()
        increaseListener?.onIncrease(nextNum)
        return increaseListener?.onTransform(nextNum) ?: increaseNum.toString()
    }

    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        handler.removeCallbacksAndMessages(null)
    }

    interface IncreaseListener {
        fun onIncreaseStart() {}

        fun onIncrease(num: Long) {}

        fun onTransform(num: Long): String

        fun onIncreaseComplete() {}
    }

    companion object {
        private const val DEFAULT_DURATION = 3_000L
        private const val DEFAULT_FREQUENCY_PER_SECOND = 30 //变化频率（每秒变化多少次）

        private const val MSG_START_ANIM = 1
        private const val MSG_RUN_ANIM = 2
    }
}