package kr.co.vividnext.sodalive.live.roulette

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.RectF
import android.util.AttributeSet
import android.view.View
import android.view.animation.Animation
import android.view.animation.RotateAnimation
import kotlin.math.cos
import kotlin.math.min
import kotlin.math.sin

class RouletteView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
    private var rect = RectF()

    private val fillPaint = Paint()
    private val textPaint = Paint()
    private val strokePaint = Paint()

    var items = listOf<RouletteItem>()

    private val colors = listOf(
        Color.parseColor("#D73535"),
        Color.parseColor("#FF5151"),
        Color.parseColor("#FF7C32"),
        Color.parseColor("#FFAF13"),
        Color.parseColor("#FFC658"),
        Color.parseColor("#8BDA70"),
        Color.parseColor("#06AB97"),
        Color.parseColor("#12AAFF"),
        Color.parseColor("#0052B3"),
        Color.parseColor("#7444FF")
    )

    init {
        strokePaint.apply {
            color = Color.WHITE
            style = Paint.Style.STROKE
            strokeWidth = 10f
            isAntiAlias = true
        }

        fillPaint.apply {
            style = Paint.Style.FILL
            isAntiAlias = true
        }

        textPaint.apply {
            color = Color.WHITE
            textSize = 30f
            textAlign = Paint.Align.CENTER
        }
    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)

        val diameter = min(width, height) - strokePaint.strokeWidth
        rect.set(
            0f + strokePaint.strokeWidth / 2,
            0f + strokePaint.strokeWidth / 2,
            diameter,
            diameter
        )
    }

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

        var startAngle = -90f
        val shuffledColors = colors.shuffled()
        items.forEachIndexed { index, (option, percentage) ->
            val sweepAngle = (percentage / 100) * 360f
            fillPaint.color = shuffledColors[index]
            canvas.drawArc(rect, startAngle, sweepAngle, true, fillPaint)

            drawOptionText(canvas, option, startAngle, sweepAngle)
            startAngle += sweepAngle
        }

        canvas.drawCircle(rect.centerX(), rect.centerY(), rect.width() / 2, strokePaint)
    }

    private fun drawOptionText(
        canvas: Canvas,
        option: String,
        startAngle: Float,
        sweepAngle: Float
    ) {
        val textRadius = rect.width() / 4  // Increase radius to move text outside the circle
        val angle = Math.toRadians((startAngle + sweepAngle / 2).toDouble()).toFloat()

        // Calculate the text position
        val x = rect.centerX() + textRadius * cos(angle) + 10
        val y = rect.centerY() + textRadius * sin(angle)

        // Save the canvas state
        val saveCount = canvas.save()

        // Rotate the canvas around the text position
        canvas.rotate(startAngle + sweepAngle / 2, x, y)

        // Draw the text aligned with the segment
        canvas.drawText(option, x, y, textPaint)

        // Restore the canvas to its previous state
        canvas.restoreToCount(saveCount)
    }

    private fun getAngleForOption(option: String): Float {
        var startAngle = 0f

        items.forEach { (currentOption, percentage) ->
            val sweepAngle = (percentage / 100) * 360f
            if (currentOption == option) {
                // Return the midpoint angle of the segment
                return (startAngle + sweepAngle / 2)
            }
            startAngle += sweepAngle
        }
        return 0f
    }

    fun rotateToOption(option: String, complete: () -> Unit) {
        val targetAngle = 0 - (getAngleForOption(option) + 360 * 10)

        val rotateAnimation = RotateAnimation(
            0f, targetAngle,
            RotateAnimation.RELATIVE_TO_SELF, 0.5f,
            RotateAnimation.RELATIVE_TO_SELF, 0.5f
        )
        rotateAnimation.duration = 2000
        rotateAnimation.fillAfter = true
        rotateAnimation.setAnimationListener(object : Animation.AnimationListener {
            override fun onAnimationStart(animation: Animation?) {
            }

            override fun onAnimationEnd(animation: Animation?) {
                complete()
            }

            override fun onAnimationRepeat(animation: Animation?) {
            }
        })

        startAnimation(rotateAnimation)
    }
}
