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.AppUtils
import com.abbidot.tracker.R

/**
 *Created  by .yzq on 2024/3/27/027.
 * @link
 * @description:wifi 信号view
 */
class MyWiFiSignalView : View {

    private lateinit var mContext: Context
    private var mWidth = 0
    private var mHeight = 0
    private var mMinCircleRadius = 0f
    private var mCircleStrokeWidth = 0f
    private var mValueColor = 0

    private lateinit var mPaint: Paint
    private lateinit var mRectF: RectF

    private val mMaxValue = 2
    private var mValue = 0

    //是否显示锁
    private var isShowLock = 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?) {
        mContext = context
        initAttrs(context, attrs)

        //禁用硬件加速,防止返回到界面多次执行onDraw
        setLayerType(LAYER_TYPE_SOFTWARE, null)

        mWidth = AppUtils.dpToPx(25)
        mHeight = mWidth

        //开启抗锯齿
        mPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
            strokeCap = Paint.Cap.ROUND
        }
        mRectF = RectF()
    }

    private fun initAttrs(context: Context, attrs: AttributeSet?) {
        if (null == attrs) {
            mMinCircleRadius = AppUtils.dpToPx(3f)
            mCircleStrokeWidth = AppUtils.dpToPx(2f)
            mValueColor = ContextCompat.getColor(context, R.color.green_color100)
            return
        }

        val typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyWiFiSignalView)
        mMinCircleRadius = typedArray.getDimension(
            R.styleable.MyWiFiSignalView_min_circle_radius, AppUtils.dpToPx(3f)
        )
        mCircleStrokeWidth = typedArray.getDimension(
            R.styleable.MyWiFiSignalView_circle_stroke_width, AppUtils.dpToPx(2f)
        )
        mValueColor = typedArray.getColor(
            R.styleable.MyWiFiSignalView_value_color,
            ContextCompat.getColor(context, R.color.green_color100)
        )
        typedArray.recycle()
    }

    /**
     * 测量模式有三种：EXACTLY（精确模式）、AT_MOST（最大模式）和 UNSPECIFIED（未指定模式）。
     * 当 View 的宽度和高度都指定为具体数值时，测量模式为 EXACTLY；当 View 的宽度和高度都为 wrap_content 时，
     * 测量模式为 AT_MOST；当 View 的宽度或高度未指定时，测量模式为 UNSPECIFIED
     */
    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)

        val widthMeasureMode = MeasureSpec.getMode(widthMeasureSpec)
        val heightMeasureMode = MeasureSpec.getMode(heightMeasureSpec)
        if (widthMeasureMode == MeasureSpec.AT_MOST || heightMeasureMode == MeasureSpec.AT_MOST || widthMeasureMode == MeasureSpec.UNSPECIFIED || heightMeasureMode == MeasureSpec.UNSPECIFIED) {
            setMeasuredDimension(mWidth, mHeight)
        } else {
            val max = maxOf(measuredWidth, measuredHeight)
            setMeasuredDimension(max, max)
            mHeight = max
            mWidth = max
        }
    }

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

    /**
     * 不同半径的同心圆
     */
    private fun startDraw(canvas: Canvas) {
        val circleX = mWidth / 2f
        val circleY = mHeight - mMinCircleRadius
        mPaint.apply {
            style = Paint.Style.FILL
            strokeWidth = 1f
            color = mValueColor
        }
        canvas.drawCircle(circleX, circleY, mMinCircleRadius, mPaint)

        val r2 = mHeight / 2f - mMinCircleRadius
        mPaint.apply {
            style = Paint.Style.STROKE
            strokeWidth = mCircleStrokeWidth
            color = if (mValue < mMaxValue - 1) {
                ContextCompat.getColor(mContext, R.color.white_gray_color)
            } else {
                mValueColor
            }
        }
        mRectF.apply {
            left = circleX - r2
            top = mHeight / 2f - mPaint.strokeWidth
            right = circleX + r2
            bottom = circleY + r2 - mPaint.strokeWidth
        }
        canvas.drawArc(mRectF, -135f, 90f, false, mPaint)

        val r3 = mHeight - mMinCircleRadius
        mPaint.color = if (mValue < mMaxValue) {
            ContextCompat.getColor(mContext, R.color.white_gray_color)
        } else {
            mValueColor
        }
        mRectF.apply {
            left = circleX - r3
            top = 0f + mPaint.strokeWidth / 2f
            right = circleX + r3
            bottom = circleY + r3 + mPaint.strokeWidth / 2f
        }
        canvas.drawArc(mRectF, -135f, 90f, false, mPaint)

        if (isShowLock) {
            mPaint.apply {
                style = Paint.Style.FILL
                color = mValueColor
            }
            val r = mMinCircleRadius / 3
            mRectF.apply {
                left = mWidth - mMinCircleRadius * 2.2f
                top = mHeight - mMinCircleRadius * 2.2f
                right = mWidth.toFloat()
                bottom = mHeight.toFloat()
            }
            canvas.drawRoundRect(mRectF, r, r, mPaint)

            val l = (mRectF.right - mRectF.left) / 6f
            mRectF.apply {
                left = mWidth - (l * 5)
                top = mHeight / 2f + mMinCircleRadius / 1.5f
                right = mWidth - l
                bottom = mHeight - mMinCircleRadius / 1.5f
            }
            mPaint.apply {
                style = Paint.Style.STROKE
                strokeWidth = AppUtils.dpToPx(1.5f)
            }
            canvas.drawOval(mRectF, mPaint)
        }
    }

    fun setValue(value: Int, showLock: Boolean = false) {
        mValue = if (value > mMaxValue) mMaxValue
        else if (value < 0) 0
        else value
        isShowLock = showLock
        invalidate()
    }

}