package com.adealink.weparty.commonui.widget.waveview

import android.content.Context
import android.graphics.BlurMaskFilter
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.RectF
import android.os.Handler
import android.os.Looper
import android.util.AttributeSet
import android.view.View
import androidx.core.content.withStyledAttributes
import androidx.core.graphics.toColorInt
import com.adealink.weparty.R
import java.util.LinkedList
import kotlin.math.PI
import kotlin.math.max
import kotlin.math.min
import kotlin.math.sin
import kotlin.random.Random

class SoundWaveView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {

    // 柱状数据
    private val barHeights = LinkedList<Float>()
    private val barColors = LinkedList<Int>()

    // 绘制相关
    private val barPaint = Paint().apply {
        isAntiAlias = true
        style = Paint.Style.FILL
        strokeCap = Paint.Cap.ROUND
    }

    private val glowPaint = Paint().apply {
        isAntiAlias = true
        style = Paint.Style.FILL
        maskFilter = BlurMaskFilter(15f, BlurMaskFilter.Blur.NORMAL)
    }

    private val highlightPaint = Paint().apply {
        color = Color.argb(50, 255, 255, 255)
        style = Paint.Style.FILL
    }

    private val linePaint = Paint().apply {
        color = "#33FFFFFF".toColorInt()
        strokeWidth = 1f
        //pathEffect = DashPathEffect(floatArrayOf(10f, 5f), 0f)
    }

    // 渐变颜色
    private var lowColor = "#4CAF50".toColorInt()    // 低分贝 - 绿色
    private var midColor = "#FF9800".toColorInt()    // 中分贝 - 橙色
    private var highColor = "#F44336".toColorInt()   // 高分贝 - 红色

    // 动画控制
    private val handler = Handler(Looper.getMainLooper())
    private var isAnimating = false
    private var isPause = false
    private val animationRunnable = object : Runnable {
        override fun run() {
            updateBars()
            invalidate()
            if (isAnimating) {
                handler.postDelayed(this, FRAME_DELAY)
            }
        }
    }

    // 配置参数
    var dbValue: Float = 50f
        set(value) {
            field = value.coerceIn(0f, 100f)
        }

    var barWidth: Float = 8f
        set(value) {
            field = value.coerceIn(4f, 20f)
        }

    var barSpacing: Float = 4f
        set(value) {
            field = value.coerceIn(2f, 10f)
        }

    var showGlow: Boolean = true
        set(value) {
            field = value
            invalidate()
        }

    var waveSpeed: Float = 3f
        set(value) {
            field = value.coerceIn(1f, 10f)
        }

    // 初始化
    init {
        // 初始填充一些数据
        val initialBars = calculateMaxBars()
        repeat(initialBars) {
            barHeights.add(height * 0.3f)
            barColors.add(lowColor)
        }

        // 从属性获取配置
        attrs?.let {
            context.withStyledAttributes(it, R.styleable.SoundWaveView) {
                barWidth = getDimension(R.styleable.SoundWaveView_barWidth, barWidth)
                barSpacing = getDimension(R.styleable.SoundWaveView_barSpacing, barSpacing)
                waveSpeed = getFloat(R.styleable.SoundWaveView_waveSpeed, waveSpeed)
                showGlow = getBoolean(R.styleable.SoundWaveView_showGlow, true)
            }
        }
    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        // 重新初始化数据以适应新的宽度
        initializeBarData()
    }

    private fun calculateMaxBars(): Int {
        val barTotalWidth = barWidth + barSpacing
        return (width / barTotalWidth).toInt() + 10 // 多加一些作为缓冲
    }

    private fun initializeBarData() {
        barHeights.clear()
        barColors.clear()
//        val maxBars = calculateMaxBars()
//        repeat(maxBars) {
//            barHeights.add(height * 0.3f)
//            barColors.add(lowColor)
//        }
    }

    // 更新分贝值并添加新的柱状条
    fun updateDecibel(db: Float) {
        this.dbValue = db

        // 根据分贝值计算柱状高度
        val barHeight = calculateBarHeight(dbValue)

        // 根据分贝值确定颜色
        val barColor = calculateBarColor(dbValue)

        // 添加到数据列表
        barHeights.add(barHeight)
        barColors.add(barColor)

        // 保持数据量在合理范围内
        if (barHeights.size > MAX_BARS) {
            for (i in 0 until barHeights.size - MAX_BARS) {
                barHeights.removeFirst()
                barColors.removeFirst()
            }
        }
    }

    private fun calculateBarHeight(db: Float): Float {
        // 将分贝值映射为柱状高度（0-100分贝映射为高度的0.1-0.9倍）
        val normalizedDb = db / 100f

        // 使用非线性映射，使变化更明显
        val heightRatio = if (normalizedDb < 0.5) {
            normalizedDb * 1.2f  // 低分贝区变化较快
        } else {
            0.6f + (normalizedDb - 0.5f) * 0.6f  // 高分贝区变化较慢
        }

        var height = height * (0.1f + heightRatio * 0.8f)

        // 添加随机抖动，使效果更自然
        val randomJitter = Random.nextFloat() * height * 0.05f
        val time = System.currentTimeMillis() / 1000.0
        val waveJitter = sin(time * PI * 2) * height * 0.03f

        height += (randomJitter + waveJitter.toFloat())

        return height.coerceIn(0f, height.toFloat())
    }

    private fun calculateBarColor(db: Float): Int {
        // 根据分贝值计算颜色
        val normalizedDb = db / 100f

        return when {
            normalizedDb < 0.33 -> {
                // 绿色到橙色渐变
                val ratio = normalizedDb / 0.33f
                interpolateColor(lowColor, midColor, ratio)
            }

            normalizedDb < 0.66 -> {
                // 橙色到红色渐变
                val ratio = (normalizedDb - 0.33f) / 0.33f
                interpolateColor(midColor, highColor, ratio)
            }

            else -> {
                // 红色
                highColor
            }
        }
    }

    private fun interpolateColor(startColor: Int, endColor: Int, ratio: Float): Int {
        val startA = Color.alpha(startColor)
        val startR = Color.red(startColor)
        val startG = Color.green(startColor)
        val startB = Color.blue(startColor)

        val endA = Color.alpha(endColor)
        val endR = Color.red(endColor)
        val endG = Color.green(endColor)
        val endB = Color.blue(endColor)

        val a = (startA + (endA - startA) * ratio).toInt()
        val r = (startR + (endR - startR) * ratio).toInt()
        val g = (startG + (endG - startG) * ratio).toInt()
        val b = (startB + (endB - startB) * ratio).toInt()

        return Color.argb(a, r, g, b)
    }

    private fun updateBars() {
        // 平滑移动：向左移动
        val barsToMove = (waveSpeed * 0.3).toInt()
        if (barsToMove > 0 && barHeights.size > barsToMove) {
            // 移除最左边的条
            repeat(barsToMove) {
                barHeights.removeFirst()
                barColors.removeFirst()
            }
        }

        // 添加新的条来填充
        val barHeight = calculateBarHeight(dbValue)
        val barColor = calculateBarColor(dbValue)
        repeat(barsToMove) {
            barHeights.add(barHeight)
            barColors.add(barColor)
        }
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)

        // 绘制背景
        //canvas.drawRect(0f, 0f, width.toFloat(), height.toFloat(), bgPaint)

        // 绘制柱状声波
        drawBars(canvas)

        // 绘制中心线
        drawCenterLine(canvas)
    }

    private fun drawBars(canvas: Canvas) {
        if (barHeights.isEmpty()) return

        val barTotalWidth = barWidth + barSpacing
        val visibleBars = min(barHeights.size, (width / barTotalWidth).toInt() + 1)
        val startIndex = max(0, barHeights.size - visibleBars)

        // 创建圆形矩形
        val rect = RectF()
        val radius = barWidth / 3

        for (i in 0 until visibleBars) {
            val index = startIndex + i
            if (index >= barHeights.size) break

            // 计算条形位置（从右向左绘制）
            val x = width - (barHeights.size - index) * barTotalWidth
            val barHeight = barHeights[index]
            val barColor = barColors[index]

            // 计算条形顶部和底部位置（从中心向上下展开）
            val centerY = height / 2f
            val top = centerY - barHeight / 2
            val bottom = centerY + barHeight / 2

            // 设置条形颜色
            barPaint.color = barColor
            barPaint.strokeWidth = barWidth

            // 绘制发光效果
            if (showGlow) {
                glowPaint.color = Color.argb(
                    100, Color.red(barColor),
                    Color.green(barColor), Color.blue(barColor)
                )

                rect.set(x - 2, top - 5, x + barWidth + 2, bottom + 5)
                canvas.drawRoundRect(rect, radius + 2, radius + 2, glowPaint)
            }

            // 绘制主条形
            //rect.set(x, top, x + barWidth)
            //canvas.drawRoundRect(rect, radius, radius, barPaint)
            canvas.drawLine(x + barWidth / 2, top, x + barWidth / 2, bottom, barPaint)

            // 绘制条形内部高光
            if (barHeight > 20) {
                val highlightRect = RectF(
                    x + 1,
                    centerY - barHeight / 4,
                    x + barWidth - 1,
                    centerY
                )
                canvas.drawRoundRect(highlightRect, radius / 2, radius / 2, highlightPaint)
            }
        }
    }

    private fun drawCenterLine(canvas: Canvas) {
        val centerY = height / 2f
        canvas.drawLine(0f, centerY, width.toFloat(), centerY, linePaint)
    }

    fun start() {
        if (!isAnimating) {
            isAnimating = true
            isPause = false
            handler.post(animationRunnable)
        }
    }

    fun pause() {
        if (isAnimating) {
            isPause = true
            handler.removeCallbacks(animationRunnable)
        }
    }

    fun resume() {
        if (isAnimating && isPause) {
            isPause = false
            handler.post(animationRunnable)
        }
    }

    fun stop() {
        isAnimating = false
        isPause = false
        handler.removeCallbacks(animationRunnable)
    }

    fun clear() {
        barHeights.clear()
        barColors.clear()
        initializeBarData()
        invalidate()
    }

    // 设置自定义颜色
    fun setColorRange(low: Int, mid: Int, high: Int) {
        lowColor = low
        midColor = mid
        highColor = high
        invalidate()
    }

    // 批量更新分贝值（用于真实音频数据）
    fun updateDecibelBatch(dbs: List<Float>) {
        dbs.forEach { db ->
            updateDecibel(db)
        }
    }

    override fun onAttachedToWindow() {
        super.onAttachedToWindow()
        start()
    }

    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        stop()
    }

    companion object {
        private const val FRAME_DELAY = 16L // 约60fps
        private const val MAX_BARS = 500
    }
}