package com.abbidot.tracker.widget

import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.RectF
import android.util.AttributeSet
import android.view.View
import androidx.core.content.ContextCompat
import com.abbidot.baselibrary.util.Utils
import com.abbidot.tracker.R
import com.abbidot.tracker.util.ViewUtil
import com.qmuiteam.qmui.util.QMUIDisplayHelper

/**
 *Created  by .yzq on 2024/1/2/002.
 * @link
 * @description:圆形图表
 */
class RingChartView : View {

    private lateinit var mContext: Context
    private var mWidth = 0
    private var mHeight = 0
    private lateinit var mYellowPaint: Paint
    private lateinit var mGrayPaint: Paint
    private lateinit var mTextPaint: Paint

    private lateinit var mRectF: RectF

    //圆的半径
    private var mRadius = 0

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

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

    //绿圆扫过的角度
    private var mSweepAngle = 0f
    private var mPercentText = "0"

    private var showPercent = true
    private var mRingValueColor1 = 0
    private var mRingValueColor2 = 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

        mYellowPaint = Paint().apply {
            color = mRingValueColor1
            //画笔的样式,圆形,进度条适合使用
//           strokeCap = Paint.Cap.ROUND
            //画笔的填充样式,描边
            style = Paint.Style.STROKE
        }
        mGrayPaint = Paint().apply {
            color = mRingValueColor2
            style = Paint.Style.STROKE
        }
        mTextPaint = Paint().apply {
            textSize = QMUIDisplayHelper.sp2px(mContext, 10).toFloat()
            color = ContextCompat.getColor(mContext, R.color.white)
        }
        mRectF = RectF()
    }

    private fun initAttrs(context: Context, attrs: AttributeSet?) {
        if (null == attrs) {
            mRingValueColor1 = ContextCompat.getColor(context, R.color.select_color2)
            mRingValueColor2 = ContextCompat.getColor(context, R.color.gray_color6)
            return
        }
        val typedArray = context.obtainStyledAttributes(attrs, R.styleable.RingChartView)
        showPercent = typedArray.getBoolean(R.styleable.RingChartView_show_percent_text, true)
        mRingValueColor1 = typedArray.getColor(
            R.styleable.RingChartView_ring_value_color1,
            ContextCompat.getColor(context, R.color.select_color2)
        )
        mRingValueColor2 = typedArray.getColor(
            R.styleable.RingChartView_ring_value_color2,
            ContextCompat.getColor(context, R.color.gray_color6)
        )
        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 {
            drawRing(this)
        }
    }

    private fun drawRing(canvas: Canvas) {
        if (mRadius == 0) {
            mRadius = mHeight / 2
            val strokeWidth = mRadius / 2.5f
            //圆弧的宽度,向正常圆内外各伸长一半宽度
            mYellowPaint.strokeWidth = strokeWidth
            mGrayPaint.strokeWidth = strokeWidth
        }
        //计算圆环的一半宽度
        val ringHalfRadius = mRadius / 5f
        //算上圆环的宽度一半后的半径
        val r = mRadius - ringHalfRadius
        val left = mWidth / 2f - r
        val top = mHeight / 2f - r
        val right = mWidth / 2f + r
        val bottom = mHeight / 2f + r
        mRectF.let {
            it.left = left
            it.top = top
            it.right = right
            it.bottom = bottom
        }
//        canvas.drawRect(mRectF, mGrayPaint)

        canvas.drawArc(mRectF, 270f, -mSweepAngle / mAnimatedPercent, false, mYellowPaint)
        val graySweepAngle = 360f - mSweepAngle
        //默认是灰色的圆环
        canvas.drawArc(mRectF, 270f, graySweepAngle / mAnimatedPercent, false, mGrayPaint)

        //动画结束显示文字
        if (mAnimatedPercent == 1f && showPercent && mPercentText.toFloat() > 0f) {
            val fontMetrics = mTextPaint.fontMetrics
            //获取文字的高度
            val height = fontMetrics.bottom - fontMetrics.top
            //根据圆弧的角度确定文字显示的位置,180°则显示中间位置

            val yYellowText = angleToY(mSweepAngle, height)
            canvas.drawText("$mPercentText%", ringHalfRadius, yYellowText, mTextPaint)

            val yGrayText = angleToY(graySweepAngle, height)
            val grayText = Utils.formatDecimal(100 - mPercentText.toFloat(), 2)
            canvas.drawText("$grayText%", mWidth - r + ringHalfRadius, yGrayText, mTextPaint)
        }
    }

    /**
     * 根据圆弧的角度确定文字显示的位置,180°则显示中间位置
     */
    private fun angleToY(angle: Float, default: Float): Float {
        return if (angle >= 180f) mHeight / 2f
        else if (angle >= 60f) (angle / 180f) * (mHeight / 2f)
        else default
    }


    fun setData(data1: Float, data2: Float) {
        if (data1 == 0f && data2 == 0f) {
            val sum = 2
            mPercentText = Utils.formatDecimal((1f / sum) * 100, 2)
            mSweepAngle = 360f * (1f / sum)
            mAnimatedPercent = 1f
            mYellowPaint.color = ContextCompat.getColor(mContext, R.color.gray_color12)
            invalidate()
        } else {
            val sum = data1 + data2
            mPercentText = Utils.formatDecimal((data1 / sum) * 100, 2)
            mSweepAngle = 360f * (data1 / sum)
            mYellowPaint.color = mRingValueColor1
            ViewUtil.instance.setValueAnimator(0f, 100f, mAnimatorDuration) {
                mAnimatedPercent = it.animatedValue as Float / 100
                postInvalidate()
            }
        }

        mPercentText = mPercentText.replace(",", ".")
    }
}