package com.erwan.revwatch.ui

import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.Typeface
import android.util.AttributeSet
import android.view.HapticFeedbackConstants
import android.view.MotionEvent
import android.view.View
import com.erwan.revwatch.util.dp

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

    private var letters = listOf<Char>()
    private var activeLetter: Char? = null
    var onLetterSelected: ((Char) -> Unit)? = null

    private val normalPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        color = 0xFF6B7588.toInt()
        textSize = context.dp(9).toFloat()
        textAlign = Paint.Align.CENTER
        typeface = Typeface.DEFAULT_BOLD
    }

    private val activePaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        color = 0xFF49D6FF.toInt()
        textSize = context.dp(11).toFloat()
        textAlign = Paint.Align.CENTER
        typeface = Typeface.DEFAULT_BOLD
    }

    private val bubblePaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        color = 0xDD1A1A2E.toInt()
    }

    private val bubbleTextPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        color = 0xFF49D6FF.toInt()
        textSize = context.dp(18).toFloat()
        textAlign = Paint.Align.CENTER
        typeface = Typeface.DEFAULT_BOLD
    }

    fun setLetters(letters: List<Char>) {
        this.letters = letters
        activeLetter = null
        invalidate()
    }

    override fun onDraw(canvas: Canvas) {
        if (letters.isEmpty()) return

        val cellH = height.toFloat() / letters.size
        val cx = width / 2f

        letters.forEachIndexed { i, letter ->
            val cy = cellH * i + cellH / 2
            val paint = if (letter == activeLetter) activePaint else normalPaint
            val textOffset = paint.textSize / 3f
            canvas.drawText(letter.toString(), cx, cy + textOffset, paint)
        }

        // Draw bubble feedback to the left when touching
        activeLetter?.let { letter ->
            val i = letters.indexOf(letter)
            if (i < 0) return@let
            val cy = cellH * i + cellH / 2
            val bubbleR = context.dp(16).toFloat()
            val bubbleX = -context.dp(18).toFloat()
            canvas.drawCircle(bubbleX, cy, bubbleR, bubblePaint)
            val textOffset = bubbleTextPaint.textSize / 3f
            canvas.drawText(letter.toString(), bubbleX, cy + textOffset, bubbleTextPaint)
        }
    }

    override fun onTouchEvent(event: MotionEvent): Boolean {
        if (letters.isEmpty()) return super.onTouchEvent(event)

        when (event.action) {
            MotionEvent.ACTION_DOWN, MotionEvent.ACTION_MOVE -> {
                val cellH = height.toFloat() / letters.size
                val index = (event.y / cellH).toInt().coerceIn(0, letters.lastIndex)
                val letter = letters[index]
                if (letter != activeLetter) {
                    activeLetter = letter
                    performHapticFeedback(HapticFeedbackConstants.CLOCK_TICK)
                    onLetterSelected?.invoke(letter)
                    invalidate()
                }
                parent?.requestDisallowInterceptTouchEvent(true)
                return true
            }
            MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                activeLetter = null
                invalidate()
                parent?.requestDisallowInterceptTouchEvent(false)
                return true
            }
        }
        return super.onTouchEvent(event)
    }
}
