package com.develop.common.widget

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Path
import android.text.TextPaint
import android.util.AttributeSet
import android.util.TypedValue
import android.view.View
import android.widget.Scroller
import com.develop.base.ext.dimenRes
import com.develop.base.R


class WeightView @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {

    private val path = Path()
    private val paint = Paint(Paint.ANTI_ALIAS_FLAG)
    private val textPaint = TextPaint(Paint.ANTI_ALIAS_FLAG)
    private val outlineStrokeWidth = dimenRes(R.dimen.convert_9px).toFloat()
    private val scaleStrokeWidth = dimenRes(R.dimen.convert_4px).toFloat()
    private val scaleTopPosition = dimenRes(R.dimen.convert_20px).toFloat()
    private val scaleBtmPosition = dimenRes(R.dimen.convert_50px).toFloat()
    private val textPutPosition = dimenRes(R.dimen.convert_90px).toFloat()
    private val triangleWidth = dimenRes(R.dimen.convert_60px).toFloat()
    private val triangleHeight = dimenRes(R.dimen.convert_30px).toFloat()
    private val triangleMargin = dimenRes(R.dimen.convert_3px).toFloat()
    private var rotateOffset = 0f
    private val scroller = Scroller(context)
    private val gapCount = 20

    init {
        paint.strokeWidth = outlineStrokeWidth
        textPaint.textSize = TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_DIP,
            14f, context.resources.displayMetrics
        )
        textPaint.color = Color.WHITE
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        val width = MeasureSpec.getSize(widthMeasureSpec)
        setMeasuredDimension(width, width / 2)
    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        val triangleBottomY = width * 0.25f - triangleMargin - outlineStrokeWidth / 2f
        path.reset()
        path.moveTo(width / 2f - triangleWidth / 2, triangleBottomY)
        path.lineTo(width / 2f, triangleBottomY - triangleHeight)
        path.lineTo(width / 2f + triangleWidth / 2, triangleBottomY)
        path.close()
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)

        paint.color = 0xffe60012.toInt() // 三角形指示器
        canvas.drawPath(path, paint)

        paint.style = Paint.Style.STROKE
        paint.strokeWidth = outlineStrokeWidth
        paint.color = Color.WHITE
        canvas.drawCircle(width / 2f, height.toFloat(), width / 2f - outlineStrokeWidth / 2f, paint)
        paint.color = Color.parseColor("#99ffffff")
        canvas.drawCircle(width / 2f, height.toFloat(), width * 0.25f, paint)

        paint.strokeWidth = scaleStrokeWidth
        paint.color = Color.WHITE

        val intervalDegree = 360 / gapCount
        canvas.save()
        canvas.rotate(-rotateOffset % 360, width / 2f, height.toFloat())
        repeat(gapCount) {
            canvas.drawLine(width / 2f, scaleTopPosition, width / 2f, scaleBtmPosition, paint)
            val scaleText = getWeightNumber(it)
            val textWidth = textPaint.measureText(scaleText)
            canvas.drawText(scaleText, width / 2f - textWidth / 2, textPutPosition, textPaint)
            canvas.rotate(intervalDegree.toFloat(), width / 2f, height.toFloat())
        }
        canvas.restore()
    }

    override fun computeScroll() {
        super.computeScroll()
        if (!scroller.computeScrollOffset()) {
            return
        }
        rotateOffset = scroller.currX.toFloat()
        invalidate()
    }

    private fun getWeightNumber(index: Int): String {
        if (rotateOffset <= 90 && index >= 14 && index <= 19) {
            // 特殊处理0左边的值
            return ((index + 1) * 250).toString()
        }
        val loopIndex = (((rotateOffset - 270f) / 360f) + 1).toInt()
        val accumulate = 200 * loopIndex + index * 10
        if (loopIndex >= 1) {
            val borderValue = (loopIndex - 1) * 360 + 540
            if (index <= 10 || rotateOffset >= borderValue) {
                return accumulate.toString()
            } else {
                return (accumulate - 200).toString()
            }
        }
        return (index * 10).toString()
    }

    fun setWeightNumber(weight: Float) {
        val dDegree = getDegreeByWeight(weight) - rotateOffset
        if (dDegree.compareTo(0) == 0) {
            return
        }
        scroller.abortAnimation()
        scroller.startScroll(
            rotateOffset.toInt(), 0,
            dDegree.toInt(), 0,
            300
        )
        invalidate()
    }

    private fun getDegreeByWeight(weight: Float): Float {
        return weight / 10f * 18f
    }
}