package com.dano.test1.questionnaire

import android.view.View
import android.widget.*
import com.dano.test1.util.LanguageManager
import com.dano.test1.util.setTextSizePercentOfScreenHeight
import com.dano.test1.MyApp
import com.dano.test1.R
import com.dano.test1.auth.TokenStore
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

/*
Zweck :
- Steuert die Eingabeseite für „Client Code“ und „Coach Code“ innerhalb des Fragebogen-Flows.
*/

class HandlerClientCoachCode(
    private val answers: MutableMap<String, Any>,
    private val languageID: String,
    private val goToNextQuestion: () -> Unit,
    private val goToPreviousQuestion: () -> Unit,
    private val showToast: (String) -> Unit,
) : QuestionHandler {

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

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

        this.layout = layout
        this.question = question

        val clientCodeField = layout.findViewById<EditText>(R.id.client_code)
        val coachCodeField  = layout.findViewById<EditText>(R.id.coach_code)
        val questionTextView = layout.findViewById<TextView>(R.id.question)
        val titleTextView    = layout.findViewById<TextView>(R.id.textView)

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

        titleTextView.setTextSizePercentOfScreenHeight(0.03f)
        questionTextView.setTextSizePercentOfScreenHeight(0.03f)
        clientCodeField.setTextSizePercentOfScreenHeight(0.025f)
        coachCodeField.setTextSizePercentOfScreenHeight(0.025f)

        // Client-Code: nur verwenden, wenn bereits geladen
        val loadedClientCode = GlobalValues.LOADED_CLIENT_CODE
        if (!loadedClientCode.isNullOrBlank()) {
            clientCodeField.setText(loadedClientCode)
            clientCodeField.isEnabled = false
        } else {
            clientCodeField.setText("")
            clientCodeField.isEnabled = true
        }

        // Coach-Code immer aus dem Login (TokenStore) setzen und sperren
        val coachFromLogin = TokenStore.getUsername(layout.context)
        if (!coachFromLogin.isNullOrBlank()) {
            coachCodeField.setText(coachFromLogin)
            lockCoachField(coachCodeField) // optisch & technisch gesperrt
        } else {
            // Falls (theoretisch) kein Login-Username vorhanden ist, verhalten wie bisher
            coachCodeField.setText(answers["coach_code"] as? String ?: "")
            coachCodeField.isEnabled = true
        }

        layout.findViewById<Button>(R.id.Qnext).setOnClickListener {
            onNextClicked(clientCodeField, coachCodeField)
        }
        layout.findViewById<Button>(R.id.Qprev).setOnClickListener {
            onPreviousClicked(clientCodeField, coachCodeField)
        }
    }

    private fun onNextClicked(clientCodeField: EditText, coachCodeField: EditText) {
        val loadedClientCode = GlobalValues.LOADED_CLIENT_CODE

        if (!validate()) {
            val message = LanguageManager.getText(languageID, "fill_both_fields")
            showToast(message)
            return
        }

        val clientCode = clientCodeField.text.toString()
        // Erzwinge Coach-Code aus Login (falls vorhanden)
        val coachCode = TokenStore.getUsername(layout.context) ?: coachCodeField.text.toString()

        // Prüfen, ob die DB-Datei vor dem Zugriff existiert
        val dbPath = layout.context.getDatabasePath("questionnaire_database")
        val dbExistedBefore = dbPath.exists()

        CoroutineScope(Dispatchers.IO).launch {
            val existingClient = MyApp.Companion.database.clientDao().getClientByCode(clientCode)

            withContext(Dispatchers.Main) {
                if (existingClient != null && clientCodeField.isEnabled) {
                    val message = LanguageManager.getText(languageID, "client_code_exists")
                    showToast(message)
                } else {
                    saveAnswers(clientCode, coachCode)
                    goToNextQuestion()

                    if (!dbExistedBefore) {
                        MyApp.Companion.database.close()
                        dbPath.delete()
                        val journalFile = layout.context.getDatabasePath("questionnaire_database-journal")
                        journalFile.delete()
                    }
                }
            }
        }
    }

    private fun onPreviousClicked(clientCodeField: EditText, coachCodeField: EditText) {
        val clientCode = clientCodeField.text.toString()
        val coachCode = TokenStore.getUsername(layout.context) ?: coachCodeField.text.toString()
        saveAnswers(clientCode, coachCode)
        goToPreviousQuestion()
    }

    override fun validate(): Boolean {
        val clientCode = layout.findViewById<EditText>(R.id.client_code).text
        val coachText   = layout.findViewById<EditText>(R.id.coach_code).text
        return clientCode.isNotBlank() && coachText.isNotBlank()
    }

    private fun saveAnswers(clientCode: String, coachCode: String) {
        GlobalValues.LAST_CLIENT_CODE = clientCode
        answers["client_code"] = clientCode
        // Speichere garantierten Coach-Code aus Login bevorzugt
        val loginCoach = TokenStore.getUsername(layout.context)
        answers["coach_code"] = loginCoach ?: coachCode
    }

    override fun saveAnswer() {
        // Not used
    }

    private fun lockCoachField(field: EditText) {
        field.isFocusable = false
        field.isFocusableInTouchMode = false
        field.isCursorVisible = false
        field.keyListener = null
        field.isLongClickable = false
        field.isClickable = false
        field.setBackgroundResource(R.drawable.bg_field_locked)
        field.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_lock_24, 0)
        field.compoundDrawablePadding = dp(8)
        field.alpha = 0.95f
    }

    private fun dp(v: Int): Int =
        (v * layout.resources.displayMetrics.density).toInt()
}
