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 2024/1/3/003.
 * @link
 * @description:
 */
class HorizontalBarChartView : View {

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

    private val mXAxis = mutableListOf("00 Min", "240", "480", "720", "960", "1200", "1440")
    private var mYAxis = mutableListOf("Fr", "Th", "We", "Tu", "Mo", "Su", "Today")

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

    private var mRadius = 0f
    private var mData: MutableList<Int>? = null

    //每个数值1所需要、占用的高度
    private var mValueHeight = 0f
    private var mMaxYAxisValue = 24 * 60
    private var mMaxValue = 0

    private lateinit var mPaint: Paint
    private lateinit var mTextPaint: Paint
    private lateinit var mMaxPaint: Paint

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

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

    private var mAxisTextColor = 0
    private var mBarValueColor = 0
    private var mBarMaxValueColor = 0
    private var mBarMaxValueTextColor = 0
    private var mBarValueTextColor = 0
    private var mBarValueBgColor = 0

    //转换小时
    private var mConvertHour = false

    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
        mBarHeight = QMUIDisplayHelper.dpToPx(18).toFloat()
        mRadius = QMUIDisplayHelper.dpToPx(8).toFloat()

        mPaint = Paint().apply {
            color = mBarValueBgColor
        }
        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.green_color1)
            mBarMaxValueColor = ContextCompat.getColor(context, R.color.select_color)
            mBarMaxValueTextColor = ContextCompat.getColor(context, R.color.select_color2)
            mBarValueTextColor = ContextCompat.getColor(context, R.color.block_color2)
            mBarValueBgColor = ContextCompat.getColor(context, R.color.dark_color)
            return
        }

        val typedArray = context.obtainStyledAttributes(attrs, R.styleable.HorizontalBarChartView)
        mAxisTextColor = typedArray.getColor(
            R.styleable.HorizontalBarChartView_bar_axis_text_color,
            ContextCompat.getColor(context, R.color.select_color3)
        )
        mBarValueColor = typedArray.getColor(
            R.styleable.HorizontalBarChartView_bar_value_color,
            ContextCompat.getColor(context, R.color.green_color1)
        )
        mBarMaxValueColor = typedArray.getColor(
            R.styleable.HorizontalBarChartView_bar_max_value_color,
            ContextCompat.getColor(context, R.color.select_color)
        )
        mBarMaxValueTextColor = typedArray.getColor(
            R.styleable.HorizontalBarChartView_bar_max_value_text_color,
            ContextCompat.getColor(context, R.color.select_color2)
        )
        mBarValueTextColor = typedArray.getColor(
            R.styleable.HorizontalBarChartView_bar_value_text_color,
            ContextCompat.getColor(context, R.color.block_color2)
        )
        mBarValueBgColor = typedArray.getColor(
            R.styleable.HorizontalBarChartView_bar_value_bg_color,
            ContextCompat.getColor(context, R.color.dark_color)
        )
        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 {
            drawBar(this)
        }
    }

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

        val xSize = mXAxis.size
        //取最长的字体宽度
        var xTxtWith = mTextPaint.measureText(mXAxis[xSize - 1])
        for (i in 0 until xSize) {
            val cTxtWith = mTextPaint.measureText(mXAxis[i])
            if (xTxtWith < cTxtWith) xTxtWith = cTxtWith
        }
        val xSpace = (mWidth - textHeight / 2 - xTxtWith * xSize) / (xSize - 1)
        mTextPaint.color = mAxisTextColor
        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], 0f, mHeight - (ySpace * (i + 1)) - textHeight * (i + 1), mTextPaint
            )
        }

        mData?.apply {
            if (size > 0) {

                val xWith = mWidth - xTxtWith
                mValueHeight = xWith / mMaxYAxisValue

                val left = xTxtWith
                for (i in 0 until size) {
                    val value = this[i]
                    val top =
                        mHeight - (ySpace * (i + 1)) - mBarHeight / 2 - textHeight * (i + 1) - textHeight / 4
                    val right = value * mValueHeight
                    val bottom = top + mBarHeight

                    mPaint.color = mBarValueBgColor
                    canvas.drawRoundRect(
                        left, top, mWidth.toFloat(), bottom, mRadius, mRadius, mPaint
                    )

                    if (value < 0) continue

                    //防止动画从x轴原点以下开始出现
                    val newRight = left + right * mAnimatedPercent

                    if (value == mMaxValue) {
                        canvas.drawRoundRect(
                            left, top, newRight, bottom, mRadius, mRadius, mMaxPaint
                        )
                    } else {
                        mPaint.color = mBarValueColor
                        canvas.drawRoundRect(
                            left, top, newRight, bottom, mRadius, mRadius, mPaint
                        )
                    }
                    //动画结束显示文字
                    if (mAnimatedPercent == 1f) {
//                            mTextPaint.color = mBarMaxValueTextColor
                        mTextPaint.color = mBarValueTextColor
                        val string = if (mConvertHour) {
                            val h = value / 60
                            val m = value % 60
                            when (h) {
                                24 -> "${h}hr"
                                0 -> "${m}min"
                                else -> "${h}hr ${m}min"
                            }
                        } else {
                            "$value min"
                        }
                        val textWith = mTextPaint.measureText(string)
                        canvas.drawText(
                            string,
                            mWidth - textWith - textHeight / 3f,
                            top + textHeight / 1.1f,
                            mTextPaint
                        )
                    }
                }
            }
        }
    }


    fun setData(
        data: MutableList<Int>, yAxis: MutableList<String>? = null, convertHour: Boolean = false
    ) {
        if (null != yAxis) mYAxis = yAxis
        mConvertHour = convertHour
        val size = data.size
        mMaxValue = 0
        for (i in 0 until size) {
            if (data[i] > mMaxValue) {
                mMaxValue = data[i]
            }
        }
        //根据y轴最大值决定x轴的值
        mMaxYAxisValue = (mMaxValue / 60 + 1) * 60
        if (mMaxYAxisValue > 24 * 60) mMaxYAxisValue = 24 * 60
        val step = mMaxYAxisValue / 6
        for (i in 1..6) {
            mXAxis[i] = (i * step).toString()
        }

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