package com.dano.test1

import android.content.res.Configuration
import android.net.ConnectivityManager
import android.net.Network
import android.net.NetworkCapabilities
import android.net.NetworkRequest
import android.os.Bundle
import android.view.View
import android.widget.EditText
import android.widget.LinearLayout
import android.widget.ProgressBar
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import com.dano.test1.network.DatabaseDownloader
import com.dano.test1.network.LoginManager
import com.dano.test1.network.TokenStore
import com.dano.test1.questionnaire.QuestionnaireBase
import com.dano.test1.ui.HandlerOpeningScreen

class MainActivity : AppCompatActivity() {

    private lateinit var openingScreenHandler: HandlerOpeningScreen

    var isInQuestionnaire: Boolean = false
    var isFirstQuestionnairePage: Boolean = false

    private var progress: ProgressBar? = null

    // LIVE: Network-Callback (optional für Statusleiste)
    private var netCb: ConnectivityManager.NetworkCallback? = null

    // Wir kennen hier (vor dem OpeningScreen) noch keine Nutzerwahl → Deutsch als Startsprache.
    private val bootLanguageId: String get() = "GERMAN"
    private fun t(key: String): String = LanguageManager.getText(bootLanguageId, key)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // === Offline-Start ermöglichen ===
        // Bedingung: gespeicherter User/Token UND lokale DB vorhanden -> direkt OpeningScreen
        val hasCreds = !TokenStore.getUsername(this).isNullOrBlank() && !TokenStore.getToken(this).isNullOrBlank()
        val hasDb = hasLocalDb()
        if (hasCreds && hasDb) {
            openingScreenHandler = HandlerOpeningScreen(this)
            openingScreenHandler.init()
            return
        }

        // Sonst: Login-Dialog -> Login -> DB (einmalig) laden -> OpeningScreen
        showLoginThenDownload()
    }

    /** Prüft, ob die lokale DB-Datei vorhanden ist. */
    private fun hasLocalDb(): Boolean {
        val dbFile = getDatabasePath("questionnaire_database")
        return dbFile != null && dbFile.exists() && dbFile.length() > 0
    }

    /** Zeigt den Login-Dialog an, führt Login aus und lädt danach einmalig die DB. */
    private fun showLoginThenDownload() {
        val container = LinearLayout(this).apply {
            orientation = LinearLayout.VERTICAL
            setPadding(dp(20), dp(8), dp(20), 0)
        }
        val etUser = EditText(this).apply {
            hint = t("username_hint")
            setSingleLine()
        }
        val etPass = EditText(this).apply {
            hint = t("password_hint")
            setSingleLine()
            inputType = android.text.InputType.TYPE_CLASS_TEXT or
                    android.text.InputType.TYPE_TEXT_VARIATION_PASSWORD
        }
        container.addView(etUser)
        container.addView(etPass)

        val dialog = AlertDialog.Builder(this)
            .setTitle(t("login_required_title"))
            .setView(container)
            .setCancelable(false)
            .setPositiveButton(t("login_btn")) { _, _ ->
                val user = etUser.text.toString().trim()
                val pass = etPass.text.toString()
                if (user.isEmpty() || pass.isEmpty()) {
                    Toast.makeText(this, t("please_username_password"), Toast.LENGTH_SHORT).show()
                    showLoginThenDownload()
                    return@setPositiveButton
                }
                showBusy(true)
                LoginManager.loginUserWithCredentials(
                    context = this,
                    username = user,
                    password = pass,
                    onSuccess = { token ->
                        // Nach erfolgreichem Login: einmalig komplette DB ziehen
                        DatabaseDownloader.downloadAndReplaceDatabase(
                            context = this,
                            token = token
                        ) { ok ->
                            showBusy(false)

                            // Wenn Download fehlgeschlagen ist, aber evtl. schon eine DB lokal liegt,
                            // lassen wir den Nutzer trotzdem weiterarbeiten (Offline).
                            if (!ok && !hasLocalDb()) {
                                Toast.makeText(this, t("download_failed_no_local_db"), Toast.LENGTH_LONG).show()
                                // Zurück zum Login, damit man es erneut probieren kann
                                showLoginThenDownload()
                                return@downloadAndReplaceDatabase
                            }

                            if (!ok) {
                                Toast.makeText(this, t("download_failed_use_offline"), Toast.LENGTH_LONG).show()
                            }

                            // Opening-Screen starten
                            openingScreenHandler = HandlerOpeningScreen(this)
                            openingScreenHandler.init()
                            openingScreenHandler.refreshHeaderStatusLive()
                        }
                    },
                    onError = { msg ->
                        showBusy(false)
                        val txt = t("login_failed_with_reason").replace("{reason}", msg ?: "")
                        Toast.makeText(this, txt, Toast.LENGTH_LONG).show()
                        showLoginThenDownload()
                    }
                )
            }
            .setNegativeButton(t("exit_btn")) { _, _ -> finishAffinity() }
            .create()

        dialog.show()
    }

    private fun showBusy(show: Boolean) {
        if (show) {
            if (progress == null) {
                progress = ProgressBar(this).apply {
                    isIndeterminate = true
                    (window?.decorView as? android.view.ViewGroup)?.addView(this)
                }
            }
            progress?.visibility = View.VISIBLE
        } else {
            progress?.visibility = View.GONE
        }
    }

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

    // --- LIVE NETZSTATUS (optional, für deine Status-Leiste) ---
    override fun onResume() {
        super.onResume()
        registerNetworkCallback()
        if (::openingScreenHandler.isInitialized && !isInQuestionnaire) {
            openingScreenHandler.refreshHeaderStatusLive()
        }
    }

    override fun onPause() {
        super.onPause()
        unregisterNetworkCallback()
    }

    private fun registerNetworkCallback() {
        if (netCb != null) return
        val cm = getSystemService(ConnectivityManager::class.java)
        val req = NetworkRequest.Builder()
            .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
            .build()
        netCb = object : ConnectivityManager.NetworkCallback() {
            override fun onAvailable(network: Network) {
                runOnUiThread {
                    if (::openingScreenHandler.isInitialized && !isInQuestionnaire) {
                        openingScreenHandler.refreshHeaderStatusLive()
                    }
                }
            }
            override fun onLost(network: Network) {
                runOnUiThread {
                    if (::openingScreenHandler.isInitialized && !isInQuestionnaire) {
                        openingScreenHandler.refreshHeaderStatusLive()
                    }
                }
            }
            override fun onCapabilitiesChanged(network: Network, caps: NetworkCapabilities) {
                runOnUiThread {
                    if (::openingScreenHandler.isInitialized && !isInQuestionnaire) {
                        openingScreenHandler.refreshHeaderStatusLive()
                    }
                }
            }
        }
        cm.registerNetworkCallback(req, netCb!!)
    }

    private fun unregisterNetworkCallback() {
        val cb = netCb ?: return
        val cm = getSystemService(ConnectivityManager::class.java)
        cm.unregisterNetworkCallback(cb)
        netCb = null
    }
    // --- /LIVE NETZSTATUS ---

    override fun onConfigurationChanged(newConfig: Configuration) {
        super.onConfigurationChanged(newConfig)
    }

    fun startQuestionnaire(questionnaire: QuestionnaireBase<*>, languageID: String) {
        isInQuestionnaire = true
        isFirstQuestionnairePage = true
        questionnaire.attach(this, languageID)
        questionnaire.startQuestionnaire()
    }

    override fun onBackPressed() {
        if (!::openingScreenHandler.isInitialized || !openingScreenHandler.onBackPressed()) {
            super.onBackPressed()
        }
    }

    fun finishQuestionnaire() {
        isInQuestionnaire = false
        isFirstQuestionnairePage = false
        if (::openingScreenHandler.isInitialized) {
            openingScreenHandler.init()
        }
    }
}
