package com.photobooth.app

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View

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

    var value: Int = 0
        set(newValue) {
            val clamped = newValue.coerceIn(minVal, maxVal)
            if (field != clamped) {
                field = clamped
                invalidate()
                onValueChangeListener?.invoke(clamped)
            }
        }

    var minVal: Int = -100
        set(newValue) {
            field = newValue
            invalidate()
        }

    var maxVal: Int = 100
        set(newValue) {
            field = newValue
            invalidate()
        }

    var onValueChangeListener: ((Int) -> Unit)? = null

    private val paint = Paint(Paint.ANTI_ALIAS_FLAG)
    private var lastX = 0f
    private var isDragging = false

    private val density = resources.displayMetrics.density
    private fun dp(value: Float) = value * density

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        val w = width.toFloat()
        val h = height.toFloat()
        val cx = w / 2f

        // Draw ticks
        // One tick mark every tickInterval value units.
        // The spacing in pixels between tickInterval units is tickSpacingPx.
        val tickInterval = 2
        val tickSpacingPx = dp(8f)

        // Draw ticks within visible area
        val unitsPerPixel = tickInterval / tickSpacingPx
        val minVisibleUnit = (value - cx * unitsPerPixel).toInt() - 5
        val maxVisibleUnit = (value + cx * unitsPerPixel).toInt() + 5

        for (u in minVisibleUnit..maxVisibleUnit) {
            if (u < minVal || u > maxVal) continue
            if (u % tickInterval != 0) continue

            val x = cx + (u - value) * (tickSpacingPx / tickInterval)
            if (x < 0 || x > w) continue

            val isMajor = u % 10 == 0
            val isMedium = u % 5 == 0 && !isMajor

            val tickHeight = when {
                isMajor -> dp(20f)
                isMedium -> dp(14f)
                else -> dp(8f)
            }

            paint.color = if (isMajor) Color.WHITE else Color.GRAY
            paint.strokeWidth = if (isMajor) dp(1.5f) else dp(1.0f)

            // Draw line from bottom upwards
            canvas.drawLine(x, h, x, h - tickHeight, paint)
        }
    }

    override fun onTouchEvent(event: MotionEvent): Boolean {
        parent.requestDisallowInterceptTouchEvent(true)
        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                lastX = event.x
                isDragging = true
            }
            MotionEvent.ACTION_MOVE -> {
                if (isDragging) {
                    val deltaX = event.x - lastX
                    lastX = event.x
                    // Move the value proportionally to translation
                    val tickSpacingPx = dp(8f)
                    val tickInterval = 2
                    val pixelsPerUnit = tickSpacingPx / tickInterval
                    val deltaVal = -(deltaX / pixelsPerUnit)
                    value = (value + deltaVal).toInt().coerceIn(minVal, maxVal)
                }
            }
            MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                isDragging = false
            }
        }
        return true
    }
}
