package com.dano.test1.questionnaire.handlers

import android.content.Context
import android.util.TypedValue
import android.view.View
import android.widget.*
import androidx.core.widget.TextViewCompat
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 mit mehreren auswählbaren Antwortoptionen (Checkboxen).
*/

class HandlerMultiCheckboxQuestion(
    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 showToast: (String) -> Unit,
    private val questionnaireMeta: String //
) : QuestionHandler {

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

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

        val container = layout.findViewById<LinearLayout>(R.id.CheckboxContainer)
        val questionTitle = layout.findViewById<TextView>(R.id.question)
        val questionTextView = layout.findViewById<TextView>(R.id.textView)

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

        // Textgrößen pro Bildschirmhöhe (wie bei deinen anderen Handlern)
        ViewUtils.setTextSizePercentOfScreenHeight(questionTextView, 0.03f)
        ViewUtils.setTextSizePercentOfScreenHeight(questionTitle,    0.03f)

        container.removeAllViews()

        // bestehende Auswahl aus answers (falls vorhanden) als Set
        val selectedKeys = this.question.question?.let {
            (answers[it] as? List<*>)?.map { it.toString() }?.toSet()
        } ?: emptySet()

        // Checkbox-Schrift & Zeilenhöhe dynamisch ableiten (kein Abschneiden)
        val dm = layout.resources.displayMetrics
        val cbTextSp = (dm.heightPixels * 0.025f) / dm.scaledDensity // ~2.5% der Bildschirmhöhe
        val cbTextPx = cbTextSp * dm.scaledDensity
        val cbPadV   = (cbTextPx * 0.40f).toInt()
        val cbMinH   = (cbTextPx * 1.60f + 2 * cbPadV).toInt()

        this.question.options.forEach { option ->
            val checkBox = CheckBox(context).apply {
                text = LanguageManager.getText(languageID, option.key)
                tag = option.key
                isChecked = selectedKeys.contains(option.key)

                // Textgröße prozentual & Zeilenhöhe/Padding für Lesbarkeit
                TextViewCompat.setAutoSizeTextTypeWithDefaults(this, TextViewCompat.AUTO_SIZE_TEXT_TYPE_NONE)
                setTextSize(TypedValue.COMPLEX_UNIT_SP, cbTextSp)
                includeFontPadding = true
                setPadding(paddingLeft, cbPadV, paddingRight, cbPadV)
                minHeight = cbMinH

                layoutParams = LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.MATCH_PARENT,
                    LinearLayout.LayoutParams.WRAP_CONTENT
                ).apply {
                    val scale = context.resources.displayMetrics.density
                    val marginBottom = (16 * scale + 0.5f).toInt()
                    setMargins(0, 0, 0, marginBottom)
                }
            }
            container.addView(checkBox)
        }

        //DB-Abfrage falls noch kein Eintrag im answers-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()) {
                        val parsed = parseMultiAnswer(dbAnswer)

                        withContext(Dispatchers.Main) {
                            // UI: Checkboxen setzen
                            for (i in 0 until container.childCount) {
                                val cb = container.getChildAt(i) as? CheckBox ?: continue
                                cb.isChecked = parsed.contains(cb.tag.toString())
                            }

                            // answers-Map aktualisieren
                            answers[answerMapKey] = parsed.toList()

                            // Punkte berechnen und hinzufügen
                            val totalPoints = parsed.sumOf { key ->
                                question.pointsMap?.get(key) ?: 0
                            }
                            points.add(totalPoints)
                        }
                    }
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }
        }

        layout.findViewById<Button>(R.id.Qnext).setOnClickListener {
            if (validate()) {
                saveAnswer()
                goToNextQuestion()
            } else {
                val msgKey = if (question.minSelection == 1) {
                    "select_at_least_one_answer"
                } else {
                    "select_at_least_minimum"
                }
                val errorMessage = LanguageManager.getTextFormatted(languageID, msgKey, "choose_more_elements")
                showToast(errorMessage)
            }
        }

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

    override fun validate(): Boolean {
        val container = layout.findViewById<LinearLayout>(R.id.CheckboxContainer)
        var selectedCount = 0
        for (i in 0 until container.childCount) {
            val checkBox = container.getChildAt(i) as? CheckBox ?: continue
            if (checkBox.isChecked) selectedCount++
        }
        return selectedCount >= question.minSelection
    }

    override fun saveAnswer() {
        val container = layout.findViewById<LinearLayout>(R.id.CheckboxContainer)
        val selectedKeys = mutableListOf<String>()
        var totalPoints = 0

        for (i in 0 until container.childCount) {
            val checkBox = container.getChildAt(i) as? CheckBox ?: continue
            if (checkBox.isChecked) {
                val key = checkBox.tag.toString()
                selectedKeys.add(key)
                totalPoints += question.pointsMap?.get(key) ?: 0
            }
        }

        question.question?.let { questionKey ->
            // ggf. alte Punkte entfernen
            val oldList = answers[questionKey] as? List<*>
            if (oldList != null) {
                val oldTotal = oldList.mapNotNull { it?.toString() }.sumOf { oldKey ->
                    question.pointsMap?.get(oldKey) ?: 0
                }
                points.remove(oldTotal)
            }

            answers[questionKey] = selectedKeys
            points.add(totalPoints)
        }
    }

    private fun parseMultiAnswer(dbAnswer: String): Set<String> {
        val trimmed = dbAnswer.trim()
        if (trimmed.startsWith("[") && trimmed.endsWith("]")) {
            val inner = trimmed.substring(1, trimmed.length - 1)
            if (inner.isBlank()) return emptySet()
            return inner.split(",")
                .map { it.trim().trim('"', '\'') }
                .filter { it.isNotEmpty() }
                .toSet()
        }

        val separator = when {
            trimmed.contains(",") -> ","
            trimmed.contains(";") -> ";"
            else -> null
        }

        return if (separator != null) {
            trimmed.split(separator)
                .map { it.trim().trim('"', '\'') }
                .filter { it.isNotEmpty() }
                .toSet()
        } else {
            setOf(trimmed.trim().trim('"', '\''))
        }
    }

}
