package com.tomhempel.rbarometer.questionnaire.handlers

import android.content.Context
import android.view.View
import android.widget.Button
import android.widget.SeekBar
import android.widget.TextView
import com.tomhempel.rbarometer.LanguageManager
import com.tomhempel.rbarometer.R
import com.tomhempel.rbarometer.questionnaire.QuestionFlowResolver
import com.tomhempel.rbarometer.questionnaire.QuestionHandler
import com.tomhempel.rbarometer.questionnaire.QuestionItem
import com.tomhempel.rbarometer.questionnaire.QuestionNotesHelper
import com.tomhempel.rbarometer.utils.ViewUtils

class HandlerSliderQuestion(
    private val context: Context,
    private val answers: MutableMap<String, Any>,
    private val languageID: String,
    private val goToNextQuestion: () -> Unit,
    private val goToPreviousQuestion: () -> Unit,
    private val goToQuestionById: (String) -> Unit,
    private val showToast: (String) -> Unit,
    private val onAnswerChanged: () -> Unit = {},
) : QuestionHandler {

    private lateinit var layout: View
    private lateinit var question: QuestionItem.SliderQuestion
    private lateinit var seekBar: SeekBar
    private lateinit var valueLabel: TextView

    private var minVal = 0
    private var maxVal = 100
    private var step = 1

    override fun bind(layout: View, question: QuestionItem) {
        if (question !is QuestionItem.SliderQuestion) return
        this.layout = layout
        this.question = question

        val questionTextView = layout.findViewById<TextView>(R.id.question)
        val titleTextView = layout.findViewById<TextView>(R.id.textView)
        seekBar = layout.findViewById(R.id.value_slider)
        valueLabel = layout.findViewById(R.id.slider_value)
        val minLabel = layout.findViewById<TextView>(R.id.slider_min)
        val maxLabel = layout.findViewById<TextView>(R.id.slider_max)

        QuestionNotesHelper.bind(layout, languageID, question.noteBeforeKey, question.noteAfterKey)

        val questionKey = question.question.trim()
        questionTextView.text =
            if (questionKey.isNotEmpty()) LanguageManager.getText(languageID, questionKey) else ""
        questionTextView.visibility =
            if (questionTextView.text.isNullOrBlank()) View.GONE else View.VISIBLE

        val titleKey = question.textKey?.trim().orEmpty()
        titleTextView.text =
            if (titleKey.isNotEmpty()) LanguageManager.getText(languageID, titleKey) else ""
        titleTextView.visibility =
            if (titleTextView.text.isNullOrBlank()) View.GONE else View.VISIBLE

        ViewUtils.setTextSizePercentOfScreenHeight(titleTextView, 0.03f)
        ViewUtils.setTextSizePercentOfScreenHeight(questionTextView, 0.03f)
        ViewUtils.setTextSizePercentOfScreenHeight(valueLabel, 0.028f)

        val range = question.range
        minVal = range?.min ?: 0
        maxVal = range?.max ?: 100
        step = (question.step ?: 1).coerceAtLeast(1)

        minLabel.text = formatValue(minVal)
        maxLabel.text = formatValue(maxVal)
        ViewUtils.setTextSizePercentOfScreenHeight(minLabel, 0.022f)
        ViewUtils.setTextSizePercentOfScreenHeight(maxLabel, 0.022f)

        val span = ((maxVal - minVal) / step).coerceAtLeast(1)
        seekBar.max = span

        val saved = question.question.let { answers[it] as? String }?.toIntOrNull()
        val initial = saved?.coerceIn(minVal, maxVal) ?: minVal
        seekBar.progress = ((initial - minVal) / step).coerceIn(0, span)
        updateValueLabel(currentValue())

        seekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
            override fun onProgressChanged(sb: SeekBar?, progress: Int, fromUser: Boolean) {
                updateValueLabel(valueForProgress(progress))
                if (fromUser) onAnswerChanged()
            }
            override fun onStartTrackingTouch(sb: SeekBar?) {}
            override fun onStopTrackingTouch(sb: SeekBar?) {
                sb?.let { updateValueLabel(valueForProgress(it.progress)) }
                onAnswerChanged()
            }
        })

        layout.findViewById<Button>(R.id.Qnext).setOnClickListener {
            if (validate()) {
                saveAnswer()
                QuestionFlowResolver.navigateAfterAnswer(
                    question.nextQuestionId,
                    goToQuestionById,
                    goToNextQuestion,
                )
            }
        }
        layout.findViewById<Button>(R.id.Qprev).setOnClickListener {
            saveAnswer()
            goToPreviousQuestion()
        }
    }

    private fun currentValue(): Int = valueForProgress(seekBar.progress)

    private fun valueForProgress(progress: Int): Int = minVal + progress * step

    private fun updateValueLabel(value: Int) {
        valueLabel.text = formatValue(value)
    }

    private fun formatValue(value: Int): String {
        val unit = question.unitLabel?.let { LanguageManager.getText(languageID, it) }?.trim().orEmpty()
        return if (unit.isNotEmpty()) "$value $unit" else value.toString()
    }

    override fun validate(): Boolean = true

    override fun saveAnswer() {
        val key = question.question
        if (key.isNotBlank()) {
            answers[key] = currentValue().toString()
        }
    }
}
