package com.abbidot.tracker.widget

import android.content.Context
import android.graphics.Canvas
import android.graphics.DashPathEffect
import android.graphics.LinearGradient
import android.graphics.Paint
import android.graphics.Path
import android.graphics.Shader
import android.util.AttributeSet
import android.view.View
import androidx.core.content.ContextCompat
import com.abbidot.baselibrary.util.AppUtils
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/4/004.
 * @link
 * @description:
 */
class LineChartView : View {

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

    private lateinit var mAxisPaint: Paint
    private lateinit var mDashedPaint: Paint
    private lateinit var mChartPaint: Paint
    private lateinit var mGradientPaint: Paint
    private lateinit var mPath: Path
    private lateinit var mGradientPath: Path

    private var mXAxis = mutableListOf("Today", "30/11", "24/11", "18/11", "12/11", "6/11")
    private val mYAxis = mutableListOf(240, 480, 720, 960, 1200, 1440)
    private var mMaxYAxisValue = 60 * 24

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

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

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

    private var mAxisTextColor = 0
    private var mAxisDashedColor = 0
    private var mLineChartColor = 0
    private var mLineGradientStartColor = 0
    private var mLineGradientEndColor = 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

        mAxisPaint = Paint().apply {
            textSize = QMUIDisplayHelper.sp2px(mContext, 10).toFloat()
            color = mAxisTextColor
        }
        mChartPaint = Paint().apply {
            color = mLineChartColor
            strokeWidth = AppUtils.dpToPx(1f)
            style = Paint.Style.STROKE
            //拐角的形状。有三个值可以选择：MITER 尖角、 BEVEL 平角和 ROUND 圆角
            strokeJoin = Paint.Join.MITER
        }
        mDashedPaint = Paint().apply {
            color = mAxisDashedColor
            style = Paint.Style.STROKE
            strokeWidth = AppUtils.dpToPx(0.5f)
        }
        mGradientPaint = Paint().apply {
            style = Paint.Style.FILL
        }

        mPath = Path()
        mGradientPath = Path()

        //要画的实线和间隔的长度
        val dashedWidth = QMUIDisplayHelper.dpToPx(4).toFloat()
        val dashPathEffect = DashPathEffect(floatArrayOf(dashedWidth, dashedWidth), 0f)
        mDashedPaint.pathEffect = dashPathEffect
    }

    private fun initAttrs(context: Context, attrs: AttributeSet?) {
        if (null == attrs) {
            mAxisTextColor = ContextCompat.getColor(context, R.color.block_color2)
            mAxisDashedColor = ContextCompat.getColor(context, R.color.white_gray_color1)
            mLineChartColor = ContextCompat.getColor(context, R.color.select_color)
            mLineGradientStartColor = ContextCompat.getColor(context, R.color.white)
            mLineGradientEndColor = ContextCompat.getColor(context, R.color.green_color2)
            return
        }

        val typedArray = context.obtainStyledAttributes(attrs, R.styleable.LineChartView)
        mAxisTextColor = typedArray.getColor(
            R.styleable.LineChartView_line_axis_text_color,
            ContextCompat.getColor(context, R.color.block_color2)
        )
        mAxisDashedColor = typedArray.getColor(
            R.styleable.LineChartView_line_axis_dashed_color,
            ContextCompat.getColor(context, R.color.white_gray_color1)
        )
        mLineChartColor = typedArray.getColor(
            R.styleable.LineChartView_line_chart_color,
            ContextCompat.getColor(context, R.color.select_color)
        )
        mLineGradientStartColor = typedArray.getColor(
            R.styleable.LineChartView_line_gradient_start_color,
            ContextCompat.getColor(context, R.color.white)
        )
        mLineGradientEndColor = typedArray.getColor(
            R.styleable.LineChartView_line_gradient_end_color,
            ContextCompat.getColor(context, R.color.green_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 {
            startDraw(this)
        }
    }

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

        val xSize = mXAxis.size
        var xTxtMaxWith = 0f
        for (i in 0 until xSize) {
            val xTxtWith = mAxisPaint.measureText(mXAxis[i])
            if (xTxtMaxWith < xTxtWith) xTxtMaxWith = xTxtWith
        }
        val xSpace = (mWidth - xTxtMaxWith * xSize) / (xSize - 1)
        for (i in 0 until xSize) {
            val x = xSpace * i + xTxtMaxWith * i
            canvas.drawText(
                mXAxis[i], x, mHeight.toFloat() - textHeight / 4, mAxisPaint
            )
        }

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

        //虚线个数
        val dashedCount = 16
        val newX = mWidth - xTxtMaxWith
        val strokeWidth = mDashedPaint.strokeWidth
        val dashedSpace = (newX - strokeWidth * dashedCount) / (dashedCount - 1)
        for (i in 0 until dashedCount) {
            val x = xTxtMaxWith + i * dashedSpace + strokeWidth * (i + 1)
//           canvas.drawLine(x, newY, x, 0f, mDashedPaint)
            mPath.moveTo(x, newYAxisHeight)
            mPath.lineTo(x, 0f)
            canvas.drawPath(mPath, mDashedPaint)
            mPath.reset()
        }

        mData?.apply {
            if (size > 0) {
                val dotWidth = mChartPaint.strokeWidth
                //value=1所占的像素
                val valueHeight = newYAxisHeight / mMaxYAxisValue
                //点之间的间隔
                val dotSpace = (newX - dotWidth * size) / (size - 1)
                //从数值坐标today原点开始连线
                mGradientPath.moveTo(xTxtMaxWith, newYAxisHeight)
                for (i in 0 until size) {
                    val value = this[i]
                    val x = xTxtMaxWith + i * dotSpace + i * dotWidth
                    //需要与y轴值对齐，要加上文字的高度textHeight / 1.5f
                    var y = newYAxisHeight - value * valueHeight
                    y /= mAnimatedPercent
                    //防止从x轴底部画起
                    if (y > newYAxisHeight) y = newYAxisHeight
                    if (i == 0) mPath.moveTo(x, y)
                    else mPath.lineTo(x, y)
                    mGradientPath.lineTo(x, y)
                }
                //开始坐标与结束坐标是什么方向就以什么方向渐变
                val shader = LinearGradient(
                    xTxtMaxWith,
                    //从最高的那个点开始渐变
                    newYAxisHeight - mMaxValue * valueHeight + textHeight / 1.5f,
                    xTxtMaxWith,
                    newYAxisHeight,
                    mLineGradientEndColor,
                    mLineGradientStartColor,
                    Shader.TileMode.CLAMP
                )
                //最后从数值顶点坐标闭合
                mGradientPath.lineTo(mWidth.toFloat(), newYAxisHeight)
                //画一个闭合的路径进行渐变
                mGradientPath.close()
                mGradientPaint.shader = shader
                canvas.drawPath(mGradientPath, mGradientPaint)
                mGradientPath.reset()

                canvas.drawPath(mPath, mChartPaint)
                mPath.reset()
            }
        }
    }

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

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