package com.abbidot.tracker.widget

import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.util.AttributeSet
import android.view.View
import androidx.core.content.ContextCompat
import com.abbidot.tracker.R
import com.abbidot.tracker.util.ViewUtil
import com.qmuiteam.qmui.util.QMUIDisplayHelper
import kotlin.math.abs


/**
 *Created  by .yzq on 2023/12/29/029.
 * @link
 * @description:
 */
class BarChartV2View : View {

    private lateinit var mContext: Context
    private var mWidth = 0
    private var mHeight = 0

    //每个圆柱的宽度
    private var mBarWidth = 0f

    //圆柱之间的间距
    private var mBarSpace = 0f
    private var mRadius = 0f
    private var mData: MutableList<Int>? = null
    private lateinit var mPaint: Paint
    private lateinit var mTextPaint: Paint
    private lateinit var mMaxPaint: Paint

    private val mXAxis = mutableListOf("0:00", "4:00", "8:00", "12:00", "16:00", "20:00", "24:00")
    private var mYAxis = mutableListOf(20, 40, 60, 80, 100, 120)

    //每个数值1所需要、占用的高度
    private var mValueHeight = 0f
    private var mMaxYValue = 120
    private var mMaxValue = 0

    //配合动画,每次画百分几
    private var mAnimatedPercent = 0f

    //动画时长（毫秒）
    private val mAnimatorDuration = 1500L

    private var mAxisTextColor = 0
    private var mBarValueColor = 0
    private var mBarMaxValueColor = 0

    constructor(context: Context) : super(context) {
        init(context, null)
    }

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
        init(context, attrs)
    }

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

    private fun init(context: Context, attrs: AttributeSet?) {
        initAttrs(context, attrs)

        //禁用硬件加速,防止返回到界面多次执行onDraw
        setLayerType(LAYER_TYPE_SOFTWARE, null)
        mContext = context
        mBarWidth = QMUIDisplayHelper.dpToPx(18).toFloat()
        mRadius = QMUIDisplayHelper.dpToPx(8).toFloat()

        mPaint = Paint().apply {
            color = mBarValueColor
        }
        mTextPaint = Paint().apply {
            color = mAxisTextColor
            textSize = QMUIDisplayHelper.sp2px(mContext, 10).toFloat()
        }
        mMaxPaint = Paint().apply {
            color = mBarMaxValueColor
        }
    }

    private fun initAttrs(context: Context, attrs: AttributeSet?) {
        if (null == attrs) {
            mAxisTextColor = ContextCompat.getColor(context, R.color.select_color3)
            mBarValueColor = ContextCompat.getColor(context, R.color.dark_color)
            mBarMaxValueColor = ContextCompat.getColor(context, R.color.select_color2)
            return
        }

        val typedArray = context.obtainStyledAttributes(attrs, R.styleable.BarChartV2View)
        mAxisTextColor = typedArray.getColor(
            R.styleable.BarChartV2View_bar_v2_axis_text_color,
            ContextCompat.getColor(context, R.color.select_color3)
        )
        mBarValueColor = typedArray.getColor(
            R.styleable.BarChartV2View_bar_v2_value_color,
            ContextCompat.getColor(context, R.color.dark_color)
        )
        mBarMaxValueColor = typedArray.getColor(
            R.styleable.BarChartV2View_bar_v2_max_value_color,
            ContextCompat.getColor(context, R.color.select_color2)
        )
        typedArray.recycle()
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        mWidth = measuredWidth
        mHeight = measuredHeight
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        canvas?.apply {
            drawAxis(this)
            startDraw(this)
        }
    }


    private fun drawAxis(canvas: Canvas) {
        val fontMetrics = mTextPaint.fontMetrics // 获取字体指标信息
        val textHeight = abs((fontMetrics.top - fontMetrics.bottom))// 计算文本高度

        val xSize = mXAxis.size
        val xTxtWith = mTextPaint.measureText(mXAxis[xSize - 1])
        val xSpace = (mWidth - textHeight / 2 - xTxtWith * xSize) / (xSize - 1)
        for (i in 0 until xSize) {
            canvas.drawText(
                mXAxis[i], xSpace * i + xTxtWith * i + textHeight / 2, mHeight.toFloat(), mTextPaint
            )
        }

        val ySize = mYAxis.size
        val ySpace = (mHeight - textHeight * ySize) / (ySize + 1)
        for (i in 0 until ySize) {
            canvas.drawText(
                mYAxis[i].toString(),
                0f,
                mHeight - (ySpace * (i + 1)) - textHeight * (i + 1),
                mTextPaint
            )
        }
    }

    private fun startDraw(canvas: Canvas) {
        mData?.apply {
            if (size > 0) {
                //因有xy轴的文字,重新计算柱状图的长宽
                val ySize = mYAxis.size
                val yTxtWith = mTextPaint.measureText(mYAxis[ySize - 1].toString())
                val fontMetrics = mTextPaint.fontMetrics // 获取字体指标信息
                val textHeight = abs((fontMetrics.top - fontMetrics.bottom))// 计算文本高度
                val yHeight = mHeight - textHeight / 2 - QMUIDisplayHelper.dpToPx(3)
                val xWith = mWidth - yTxtWith
                mValueHeight = yHeight / mMaxYValue
                mBarSpace = ((xWith - mBarWidth * size) / size)

                for (i in 0 until size) {
                    val value = this[i]
                    if (value <= 0) continue
                    val left = (mBarSpace * (i + 1) + i * mBarWidth) + yTxtWith
                    val top = (yHeight - value * mValueHeight)
                    val right = (mBarSpace * (i + 1) + mBarWidth * (i + 1)) + yTxtWith

                    //防止动画从x轴原点以下开始出现
                    val newTop = with(top / mAnimatedPercent) {
                        if (this > yHeight) yHeight
                        else if (this == 0f || isNaN()) yHeight - yHeight * mAnimatedPercent
                        else this
                    }
                    if (value == mMaxValue) {
                        canvas.drawRoundRect(
                            left, newTop, right, yHeight, mRadius, mRadius, mMaxPaint
                        )
                    } else {
                        canvas.drawRoundRect(
                            left, newTop, right, yHeight, mRadius, mRadius, mPaint
                        )
                    }

                }
            }
        }
    }

    fun setData(data: MutableList<Int>) {
        val size = data.size
        mMaxValue = 0
        for (i in 0 until size) {
            if (data[i] > mMaxValue) {
                mMaxValue = data[i]
            }
        }
        if (mMaxValue > 60) {
            mMaxYValue = 120
            mYAxis = mutableListOf(20, 40, 60, 80, 100, 120)
        } else {
            mMaxYValue = 60
            mYAxis = mutableListOf(10, 20, 30, 40, 50, 60)
        }
        mData = data

        ViewUtil.instance.setValueAnimator(0f, 100f, mAnimatorDuration) {
            mAnimatedPercent = it.animatedValue as Float / 100
            postInvalidate()
        }
    }
}