package com.dano.test1.questionnaire.handlers

import android.content.Context
import android.view.View
import android.text.Html
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 Einzelfrage mit genau einer auswählbaren Antwort (RadioButtons).
*/

class HandlerRadioQuestion(
    private val context: Context,
    private val answers: MutableMap<String, Any>,
    private val points: MutableList<Int>,
    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.RadioQuestion

    override fun bind(layout: View, question: QuestionItem) {
        this.layout = layout
        this.question = question as QuestionItem.RadioQuestion

        val radioGroup = layout.findViewById<RadioGroup>(R.id.RadioGroup)
        val questionTextView = layout.findViewById<TextView>(R.id.textView)
        val questionTitle = layout.findViewById<TextView>(R.id.question)

        questionTextView.text = question.textKey?.let { LanguageManager.getText(languageID, it) } ?: ""
        questionTitle.text = question.question?.let {
            Html.fromHtml(LanguageManager.getText(languageID, it), Html.FROM_HTML_MODE_LEGACY)
        } ?: ""

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

        radioGroup.removeAllViews()

        question.options.forEach { option ->
            val radioButton = RadioButton(context).apply {
                text = LanguageManager.getText(languageID, option.key)
                tag = option.key

                // RadioButton-Text analog zu EditTexts: 2.5% der Bildschirmhöhe
                ViewUtils.setTextSizePercentOfScreenHeight(this, 0.025f)

                layoutParams = RadioGroup.LayoutParams(
                    RadioGroup.LayoutParams.MATCH_PARENT,
                    RadioGroup.LayoutParams.WRAP_CONTENT
                ).apply {
                    val scale = context.resources.displayMetrics.density
                    val margin = (16 * scale + 0.5f).toInt()
                    setMargins(0, 0, 0, margin)
                }

                val padding = (12 * resources.displayMetrics.density).toInt()
                setPadding(padding, padding, padding, padding)
            }
            radioGroup.addView(radioButton)
        }

        restorePreviousAnswer(radioGroup)

        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) {
                            val oldAnswerKey = answers[answerMapKey] as? String
                            val oldPoint = oldAnswerKey?.let { question.pointsMap?.get(it) } ?: 0
                            if (oldAnswerKey != null) {
                                points.remove(oldPoint)
                            }

                            for (i in 0 until radioGroup.childCount) {
                                val radioButton = radioGroup.getChildAt(i) as RadioButton
                                if (radioButton.tag == dbAnswer) {
                                    radioButton.isChecked = true
                                    break
                                }
                            }

                            answers[answerMapKey] = dbAnswer
                            val newPoint = question.pointsMap?.get(dbAnswer) ?: 0
                            points.add(newPoint)
                        }
                    }
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }
        }

        layout.findViewById<Button>(R.id.Qnext).setOnClickListener {
            if (validate()) {
                saveAnswer()

                val selectedId = radioGroup.checkedRadioButtonId
                val selectedRadioButton = layout.findViewById<RadioButton>(selectedId)
                val selectedKey = selectedRadioButton.tag.toString()

                val nextId = question.options.find { it.key == selectedKey }?.nextQuestionId

                if (!nextId.isNullOrEmpty()) {
                    goToQuestionById(nextId)
                } else {
                    goToNextQuestion()
                }
            } else {
                showToast(LanguageManager.getText(languageID, "select_one_answer"))
            }
        }

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

    private fun restorePreviousAnswer(radioGroup: RadioGroup) {
        question.question?.let { questionKey ->
            val savedAnswer = answers[questionKey] as? String
            savedAnswer?.let { saved ->
                for (i in 0 until radioGroup.childCount) {
                    val radioButton = radioGroup.getChildAt(i) as RadioButton
                    if (radioButton.tag == saved) {
                        radioButton.isChecked = true
                        break
                    }
                }
            }
        }
    }

    override fun validate(): Boolean {
        return layout.findViewById<RadioGroup>(R.id.RadioGroup).checkedRadioButtonId != -1
    }

    override fun saveAnswer() {
        val radioGroup = layout.findViewById<RadioGroup>(R.id.RadioGroup)
        val selectedId = radioGroup.checkedRadioButtonId
        val selectedRadioButton = layout.findViewById<RadioButton>(selectedId)
        val answerKey = selectedRadioButton.tag.toString()

        question.question?.let { questionKey ->
            val oldAnswerKey = answers[questionKey] as? String
            val oldPoint = oldAnswerKey?.let { question.pointsMap?.get(it) } ?: 0
            points.remove(oldPoint)

            answers[questionKey] = answerKey

            val newPoint = question.pointsMap?.get(answerKey) ?: 0
            points.add(newPoint)
        }
    }
}
