package com.isidroid.slider.ext

import android.content.res.ColorStateList
import android.graphics.Rect
import android.view.LayoutInflater
import android.widget.FrameLayout
import android.widget.TextView
import androidx.annotation.ColorInt
import androidx.core.graphics.ColorUtils
import androidx.core.text.bold
import androidx.core.text.buildSpannedString
import androidx.core.view.updateLayoutParams
import com.google.android.material.slider.Slider
import com.isidroid.slider.SliderOption
import com.isidroid.ui.slider.R


internal fun Slider.calculateCoordinates(): List<Int> {
    val tickCount = ((valueTo - valueFrom) / stepSize + 1)
    val interval = trackWidth / (tickCount - 1)

    return (0 until tickCount.toInt()).map { i -> (interval * i).toInt() }
}

internal fun createSliderLabel(
    inflater: LayoutInflater,
    parent: FrameLayout,
    offset: Int,
    text: String?,
    tag: Any?,
    isActive: Boolean,
    @ColorInt labelActiveColor: Int,
    @ColorInt labelDefaultColor: Int,
): TextView {
    val textView = inflater.inflate(R.layout.item_text, parent, false).findViewById<TextView>(R.id.textView)
    textView ?: throw IllegalStateException("Inflated must be a text view but $textView received")

    parent.addView(textView)

    textView.tag = tag
    textView.text = buildSpannedString {
        if(isActive)
            bold { append(text) }
        else
            append(text)
    }
    textView.setTextColor(getSliderLabelColor(isActive, labelActiveColor = labelActiveColor, labelDefaultColor = labelDefaultColor))
    val textWidth = textView.getTextWidth(text).toFloat()
    textView.updateLayoutParams<FrameLayout.LayoutParams> {
        val x = when {
            textWidth + offset > parent.width -> (parent.width - textWidth)
            offset == 0 || (text?.length ?: 0) == 1 -> offset
            else -> offset - (textWidth / 2)
        }.toFloat()

        textView.translationX = x
    }

    return textView
}

@ColorInt
internal fun getSliderLabelColor(isActive: Boolean, @ColorInt labelActiveColor: Int, @ColorInt labelDefaultColor: Int): Int = if (isActive) labelActiveColor else labelDefaultColor

internal fun TextView.getTextWidth(text: String? = null): Int {
    val text1 = text ?: this.text.toString()

    val bounds = Rect()
    val paint = this.paint

    paint.typeface = typeface
    paint.textSize = textSize

    paint.getTextBounds(text1, 0, text1.length, bounds)

    return bounds.width()
}


internal fun Slider.updateSliderColor(@ColorInt trackActiveColor: Int, @ColorInt trackDefaultColor: Int, isEnabled: Boolean = true) {
    val alpha = if(isEnabled) 255 else 128
    val clrActive = ColorUtils.setAlphaComponent(trackActiveColor, alpha)

    val colorActiveStateList = ColorStateList.valueOf(clrActive)
    val colorInactiveStateList = ColorStateList.valueOf(trackDefaultColor)


    thumbTintList = colorActiveStateList
    trackActiveTintList = colorActiveStateList
    trackInactiveTintList = colorInactiveStateList
}

internal inline fun displayActiveSliderLabel(
    labelViewList: List<TextView>,
    @ColorInt labelActiveColor: Int,
    @ColorInt labelDefaultColor: Int,
    findCallback: (tag: Any?) -> Boolean
) {
    val activeView = labelViewList.find { findCallback(it.tag) }
    for (v in labelViewList) {
        val color = getSliderLabelColor(v == activeView, labelActiveColor = labelActiveColor, labelDefaultColor = labelDefaultColor)
        v.setTextColor(color)
    }
}

internal fun findItem(tag: Any?, index: Int, valueList: List<SliderOption>): Boolean {
    val textValue = valueList.getOrNull(index)?.optionMessage
    return (tag as? SliderOption)?.optionMessage == textValue
}
