package com.dano.test1.questionnaire.handlers

import android.content.Context
import android.view.View
import android.widget.*
import kotlinx.coroutines.*
import java.text.SimpleDateFormat
import java.util.*
import com.dano.test1.questionnaire.GlobalValues
import com.dano.test1.LanguageManager
import com.dano.test1.questionnaire.MAX_VALUE_YEAR
import com.dano.test1.ui.Month
import com.dano.test1.ui.Months
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:
Rendert eine Datumsfrage mit drei Spinnern (Tag/Monat/Jahr) innerhalb des Fragebogen-Flows.
*/

class HandlerDateSpinner(
    private val context: Context,
    private val answers: MutableMap<String, Any>,
    private val languageID: String,
    private val goToNextQuestion: () -> Unit,
    private val goToPreviousQuestion: () -> Unit,
    private val showToast: (String) -> Unit,
    private val questionnaireMeta: String // neu für DB-Abfrage
) : QuestionHandler {

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

    private lateinit var spinnerDay: Spinner
    private lateinit var spinnerMonth: Spinner
    private lateinit var spinnerYear: Spinner

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

        this.layout = layout
        this.question = question

        initViews()

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

        val labelDay = layout.findViewById<TextView>(R.id.date_spinner_day)
        val labelMonth = layout.findViewById<TextView>(R.id.date_spinner_month)
        val labelYear = layout.findViewById<TextView>(R.id.date_spinner_year)

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

        // Schriftgrößen pro Bildschirmhöhe
        ViewUtils.setTextSizePercentOfScreenHeight(textView,          0.03f)
        ViewUtils.setTextSizePercentOfScreenHeight(questionTextView,  0.03f)
        ViewUtils.setTextSizePercentOfScreenHeight(labelDay,          0.025f)
        ViewUtils.setTextSizePercentOfScreenHeight(labelMonth,        0.025f)
        ViewUtils.setTextSizePercentOfScreenHeight(labelYear,         0.025f)

        // gespeicherte Antwort (YYYY-MM-DD) lesen
        val (savedYear, savedMonthIndex, savedDay) = question.question?.let {
            parseSavedDate(answers[it] as? String)
        } ?: Triple(null, null, null)

        val days = (1..31).toList()
        val months = Months.getAllMonths(languageID)
        val years = (1900..MAX_VALUE_YEAR + 1).toList().reversed()

        val today = Calendar.getInstance()
        val defaultDay = savedDay ?: today.get(Calendar.DAY_OF_MONTH)
        val defaultMonth = savedMonthIndex?.takeIf { it in months.indices }?.let { months[it] }
            ?: months[today.get(Calendar.MONTH)]
        val defaultYear = savedYear ?: today.get(Calendar.YEAR)

        // Spinner responsiv aufsetzen (Schrift + Zeilenhöhe ohne Abschneiden)
        ViewUtils.setupResponsiveSpinner(context, spinnerDay, days, defaultDay)
        ViewUtils.setupResponsiveSpinner(context, spinnerMonth, months, defaultMonth)
        ViewUtils.setupResponsiveSpinner(context, spinnerYear, years, defaultYear)

        // DB-Abfrage, falls noch nicht im answers-Map
        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()) {
                        withContext(Dispatchers.Main) {
                            answers[answerMapKey] = dbAnswer

                            val (dbYear, dbMonthIndex, dbDay) = parseSavedDate(dbAnswer)

                            dbYear?.let { year ->
                                val index = years.indexOf(year)
                                if (index >= 0) spinnerYear.setSelection(index)
                            }

                            dbMonthIndex?.let { monthIndex ->
                                if (monthIndex in months.indices) {
                                    val monthObj = months[monthIndex]
                                    val idx = months.indexOf(monthObj)
                                    if (idx >= 0) spinnerMonth.setSelection(idx)
                                }
                            }

                            dbDay?.let { day ->
                                val idx = days.indexOf(day)
                                if (idx >= 0) spinnerDay.setSelection(idx)
                            }
                        }
                    }
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }
        }

        layout.findViewById<Button>(R.id.Qnext).setOnClickListener {
            if (validate()) {
                saveAnswer()
                goToNextQuestion()
            }
        }

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

    private fun initViews() {
        spinnerDay = layout.findViewById(R.id.spinner_value_day)
        spinnerMonth = layout.findViewById(R.id.spinner_value_month)
        spinnerYear = layout.findViewById(R.id.spinner_value_year)
    }

    override fun validate(): Boolean {
        val day = spinnerDay.selectedItem.toString().padStart(2, '0')
        val month = spinnerMonth.selectedItem as Month
        val year = spinnerYear.selectedItem.toString()

        val allMonths = Months.getAllMonths(languageID)
        val monthNumber = (allMonths.indexOf(month) + 1).toString().padStart(2, '0')
        val selectedDateString = "$year-$monthNumber-$day"
        val selectedDate = parseDate(selectedDateString)

        question.constraints?.notBefore?.let { key ->
            val referenceDateString = answers[key] as? String
            val referenceDate = referenceDateString?.let { parseDate(it) }
            if (referenceDate != null && selectedDate.before(referenceDate)) {
                val message1 = LanguageManager.getText(languageID, "date_after")
                val message2 = LanguageManager.getText(languageID, "lay")
                showToast(message1 + " " + referenceDateString + " " + message2)
                return false
            }
        }

        question.constraints?.notAfter?.let { key ->
            val referenceDate = when (key) {
                "today" -> Date()
                else -> (answers[key] as? String)?.let { parseDate(it) }
            }
            if (referenceDate != null && selectedDate.after(referenceDate)) {
                val message1 = LanguageManager.getText(languageID, "date_before")
                val message2 = LanguageManager.getText(languageID, "lay")
                showToast(message1 + " " + referenceDate + " " + message2)
                return false
            }
        }

        return true
    }

    override fun saveAnswer() {
        val day = spinnerDay.selectedItem.toString().padStart(2, '0')
        val month = spinnerMonth.selectedItem as Month
        val year = spinnerYear.selectedItem.toString()

        val allMonths = Months.getAllMonths(languageID)
        val monthNumber = (allMonths.indexOf(month) + 1).toString().padStart(2, '0')

        question.question?.let { key ->
            answers[key] = "$year-$monthNumber-$day"
        }
    }

    private fun parseSavedDate(dateString: String?): Triple<Int?, Int?, Int?> {
        if (dateString.isNullOrBlank()) return Triple(null, null, null)
        val parts = dateString.split("-")
        if (parts.size != 3) return Triple(null, null, null)

        val year = parts[0].toIntOrNull()
        val monthIndex = parts[1].toIntOrNull()?.minus(1)
        val day = parts[2].toIntOrNull()

        return Triple(year, monthIndex, day)
    }

    private fun parseDate(dateString: String): Date {
        val sdf = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
        return sdf.parse(dateString)
    }

}
