package com.abbidot.tracker.widget

import android.animation.ValueAnimator
import android.content.Context
import android.graphics.Canvas
import android.graphics.LinearGradient
import android.graphics.Paint
import android.graphics.RectF
import android.graphics.Shader
import android.util.AttributeSet
import android.view.View
import android.view.animation.LinearInterpolator
import androidx.core.content.ContextCompat
import com.abbidot.baselibrary.util.AppUtils
import com.abbidot.baselibrary.util.LogUtil
import com.abbidot.baselibrary.util.Utils
import com.abbidot.tracker.R

/**
 *Created  by .yzq on 2024/3/14/014.
 * @link
 * @description:
 */
class SignalRadarView : View {

    private lateinit var mContext: Context

    private lateinit var mPaint: Paint
    private lateinit var mScanPaint: Paint

    private lateinit var mRectF: RectF

    private var mWidth = 0
    private var mHeight = 0

    private var mStartScanAngle = 0f
    private var mMaxRadius = 0f
    private var mMinRadius = 0f
    private var mCircleRadius1 = 0f
    private var mCircleRadius2 = 0f
    private var mCircleRadius3 = 0f
    private var mCircleRadius4 = 0f

    private var mCircle1Animator: ValueAnimator? = null
    private var mCircle2Animator: ValueAnimator? = null
    private var mCircle3Animator: ValueAnimator? = null
    private var mCircle4Animator: ValueAnimator? = null
    private var mScanAnimator: ValueAnimator? = null

    private lateinit var mSignalStrengthColors: IntArray
    private var mValue = 0

    //增幅
    private val mRate = 40f

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

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

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

    private fun init(context: Context) {
        //禁用硬件加速,防止返回到界面多次执行onDraw-
        setLayerType(LAYER_TYPE_SOFTWARE, null)

        mContext = context
        mPaint = Paint().apply {
            strokeWidth = AppUtils.dpToPx(1f)
            style = Paint.Style.STROKE
        }
        mScanPaint = Paint().apply {
            color = ContextCompat.getColor(context, R.color.radar_color9)
        }

        mSignalStrengthColors = intArrayOf(
            R.color.radar_color4,
            R.color.radar_color7,
            R.color.radar_color5,
            R.color.radar_color6,
            R.color.radar_color9
        )

        mRectF = RectF()
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        mHeight = AppUtils.dpToPx(160)
        mWidth = mHeight
        mRectF.apply {
            left = 0f
            top = 0f
            right = mWidth.toFloat()
            bottom = mHeight.toFloat()
        }
        setMeasuredDimension(mWidth, mHeight)
    }

    override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
        super.onLayout(changed, left, top, right, bottom)
        mMaxRadius = mHeight / 2f - mPaint.strokeWidth
        mCircleRadius1 = mMaxRadius - AppUtils.dpToPx(70)
        mMinRadius = mCircleRadius1
        mCircleRadius4 = mCircleRadius1
        mCircleRadius3 = mCircleRadius1
        mCircleRadius2 = mCircleRadius1
        startScanAnimator()
    }

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

    private fun startDraw(canvas: Canvas) {

//        val circleX = mWidth / 2f
//        val circleY = mHeight / 2f

        canvas.apply {
//            var radius = mMaxRadius
//            mPaint.style = Paint.Style.FILL
//            onDrawCircle(mContext, canvas, R.color.radar_color4, radius, mPaint)
//            mPaint.style = Paint.Style.STROKE
//            drawLine(circleX, 0f, circleX, mHeight.toFloat(), mPaint)
//            drawLine(0f, circleY, mWidth.toFloat(), circleY, mPaint)
//            radius -= mPaint.strokeWidth
            onDrawCircle(mContext, canvas, R.color.radar_color9, mCircleRadius4, mPaint)
//            radius -= AppUtils.dpToPx(18)
            onDrawCircle(mContext, canvas, R.color.radar_color9, mCircleRadius3, mPaint)
//            radius -= AppUtils.dpToPx(20)
            onDrawCircle(mContext, canvas, R.color.radar_color9, mCircleRadius2, mPaint)
//            radius -= AppUtils.dpToPx(22)
            onDrawCircle(mContext, canvas, R.color.radar_color9, mCircleRadius1, mPaint)

            val strength = (mValue * 20) + mRate
            drawArc(mRectF, mStartScanAngle, strength, true, mScanPaint)
        }
    }

    private fun onDrawCircle(
        context: Context, canvas: Canvas, colorId: Int, radius: Float, paint: Paint
    ) {
        paint.color = ContextCompat.getColor(context, colorId)
        canvas.drawCircle(mWidth / 2f, mHeight / 2f, radius, paint)
    }

    /**
     * 动画
     */
    private fun startScanAnimator() {
        if (null == mScanAnimator) {
            mScanAnimator = ValueAnimator.ofFloat(0f, 360f).apply {
                duration = 1500
                repeatCount = ValueAnimator.INFINITE
                //匀速变化
                interpolator = LinearInterpolator()
                addUpdateListener {
                    mStartScanAngle = it.animatedValue as Float
                    val circleX = mWidth / 2f
                    val circleY = mHeight / 2f
                    val strength = (mValue * 20) + mRate
                    //开始坐标与结束坐标是什么方向就以什么方向渐变
                    val start = Utils.getPointOnCircleArc(
                        circleX, circleY, circleY, mStartScanAngle.toDouble() + strength
                    )
                    val end = Utils.getPointOnCircleArc(
                        circleX, circleY, circleY, mStartScanAngle.toDouble()
                    )
                    val shader = LinearGradient(
                        start[0],
                        start[1],
                        end[0],
                        end[1],
                        ContextCompat.getColor(mContext, mSignalStrengthColors[mValue]),
                        ContextCompat.getColor(mContext, R.color.transparent),
                        Shader.TileMode.CLAMP
                    )
                    mScanPaint.shader = shader
//                    postInvalidate()
                }
            }
        }
        mScanAnimator?.apply {
            if (!isRunning) {
                LogUtil.e("木有开始")
                start()
            }
        }

        if (null == mCircle1Animator) {
            mCircle1Animator = setCircleAnimator().apply {
                addUpdateListener {
                    mCircleRadius1 = it.animatedValue as Float
                    postInvalidate()
                }
            }
        }
        mCircle1Animator?.apply {
            if (!isRunning) {
                start()
            }
        }

        if (null == mCircle2Animator) {
            mCircle2Animator = setCircleAnimator().apply {
                addUpdateListener {
                    mCircleRadius2 = it.animatedValue as Float
//                    postInvalidate()
                }
                startDelay = 400
            }
        }
        mCircle2Animator?.apply {
            if (!isRunning) {
                start()
            }
        }

        if (null == mCircle3Animator) {
            mCircle3Animator = setCircleAnimator().apply {
                addUpdateListener {
                    mCircleRadius3 = it.animatedValue as Float
//                    postInvalidate()
                }
                startDelay = 700
            }
        }
        mCircle3Animator?.apply {
            if (!isRunning) {
                start()
            }
        }

        if (null == mCircle4Animator) {
            mCircle4Animator = setCircleAnimator().apply {
                addUpdateListener {
                    mCircleRadius4 = it.animatedValue as Float
//                    postInvalidate()
                }
                startDelay = 1100
            }
        }
        mCircle4Animator?.apply {
            if (!isRunning) {
                start()
            }
        }
    }

    private fun setCircleAnimator(): ValueAnimator {
        return ValueAnimator.ofFloat(mMaxRadius - AppUtils.dpToPx(70), mMaxRadius).apply {
            duration = 1500L
            repeatCount = ValueAnimator.INFINITE
            //匀速变化
            interpolator = LinearInterpolator()
        }
    }

    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        mScanAnimator?.cancel()
        mCircle1Animator?.cancel()
        mCircle2Animator?.cancel()
        mCircle3Animator?.cancel()
        mCircle4Animator?.cancel()
    }

    fun setValue(value: Int) {
        if (value < 0) return
        mValue = value
    }
}