package com.gh.gamecenter.common.view

import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.Path
import android.graphics.RectF
import android.util.AttributeSet
import android.view.View
import androidx.annotation.FloatRange
import com.gh.gamecenter.common.R
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.common.utils.toColor
import kotlin.math.cos
import kotlin.math.sin
import kotlin.math.tan

class TrapezoidProgressBar @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
    private val leftPaint = Paint(Paint.ANTI_ALIAS_FLAG)
    private val rightPaint = Paint(Paint.ANTI_ALIAS_FLAG)

    private var partMinWidth = 0F
    private var partMaxWidth = 0F

    private val leftPositiveColor = R.color.primary_theme
    private val leftNegativeColor = R.color.primary_theme_10
    private val rightPositiveColor = R.color.secondary_red
    private val rightNegativeColor = R.color.secondary_red_10

    private var viewWidth = 0F
    private var viewHeight = 0F

    private val cornerRadius = 4F.dip2px(context).toFloat()
    private val angle = Math.toRadians(65.0).toFloat()
    private val gap = 4F.dip2px(context).toFloat() // 左右两部分中间的间距
    private var offset = 0F // 长短边差值

    private var leftPositive = false
    private var rightPositive = true
    private var leftProgressColor = (if (leftPositive) leftPositiveColor else leftNegativeColor).toColor(context)
    private var rightProgressColor = (if (rightPositive) rightPositiveColor else rightNegativeColor).toColor(context)

    @FloatRange(from = 0.0, to = 1.0)
    var progress = 0F

    fun show(leftPositive: Boolean, rightPositive: Boolean, @FloatRange(from = 0.0, to = 1.0) progress: Float) {
        this.leftPositive = leftPositive
        this.rightPositive = rightPositive
        this.progress = progress
        updateColor()
        invalidate()
    }

    private fun updateColor() {
        leftProgressColor = (if (leftPositive) leftPositiveColor else leftNegativeColor).toColor(context)
        rightProgressColor = (if (rightPositive) rightPositiveColor else rightNegativeColor).toColor(context)
    }

    override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
        super.onLayout(changed, left, top, right, bottom)
        viewHeight = height.toFloat()
        viewWidth = width.toFloat()
        partMinWidth = viewWidth * MIN_RATIO
        partMaxWidth = viewWidth * MAX_RATIO
        offset = viewHeight / tan(angle)
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        leftPaint.color = leftProgressColor
        rightPaint.color = rightProgressColor
        leftPaint.style = Paint.Style.FILL
        rightPaint.style = Paint.Style.FILL
        if (progress == 0F || progress == 1F) {
            drawFull(canvas)
        } else {
            drawParts(canvas)
        }
    }

    private fun drawFull(canvas: Canvas) {
        val rectF = RectF().apply {
            left = 0F
            right = viewWidth
            top = 0F
            bottom = viewHeight
        }
        val paint = if (progress == 0F) rightPaint else leftPaint
        canvas.drawRoundRect(rectF, viewHeight / 2F, viewHeight / 2F, paint)
    }

    private fun drawParts(canvas: Canvas) {
        val leftEndX = partMinWidth + (partMaxWidth - partMinWidth) * progress
        val rightStartX = leftEndX - offset + gap
        val leftPartPath = getLeftPartPath(leftEndX)
        val rightPartPath = getRightPartPath(rightStartX)

        canvas.drawPath(leftPartPath, leftPaint)
        canvas.drawPath(rightPartPath, rightPaint)
    }

    private fun getLeftPartPath(endX: Float): Path = Path().apply {
        val bottomRightX = endX - viewHeight / tan(angle)
        val cosValue = cornerRadius * cos(angle)
        val sinValue = cornerRadius * sin(angle)
        val leftRadius = viewHeight / 2F

        moveTo(endX - cornerRadius, 0F) // 右上角

        quadTo(
            endX,
            0F,
            endX - cosValue,
            sinValue
        ) // 右上圆角

        lineTo(
            bottomRightX + cosValue,
            viewHeight - sinValue
        ) // 右下角

        quadTo(
            bottomRightX,
            viewHeight,
            bottomRightX - cosValue - cornerRadius,
            viewHeight
        ) // 右下圆角

        lineTo(leftRadius, viewHeight) // 左下角

        arcTo(
            RectF(
                0F,
                0F,
                2 * leftRadius,
                2 * leftRadius
            ),
            90F,
            180F,
            false
        ) // 左半圆

        close()
    }

    private fun getRightPartPath(startX: Float): Path = Path().apply {
        val topLeftX = startX + viewHeight / tan(angle)
        val cosValue = cornerRadius * cos(angle)
        val sinValue = cornerRadius * sin(angle)
        val rightRadius = viewHeight / 2F

        moveTo(startX + cornerRadius, viewHeight) // 左下角

        quadTo(
            startX,
            viewHeight,
            cosValue + startX,
            viewHeight - sinValue
        ) // 左下圆角

        lineTo(
            topLeftX - cosValue,
            sinValue
        ) // 左上角

        quadTo(
            topLeftX,
            0F,
            topLeftX + cosValue + cornerRadius,
            0F
        ) // 左上圆角

        lineTo(viewWidth - rightRadius, 0F) // 右上角

        arcTo(
            RectF(
                viewWidth - 2 * rightRadius,
                0F,
                viewWidth,
                viewHeight
            ),
            270F,
            180F,
            false
        ) // 右半圆

        close()
    }

    companion object {
        const val MIN_RATIO = 0.16F
        const val MAX_RATIO = 0.89F
    }
}