package com.tomhempel.rbarometer.questionnaire.handlers

import android.content.Context
import android.text.InputFilter
import android.view.View
import android.widget.Button
import android.widget.EditText
import android.widget.TextView
import com.tomhempel.rbarometer.LanguageManager
import com.tomhempel.rbarometer.data.AnswerRepository
import com.tomhempel.rbarometer.R
import com.tomhempel.rbarometer.questionnaire.GlobalValues
import com.tomhempel.rbarometer.questionnaire.QuestionFlowResolver
import com.tomhempel.rbarometer.questionnaire.QuestionHandler
import com.tomhempel.rbarometer.questionnaire.QuestionItem
import com.tomhempel.rbarometer.questionnaire.QuestionNotesHelper
import com.tomhempel.rbarometer.utils.TextInputSanitizer
import com.tomhempel.rbarometer.utils.ViewUtils
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

class HandlerFreeText(
    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.FreeTextQuestion
    private lateinit var inputField: EditText

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

        this.layout = layout
        this.question = question
        inputField = layout.findViewById(R.id.free_text_input)
        ViewUtils.styleFormEditText(inputField)

        val questionTextView = layout.findViewById<TextView>(R.id.question)
        val titleTextView = layout.findViewById<TextView>(R.id.textView)

        QuestionNotesHelper.bind(layout, languageID, question.noteBeforeKey, question.noteAfterKey)

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

        ViewUtils.setTextSizePercentOfScreenHeight(titleTextView, 0.03f)
        ViewUtils.setTextSizePercentOfScreenHeight(questionTextView, 0.03f)
        ViewUtils.setTextSizePercentOfScreenHeight(inputField, 0.025f)

        val maxLen = question.maxLength.coerceIn(1, 10_000)
        inputField.filters = arrayOf(InputFilter.LengthFilter(maxLen))
        inputField.inputType =
            android.text.InputType.TYPE_CLASS_TEXT or
                android.text.InputType.TYPE_TEXT_FLAG_CAP_SENTENCES
        inputField.maxLines = 1

        question.hint?.let { hintKey ->
            inputField.hint = LanguageManager.getText(languageID, hintKey)
        }

        val answerKey = question.question ?: question.id
        inputField.setText(answers[answerKey] as? String ?: "")

        if (answerKey.isNotBlank() && !answers.containsKey(answerKey)) {
            CoroutineScope(Dispatchers.IO).launch {
                try {
                    val clientCode = GlobalValues.LAST_CLIENT_CODE ?: return@launch
                    val dbQuestionId = "$questionnaireMeta-$answerKey"
                    val dbAnswer = AnswerRepository.getAnswersForClient(clientCode)
                        .find { it.questionId == dbQuestionId }
                        ?.answerValue
                    if (!dbAnswer.isNullOrBlank()) {
                        withContext(Dispatchers.Main) {
                            answers[answerKey] = dbAnswer
                            inputField.setText(dbAnswer)
                        }
                    }
                } catch (_: Exception) {
                }
            }
        }

        layout.findViewById<Button>(R.id.Qnext).setOnClickListener {
            if (validate()) {
                saveAnswer()
                QuestionFlowResolver.navigateAfterAnswer(
                    question.nextQuestionId,
                    goToQuestionById,
                    goToNextQuestion,
                )
            }
        }
        layout.findViewById<Button>(R.id.Qprev).setOnClickListener {
            saveAnswer()
            goToPreviousQuestion()
        }
    }

    override fun validate(): Boolean {
        val raw = inputField.text?.toString().orEmpty()
        val maxLen = question.maxLength.coerceIn(1, 10_000)
        if (!TextInputSanitizer.isUsableAfterSanitize(raw, maxLen)) {
            val key = if (raw.isBlank()) "enter_text_to_continue" else "error_invalid_data"
            showToast(LanguageManager.getText(languageID, key))
            return false
        }
        return true
    }

    override fun saveAnswer() {
        val answerKey = question.question ?: question.id
        if (answerKey.isBlank()) return
        val maxLen = question.maxLength.coerceIn(1, 10_000)
        val clean = TextInputSanitizer.sanitize(inputField.text?.toString().orEmpty(), maxLen)
        if (clean.isNotBlank()) {
            answers[answerKey] = clean
            if (inputField.text?.toString() != clean) {
                inputField.setText(clean)
            }
        }
    }
}
