package com.dano.test1.questionnaire.handlers

import android.content.Context
import android.view.View
import android.widget.*
import kotlinx.coroutines.*
import com.dano.test1.questionnaire.GlobalValues
import com.dano.test1.LanguageManager
import com.dano.test1.MyApp
import com.dano.test1.questionnaire.QuestionHandler
import com.dano.test1.questionnaire.QuestionItem
import com.dano.test1.R
import com.dano.test1.utils.ViewUtils

/*
Zweck:
- Steuert eine Frage, bei der ein numerischer Wert aus einem Spinner gewählt wird.
- Unterstützt sowohl feste Optionslisten als auch numerische Bereiche (min..max).
- Lokalisiert Texte, kann eine frühere Antwort aus der lokalen Room-DB (per AnswerDao) wiederherstellen.

*/

class HandlerValueSpinner(
    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 questionnaireMeta: String
) : QuestionHandler {

    private lateinit var layout: View
    private lateinit var question: QuestionItem.ValueSpinnerQuestion

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

        this.layout = layout
        this.question = question

        val questionTextView = layout.findViewById<TextView>(R.id.question)
        val textView = layout.findViewById<TextView>(R.id.textView)
        val spinner = layout.findViewById<Spinner>(R.id.value_spinner)

        questionTextView.text = question.question?.let { LanguageManager.getText(languageID, it) } ?: ""
        textView.text = question.textKey?.let { LanguageManager.getText(languageID, it) } ?: ""

        ViewUtils.setTextSizePercentOfScreenHeight(textView,          0.03f)
        ViewUtils.setTextSizePercentOfScreenHeight(questionTextView,  0.03f)

        val prompt = LanguageManager.getText(languageID, "choose_answer")
        val spinnerItems: List<String> = listOf(prompt) + if (question.range != null) {
            (question.range.min..question.range.max).map { it.toString() }
        } else {
            question.options.map { it.value.toString() }
        }

        val savedValue = question.question?.let { answers[it] as? String }
        ViewUtils.setupResponsiveSpinner(context, spinner, spinnerItems, savedValue)

        //DB-Abfrage falls noch keine Antwort im Map existiert
        val answerMapKey = question.question ?: (question.id ?: "")
        if (answerMapKey.isNotBlank() && !answers.containsKey(answerMapKey)) {
            CoroutineScope(Dispatchers.IO).launch {
                try {
                    val clientCode = GlobalValues.LAST_CLIENT_CODE
                    if (clientCode.isNullOrBlank()) return@launch

                    val allAnswersForClient = MyApp.database.answerDao().getAnswersForClient(clientCode)
                    val myQuestionId = questionnaireMeta + "-" + question.question
                    val dbAnswer = allAnswersForClient.find { it.questionId == myQuestionId }?.answerValue

                    if (!dbAnswer.isNullOrBlank()) {
                        withContext(Dispatchers.Main) {
                            answers[answerMapKey] = dbAnswer
                            val index = spinnerItems.indexOf(dbAnswer)
                            if (index >= 0) spinner.setSelection(index)
                        }
                    }
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }
        }

        layout.findViewById<Button>(R.id.Qnext).setOnClickListener {
            if (validate()) {
                saveAnswer()
                val selectedValue = (spinner.selectedItem as? String)?.toIntOrNull()

                if (!question.options.isNullOrEmpty() && selectedValue != null) {
                    val selectedOption = question.options.find { it.value == selectedValue }
                    val nextId = selectedOption?.nextQuestionId
                    if (!nextId.isNullOrEmpty()) {
                        goToQuestionById(nextId)
                        return@setOnClickListener
                    }
                }
                goToNextQuestion()
            }
        }

        layout.findViewById<Button>(R.id.Qprev).setOnClickListener {
            goToPreviousQuestion()
        }
    }

    override fun validate(): Boolean {
        val spinner = layout.findViewById<Spinner>(R.id.value_spinner)
        val selected = spinner.selectedItem as? String
        val prompt = LanguageManager.getText(languageID, "choose_answer")

        return if (selected == null || selected == prompt) {
            showToast(LanguageManager.getText(languageID, "select_one_answer"))
            false
        } else {
            true
        }
    }

    override fun saveAnswer() {
        val spinner = layout.findViewById<Spinner>(R.id.value_spinner)
        val selected = spinner.selectedItem as? String ?: return

        question.question?.let { key ->
            answers[key] = selected
        }
    }

}
