package com.adealink.weparty.commonui.widget.progress

import android.animation.ValueAnimator
import android.content.Context
import android.graphics.Canvas
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 android.view.animation.LinearInterpolator
import androidx.core.content.withStyledAttributes
import com.adealink.frame.aab.util.getCompatColor
import com.adealink.frame.base.fastLazy
import com.adealink.frame.util.DisplayUtil
import com.adealink.weparty.R
import kotlin.math.sin

class SinWaveProgressBar @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0,
) : View(context, attrs, defStyleAttr) {
    private var viewWidth = 0
    private var viewHeight = 0

    //背景
    private val bgLinePath by fastLazy { Path() }
    private val bgLinePaint by fastLazy {
        Paint(Paint.ANTI_ALIAS_FLAG).apply {
            style = Paint.Style.FILL
            isAntiAlias = true
            color = getCompatColor(R.color.color_FFDE2AEF)
        }
    }

    //前景
    private val fgLinePath by fastLazy { Path() }
    private val fgLinePaint by fastLazy {
        Paint(Paint.ANTI_ALIAS_FLAG).apply {
            style = Paint.Style.FILL
            isAntiAlias = true
            shader = LinearGradient(
                0F, 0F,  // 渐变起点坐标
                0F, viewHeight.toFloat(),      // 渐变终点坐标
                intArrayOf(
                    getCompatColor(R.color.color_FFF683FF),
                    getCompatColor(R.color.color_FFFAB4FF),
                    getCompatColor(R.color.color_FFF9AEFF),  // 渐变颜色数组
                    getCompatColor(R.color.color_FFF683FF),
                ),
                floatArrayOf(0.25F, 0.4F, 0.6F, 0.75F),           // 颜色位置（null表示均匀分布）
                Shader.TileMode.CLAMP  // 渐变填充模式
            )
        }
    }

    //振幅,单位px
    private var amplitude: Float = 0F

    //角频率， 控制周期
    private var angularFrequency: Float = 0F

    //初次相位角,
    private var phaseAngle = 0 * Math.PI / 180 + Math.PI / 2 * -1

    //相位动画持续时间
    private var animationDuration: Int = 0

    //波浪起始点的y坐标
    private val waveStartY: Float
        get() {
            return viewHeight * (1 - progress) + amplitude * 2
        }

    //波浪起始点的y坐标
    private val waveStartX: Float
        get() {
            return viewWidth * (progress) + amplitude * 2
        }
    var progress: Float = 0f
        set(value) {
            if (field == value) {
                return
            }
            field = value
            startWaveAnimation()
        }
    var animator: ValueAnimator? = null

    init {
        context.withStyledAttributes(attrs, R.styleable.SinWaveProgressBar) {
            amplitude = getDimension(
                R.styleable.SinWaveProgressBar_amplitude,
                DisplayUtil.dp2px(5f).toFloat()
            )
            val frequency = getFloat(R.styleable.SinWaveProgressBar_frequency, 8f)
            angularFrequency = frequency * 1.0f / 4
            val radian = getFloat(R.styleable.SinWaveProgressBar_phaseAngleRadian, 0f)
            phaseAngle = radian * Math.PI / 180 + Math.PI / 2 * -1
            animationDuration = getInt(R.styleable.SinWaveProgressBar_animationDuration, 1000)
        }
    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        viewWidth = w
        viewHeight = h
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        when {
            progress >= 100 -> drawComplete(canvas)
            progress <= 0 -> {} //不绘制
            else -> drawRunning(canvas)
        }
    }

    private fun drawComplete(canvas: Canvas) {
        canvas.drawRect(0f, 0f, viewWidth.toFloat(), viewHeight.toFloat(), fgLinePaint)
    }

    private fun drawRunning(canvas: Canvas) {
        bgLinePath.reset()
        fgLinePath.reset()

        // 水平波浪从左侧开始
        bgLinePath.moveTo(waveStartX, 0f)
        fgLinePath.moveTo(waveStartX, 0f)

        // 计算波浪路径
        for (i in 0 until viewHeight) {
            val angle = i * 1f / viewHeight * 2 * Math.PI
            val x1 = amplitude * sin(angle * angularFrequency + phaseAngle)
            bgLinePath.lineTo((x1 + waveStartX - amplitude).toFloat(), i.toFloat())
            fgLinePath.lineTo((-x1 + waveStartX - amplitude).toFloat(), i.toFloat())
        }

        // 闭合路径形成填充区域
        bgLinePath.lineTo(0f, viewHeight.toFloat())
        bgLinePath.lineTo(0f, 0f)
        bgLinePath.close()
        fgLinePath.lineTo(0f, viewHeight.toFloat())
        fgLinePath.lineTo(0f, 0f)
        fgLinePath.close()

        canvas.drawPath(bgLinePath, bgLinePaint)
        canvas.drawPath(fgLinePath, fgLinePaint)
    }

    /**
     * 振幅
     */
    fun setAmplitude(amplitude: Float) {
        this.amplitude = amplitude
        invalidate()
    }

    /**
     * 角频率
     */
    fun setAngularFrequency(frequency: Int) {
        angularFrequency = frequency * 1.0f / 4
        invalidate()
    }

    /**
     * 初次相位角
     */
    fun setPhaseAngle(radian: Float) {
        this.phaseAngle = radian * Math.PI / 180 + Math.PI / 2 * -1
        invalidate()
    }

    fun startWaveAnimation() {
        animator = ValueAnimator.ofInt(0, DisplayUtil.getScreenWidth())
        animator?.duration = animationDuration.toLong()
        animator?.repeatCount = ValueAnimator.INFINITE
        animator?.interpolator = LinearInterpolator()
        animator?.addUpdateListener { animation ->
            val phase = animation?.animatedValue as? Int ?: 0
            setPhaseAngle(phase.toFloat())
        }
        animator?.start()
    }

    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        animator?.cancel()
    }
}