package com.tomhempel.rbarometer.ui

import android.content.Intent
import android.os.Bundle
import android.view.View
import android.widget.Button
import android.widget.RadioButton
import android.widget.RadioGroup
import android.widget.TextView
import android.widget.Toast
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.SwitchCompat
import androidx.appcompat.widget.Toolbar
import com.tomhempel.rbarometer.MainActivity
import com.tomhempel.rbarometer.R
import com.tomhempel.rbarometer.network.QuestionnaireSyncService
import com.tomhempel.rbarometer.network.TokenStore
import com.tomhempel.rbarometer.utils.SyncProgressOverlay
import com.tomhempel.rbarometer.utils.SyncProgressTexts
import com.google.android.material.button.MaterialButton
import com.tomhempel.rbarometer.ui.AppLanguageStore
import com.tomhempel.rbarometer.ui.LogoutDialogs
import com.tomhempel.rbarometer.ui.SessionLogout
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

/**
 * Dev-only A/B settings. Requires DEVELOPER-SETTINGS in the coach's assigned client list.
 */
class DevSettingsActivity : AppCompatActivity() {

    private lateinit var switchOverride: SwitchCompat
    private lateinit var radioGroup: RadioGroup

    override fun onCreate(savedInstanceState: Bundle?) {
        enableEdgeToEdge()
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_dev_settings)

        SystemBarInsets.applyToContentRoot(this)

        val toolbar = findViewById<Toolbar>(R.id.devSettingsToolbar)
        setSupportActionBar(toolbar)
        supportActionBar?.setDisplayHomeAsUpEnabled(true)

        switchOverride = findViewById(R.id.switchAbOverride)
        radioGroup = findViewById(R.id.radioGroupVariant)

        applyPrefsToUi()

        switchOverride.setOnCheckedChangeListener { _, isChecked ->
            AbTestSettingsStore.setOverrideEnabled(this, isChecked)
            updateRadiosEnabled(isChecked)
        }

        radioGroup.setOnCheckedChangeListener { _, checkedId ->
            val variant = when (checkedId) {
                R.id.radioVariantA -> AbTestSettingsStore.VARIANT_A
                R.id.radioVariantB -> AbTestSettingsStore.VARIANT_B
                else -> AbTestSettingsStore.VARIANT_NONE
            }
            AbTestSettingsStore.setVariant(this, variant)
        }

        val refreshButton = findViewById<Button>(R.id.refreshDataButton)
        val refreshStatus = findViewById<TextView>(R.id.refreshStatusText)
        refreshButton.setOnClickListener {
            val token = TokenStore.getToken(this)
            if (token.isNullOrBlank()) {
                Toast.makeText(this, "No token – please log in first", Toast.LENGTH_LONG).show()
                return@setOnClickListener
            }
            refreshButton.isEnabled = false
            refreshStatus.visibility = View.GONE

            val overlay = SyncProgressOverlay(this, SyncProgressTexts.Locale.GERMAN)
            overlay.show()

            CoroutineScope(Dispatchers.IO).launch {
                val result = runCatching {
                    QuestionnaireSyncService.refreshAll(
                        this@DevSettingsActivity,
                        token,
                        pullAnswers = true,
                        forceAnswerPull = true,
                        onProgress = { progress ->
                            runOnUiThread { overlay.update(progress) }
                        },
                    )
                }
                withContext(Dispatchers.Main) {
                    overlay.hide()
                    refreshButton.isEnabled = true
                    if (result.isSuccess) {
                        refreshStatus.text = "Refresh successful"
                        Toast.makeText(this@DevSettingsActivity, "Data refreshed", Toast.LENGTH_SHORT).show()
                    } else {
                        refreshStatus.text = "Refresh failed: ${result.exceptionOrNull()?.message}"
                        Toast.makeText(this@DevSettingsActivity, "Refresh failed", Toast.LENGTH_LONG).show()
                    }
                }
            }
        }

        findViewById<MaterialButton>(R.id.logoutButton).setOnClickListener { attemptLogout() }
    }

    private fun attemptLogout() {
        val languageId = AppLanguageStore.get(this)
        CoroutineScope(Dispatchers.Main).launch {
            val block = withContext(Dispatchers.IO) { SessionLogout.evaluate(this@DevSettingsActivity) }
            when (block) {
                null -> LogoutDialogs.showConfirm(this@DevSettingsActivity, languageId) {
                    CoroutineScope(Dispatchers.Main).launch {
                        withContext(Dispatchers.IO) { SessionLogout.wipeAllLocalData(this@DevSettingsActivity) }
                        val intent = Intent(this@DevSettingsActivity, MainActivity::class.java).apply {
                            addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
                        }
                        startActivity(intent)
                        finish()
                    }
                }
                SessionLogout.BlockReason.Offline -> LogoutDialogs.showBlocked(
                    activity = this@DevSettingsActivity,
                    languageId = languageId,
                    title = SessionLogout.message(languageId, "logout_offline_title", "Cannot log out"),
                    message = SessionLogout.message(
                        languageId,
                        "logout_offline_message",
                        "You are offline. Connect to the internet, upload pending data, then try again.",
                    ),
                    tone = LogoutDialogs.Tone.Info,
                )
                is SessionLogout.BlockReason.UnuploadedWork -> {
                    val details = SessionLogout.formatPendingDetails(languageId, block.summary)
                    val bodyTemplate = SessionLogout.message(
                        languageId,
                        "logout_pending_message",
                        "You still have data on this device that has not been uploaded.\n\n{details}\n\nPlease tap Upload and wait until it finishes.",
                    )
                    val message = bodyTemplate.replace("{details}", "").trim()
                    LogoutDialogs.showBlocked(
                        activity = this@DevSettingsActivity,
                        languageId = languageId,
                        title = SessionLogout.message(languageId, "logout_pending_title", "Cannot log out"),
                        message = message,
                        details = details,
                        tone = LogoutDialogs.Tone.Warning,
                    )
                }
            }
        }
    }

    private fun applyPrefsToUi() {
        val overrideOn = AbTestSettingsStore.isOverrideEnabled(this)
        switchOverride.isChecked = overrideOn
        updateRadiosEnabled(overrideOn)

        when (AbTestSettingsStore.getVariant(this)) {
            AbTestSettingsStore.VARIANT_A -> radioGroup.check(R.id.radioVariantA)
            AbTestSettingsStore.VARIANT_B -> radioGroup.check(R.id.radioVariantB)
            else -> radioGroup.check(R.id.radioVariantDefault)
        }
    }

    private fun updateRadiosEnabled(enabled: Boolean) {
        for (i in 0 until radioGroup.childCount) {
            (radioGroup.getChildAt(i) as? RadioButton)?.isEnabled = enabled
        }
        radioGroup.alpha = if (enabled) 1f else 0.5f
    }

    override fun onSupportNavigateUp(): Boolean {
        finish()
        return true
    }
}
