package com.tomhempel.rbarometer.questionnaire

import android.R
import android.app.Activity
import android.util.Log
import android.view.View
import android.widget.*
import com.tomhempel.rbarometer.LanguageManager
import com.tomhempel.rbarometer.MainActivity
import com.tomhempel.rbarometer.session.QuestionnaireDraftSnapshot
import kotlinx.coroutines.*
import java.io.File
import java.util.Calendar

const val MAX_VALUE_AGE = 122
val MAX_VALUE_YEAR = Calendar.getInstance().get(Calendar.YEAR)

object GlobalValues {
    var INTEGRATION_INDEX: Int = 0
    var LAST_CLIENT_CODE: String? = null
    var LOADED_CLIENT_CODE: String? = null
}

data class QuestionnaireMeta(val id: String)
data class QuestionnaireData(val meta: QuestionnaireMeta, val questions: List<QuestionItem>)

abstract class QuestionnaireBase<T> {
    abstract fun startQuestionnaire()
    abstract fun showCurrentQuestion()

    companion object {
        val LANGUAGE_IDS: List<String> get() = AppLanguages.ids
        val LANGUAGE_LABELS: List<String> get() = AppLanguages.shortLabels
    }

    fun attach(activity: Activity, language: String) {
        this.context = activity
        this.languageID = language
    }

    protected lateinit var questionnaireMeta: QuestionnaireMeta
    protected var currentIndex = 0
    protected lateinit var questions: List<QuestionItem>
    protected val answers = mutableMapOf<String, Any>()
    protected var languageID: String = "GERMAN"
    protected lateinit var context: Activity
    private val navigationHistory = mutableListOf<Int>()

    protected fun showToast(message: String) {
        Toast.makeText(context, message, Toast.LENGTH_SHORT).show()
    }

    protected fun validateEditTexts(vararg fields: EditText): Boolean {
        return fields.all { it.text.toString().trim().isNotEmpty() }
    }

    protected fun updateFileContent(fileName: String, placeholders: Map<String, Any?>) {
        val file = File(context.filesDir, fileName)
        if (file.exists()) {
            var updatedContent = file.readText()
            placeholders.forEach { (key, value) ->
                updatedContent = updatedContent.replace("{$key}", value.toString())
            }
            file.writeText(updatedContent)
        }
    }

    protected fun navigateTo(layoutResId: Int, setup: (View) -> Unit) {
        context.setContentView(layoutResId)
        val questionRoot = QuestionnaireLanguagePicker.ensureToolbarLayout(
            activity = context,
            languageId = languageID,
            onLanguageChanged = { newLang ->
                languageID = newLang
                com.tomhempel.rbarometer.ui.AppLanguageStore.set(context, newLang)
                onLanguageChanged(newLang)
            },
        )
        com.tomhempel.rbarometer.ui.SessionUi.applyQuestionScreen(context, questionRoot)
        setup(questionRoot)
    }

    protected open fun onLanguageChanged(newLanguageId: String) {
        showCurrentQuestion()
    }

    protected fun setupPrevButton(buttonId: Int, action: () -> Unit) {
        context.findViewById<Button>(buttonId)?.setOnClickListener { action() }
    }

    protected fun showEmptyScreen() {
        navigateTo(getLayoutResId("empty")) {
            setupPrevButton(com.tomhempel.rbarometer.R.id.Qprev) { goToPreviousQuestion() }
        }
    }

    protected fun getLayoutResId(layoutName: String?): Int {
        return layoutName?.let {
            context.resources.getIdentifier(it, "layout", context.packageName)
        } ?: 0
    }

    protected fun goToPreviousQuestion() {
        if (navigationHistory.isNotEmpty()) {
            currentIndex = navigationHistory.removeAt(navigationHistory.size - 1)
            showCurrentQuestion()
        } else {
            (context as? MainActivity)?.finishQuestionnaire()
        }
    }

    protected fun goToNextQuestion() {
        if (currentIndex < questions.size - 1) {
            navigationHistory.add(currentIndex)
            currentIndex++
            showCurrentQuestion()
        }
    }

    fun goToQuestionById(questionId: String) {
        val index = questions.indexOfFirst { it.id == questionId }
        if (index != -1) {
            navigationHistory.add(currentIndex)
            currentIndex = index
            showCurrentQuestion()
        }
    }

    protected fun loadQuestionnaireFromJson(filename: String): Pair<QuestionnaireMeta, List<QuestionItem>> =
        QuestionnaireJsonLoader.load(context, filename)

    protected fun handlerDependencies(): HandlerDependencies = HandlerDependencies(
        context = context,
        answers = answers,
        languageID = languageID,
        questionnaireMetaId = questionnaireMeta.id,
        goToNext = ::goToNextQuestion,
        goToPrev = ::goToPreviousQuestion,
        goToById = ::goToQuestionById,
        showToast = ::showToast,
        saveAnswers = { map ->
            saveAnswersToDatabase(map, questionnaireMeta.id)
        },
    )

    protected open fun createHandlerForQuestion(question: QuestionItem): QuestionHandler? =
        QuestionHandlerFactory.create(question, NavigationMode.Step, handlerDependencies())

    suspend fun saveAnswersToDatabase(answers: Map<String, Any>, questionnaireId: String) {
        QuestionnairePersistence.saveAnswers(context, answers, questionnaireId, languageID, questions)
    }

    fun draftSnapshot(): QuestionnaireDraftSnapshot? {
        if (!::questionnaireMeta.isInitialized) return null
        return QuestionnaireDraftSnapshot(
            questionnaireId = questionnaireMeta.id,
            answers = answers.toMap(),
            questions = if (::questions.isInitialized) questions else emptyList(),
            languageId = languageID,
        )
    }

    fun endQuestionnaire() {
        (context as? MainActivity)?.finishQuestionnaire(wasCompleted = false)
    }
}
