package com.dano.test1.ui

import android.content.Intent
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
import com.dano.test1.LanguageManager
import com.dano.test1.MainActivity
import com.dano.test1.MyApp
import kotlinx.coroutines.*
import com.dano.test1.data.CompletedQuestionnaire
import com.dano.test1.questionnaire.GlobalValues
import com.dano.test1.questionnaire.QuestionItem

class LoadButtonHandler(
    private val activity: MainActivity,
    private val loadButton: Button,
    private val editText: EditText,
    private val languageIDProvider: () -> String,
    private val questionnaireEntriesProvider: () -> List<QuestionItem.QuestionnaireEntry>,
    private val dynamicButtonsProvider: () -> List<Button>,
    private val buttonPoints: MutableMap<String, Int>,
    private val updateButtonTexts: () -> Unit,
    private val setButtonsEnabled: (List<Button>) -> Unit,
    private val updateMainButtonsState: (Boolean) -> Unit,
) {

    companion object {
        /** Opening-screen client code that opens dev A/B settings (not a security boundary). */
        private const val DEV_SETTINGS_SECRET = "_dev_settings_"
    }

    fun setup() {
        loadButton.text = LanguageManager.getText(languageIDProvider(), "load")
        loadButton.setOnClickListener { handleLoadButton() }
    }

    private fun handleLoadButton() {
        val inputText = editText.text.toString().trim()
        if (inputText.isBlank()) {
            val message = LanguageManager.getText(languageIDProvider(), "please_client_code")
            Toast.makeText(activity, message, Toast.LENGTH_SHORT).show()
            return
        }

        if (inputText == DEV_SETTINGS_SECRET) {
            editText.text.clear()
            activity.startActivity(Intent(activity, DevSettingsActivity::class.java))
            return
        }

        buttonPoints.clear()
        setButtonsEnabled(emptyList())   // temporär sperren
        updateButtonTexts()              // Chips zeigen vorläufig „Gesperrt“

        val clientCode = inputText
        GlobalValues.LAST_CLIENT_CODE = clientCode

        CoroutineScope(Dispatchers.IO).launch {
            val client = MyApp.database.clientDao().getClientByCode(clientCode)
            if (client == null) {
                GlobalValues.LOADED_CLIENT_CODE = null
                withContext(Dispatchers.Main) {
                    val message = LanguageManager.getText(languageIDProvider(), "no_profile")
                    Toast.makeText(activity, message, Toast.LENGTH_LONG).show()
                    val questionnaireEntries = questionnaireEntriesProvider()
                    val alwaysButtons = questionnaireEntries.mapIndexedNotNull { idx, entry ->
                        val btn = dynamicButtonsProvider().getOrNull(idx)
                        if (entry.condition is QuestionItem.Condition.AlwaysAvailable) btn else null
                    }
                    setButtonsEnabled(alwaysButtons)
                    updateButtonTexts()   // <- nach dem Aktivieren Chips aktualisieren
                }
                return@launch
            }

            GlobalValues.LOADED_CLIENT_CODE = clientCode
            withContext(Dispatchers.Main) { updateMainButtonsState(true) }
            handleNormalLoad(clientCode)
        }
    }


    private suspend fun evaluateCondition(
        condition: QuestionItem.Condition?,
        clientCode: String,
        completedEntries: List<CompletedQuestionnaire>
    ): Boolean {
        if (condition == null) return false
        return when (condition) {
            is QuestionItem.Condition.AlwaysAvailable -> true
            is QuestionItem.Condition.RequiresCompleted -> {
                val normalizedCompleted = completedEntries.map { normalizeQuestionnaireId(it.questionnaireId) }
                condition.required.all { req ->
                    val nReq = normalizeQuestionnaireId(req)
                    normalizedCompleted.any { it.contains(nReq) || nReq.contains(it) }
                }
            }
            is QuestionItem.Condition.QuestionCondition -> {
                val answers = MyApp.database.answerDao().getAnswersForClientAndQuestionnaire(clientCode, condition.questionnaire)
                val relevant = answers.find { it.questionId.endsWith(condition.questionId, ignoreCase = true) }
                val answerValue = relevant?.answerValue ?: ""
                when (condition.operator) {
                    "==" -> answerValue == condition.value
                    "!=" -> answerValue != condition.value
                    else -> false
                }
            }
            is QuestionItem.Condition.Combined -> {
                val normalizedCompleted = completedEntries.map { normalizeQuestionnaireId(it.questionnaireId) }
                val reqOk = condition.requiresCompleted.isNullOrEmpty() || condition.requiresCompleted.all { req ->
                    val nReq = normalizeQuestionnaireId(req)
                    normalizedCompleted.any { it.contains(nReq) || nReq.contains(it) }
                }
                if (!reqOk) return false
                val q = condition.questionCheck ?: return true
                val answers = MyApp.database.answerDao().getAnswersForClientAndQuestionnaire(clientCode, q.questionnaire)
                val relevant = answers.find { it.questionId.endsWith(q.questionId, ignoreCase = true) }
                val answerValue = relevant?.answerValue ?: ""
                when (q.operator) {
                    "==" -> answerValue == q.value
                    "!=" -> answerValue != q.value
                    else -> false
                }
            }
            is QuestionItem.Condition.AnyOf -> {
                condition.conditions.any { evaluateCondition(it, clientCode, completedEntries) }
            }
        }
    }

    private fun normalizeQuestionnaireId(name: String): String =
        name.lowercase().removeSuffix(".json")

    private suspend fun handleNormalLoad(clientCode: String) {
        val completedEntries = withContext(Dispatchers.IO) {
            MyApp.database.completedQuestionnaireDao().getAllForClient(clientCode)
        }

        buttonPoints.clear()
        for (entry in completedEntries) {
            if (entry.isDone) {
                buttonPoints[entry.questionnaireId] = entry.sumPoints ?: 0
                if (entry.questionnaireId.contains("questionnaire_2_rhs", ignoreCase = true)) {
                    RHS_POINTS = entry.sumPoints
                }
            }
        }

        val enabledButtons = mutableListOf<Button>()
        val questionnaireEntries = questionnaireEntriesProvider()
        val dynamicButtons = dynamicButtonsProvider()

        for ((idx, entry) in questionnaireEntries.withIndex()) {
            val button = dynamicButtons.getOrNull(idx) ?: continue

            val isCompleted = completedEntries.any { completed ->
                normalizeQuestionnaireId(completed.questionnaireId).let { completedNorm ->
                    val targetNorm = normalizeQuestionnaireId(entry.file)
                    (completedNorm.contains(targetNorm) || targetNorm.contains(completedNorm)) && completed.isDone
                }
            }

            val condMet = evaluateCondition(entry.condition, clientCode, completedEntries)
            if (condMet || isCompleted) enabledButtons.add(button)
        }

        withContext(Dispatchers.Main) {
            setButtonsEnabled(enabledButtons)   // erst aktivieren …
            updateButtonTexts()                 // … dann Chips/Labels korrekt setzen
        }
    }

}
