package com.tomhempel.rbarometer.ui

import android.app.Dialog
import android.content.res.ColorStateList
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.ViewTreeObserver
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.widget.NestedScrollView
import com.tomhempel.rbarometer.R
import com.google.android.material.button.MaterialButton

/**
 * Branded dialogs for logout: blocked (info/warning) and confirmation before sign-out.
 */
object LogoutDialogs {

    enum class Tone { Info, Warning, Logout }

    fun showBlocked(
        activity: AppCompatActivity,
        languageId: String,
        title: String,
        message: String,
        details: String? = null,
        tone: Tone = Tone.Warning,
    ) {
        show(
            activity = activity,
            tone = tone,
            title = title,
            message = message,
            details = details,
            primaryLabel = msg(languageId, "ok", "OK"),
            secondaryLabel = null,
            tertiaryLabel = null,
            onPrimary = null,
            onSecondary = null,
        )
    }

    fun showConfirm(
        activity: AppCompatActivity,
        languageId: String,
        onConfirm: () -> Unit,
    ) {
        show(
            activity = activity,
            tone = Tone.Logout,
            title = msg(languageId, "logout_confirm_title", "Log out?"),
            message = msg(
                languageId,
                "logout_confirm_message",
                "All data on this device will be removed. You will need to sign in again.",
            ),
            details = null,
            primaryLabel = msg(languageId, "logout_confirm_action", msg(languageId, "logout", "Log out")),
            secondaryLabel = msg(languageId, "cancel", "Cancel"),
            tertiaryLabel = null,
            onPrimary = onConfirm,
            onSecondary = null,
        )
    }

    fun showAction(
        activity: AppCompatActivity,
        languageId: String,
        title: String,
        message: String,
        details: String? = null,
        tone: Tone = Tone.Info,
        primaryLabel: String,
        secondaryLabel: String,
        onPrimary: () -> Unit,
    ) {
        show(
            activity = activity,
            tone = tone,
            title = title,
            message = message,
            details = details,
            primaryLabel = primaryLabel,
            secondaryLabel = secondaryLabel,
            tertiaryLabel = null,
            onPrimary = onPrimary,
            onSecondary = null,
        )
    }

    fun showThreeAction(
        activity: AppCompatActivity,
        title: String,
        message: String,
        tone: Tone = Tone.Info,
        primaryLabel: String,
        secondaryLabel: String,
        tertiaryLabel: String,
        showPrimary: Boolean = true,
        onPrimary: () -> Unit,
        onSecondary: () -> Unit,
    ) {
        if (showPrimary) {
            show(
                activity = activity,
                tone = tone,
                title = title,
                message = message,
                details = null,
                primaryLabel = primaryLabel,
                secondaryLabel = secondaryLabel,
                tertiaryLabel = tertiaryLabel,
                onPrimary = onPrimary,
                onSecondary = onSecondary,
            )
        } else {
            show(
                activity = activity,
                tone = tone,
                title = title,
                message = message,
                details = null,
                primaryLabel = secondaryLabel,
                secondaryLabel = tertiaryLabel,
                tertiaryLabel = null,
                onPrimary = onSecondary,
                onSecondary = null,
            )
        }
    }

    private fun show(
        activity: AppCompatActivity,
        tone: Tone,
        title: String,
        message: String,
        details: String?,
        primaryLabel: String,
        secondaryLabel: String?,
        tertiaryLabel: String?,
        onPrimary: (() -> Unit)?,
        onSecondary: (() -> Unit)?,
    ) {
        val dialog = Dialog(activity)
        dialog.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))

        val root = LayoutInflater.from(activity).inflate(R.layout.dialog_app_message, null)
        val scroll = root.findViewById<NestedScrollView>(R.id.dialogScroll)
        val iconContainer = root.findViewById<View>(R.id.dialogIconContainer)
        val icon = root.findViewById<ImageView>(R.id.dialogIcon)
        val titleView = root.findViewById<TextView>(R.id.dialogTitle)
        val messageView = root.findViewById<TextView>(R.id.dialogMessage)
        val detailsScroll = root.findViewById<NestedScrollView>(R.id.dialogDetailsScroll)
        val detailsView = root.findViewById<TextView>(R.id.dialogDetails)
        val btnPrimary = root.findViewById<MaterialButton>(R.id.dialogBtnPrimary)
        val btnPrimaryInline = root.findViewById<MaterialButton>(R.id.dialogBtnPrimaryInline)
        val btnSecondary = root.findViewById<MaterialButton>(R.id.dialogBtnSecondary)
        val btnTertiary = root.findViewById<MaterialButton>(R.id.dialogBtnTertiary)
        val buttonRow = root.findViewById<ViewGroup>(R.id.dialogButtonRow)

        when (tone) {
            Tone.Info -> {
                iconContainer.setBackgroundResource(R.drawable.bg_dialog_icon_info)
                icon.setImageResource(R.drawable.ic_dialog_info_24)
                icon.imageTintList = null
            }
            Tone.Warning -> {
                iconContainer.setBackgroundResource(R.drawable.bg_dialog_icon_warning)
                icon.setImageResource(R.drawable.ic_dialog_warning_24)
                icon.imageTintList = null
            }
            Tone.Logout -> {
                iconContainer.setBackgroundResource(R.drawable.bg_dialog_icon_logout)
                icon.setImageResource(R.drawable.ic_lock_24)
                icon.imageTintList = ColorStateList.valueOf(
                    ContextCompat.getColor(activity, R.color.brand_destructive_text),
                )
            }
        }

        titleView.text = title
        messageView.text = message

        if (!details.isNullOrBlank()) {
            detailsScroll.visibility = View.VISIBLE
            detailsView.text = details.trim()
            val maxDetailsHeight = activity.resources.getDimensionPixelSize(R.dimen.dialog_details_max_height)
            detailsScroll.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
                override fun onGlobalLayout() {
                    detailsScroll.viewTreeObserver.removeOnGlobalLayoutListener(this)
                    if (detailsScroll.height > maxDetailsHeight) {
                        detailsScroll.layoutParams = detailsScroll.layoutParams.apply {
                            height = maxDetailsHeight
                        }
                    }
                }
            })
        } else {
            detailsScroll.visibility = View.GONE
        }

        val layoutMode = when {
            tertiaryLabel != null && secondaryLabel != null -> DialogButtonLayout.TRIPLE
            secondaryLabel != null -> DialogButtonLayout.PAIR
            else -> DialogButtonLayout.SINGLE
        }

        fun stylePrimaryButton(button: MaterialButton) {
            if (tone == Tone.Logout) {
                button.backgroundTintList = ColorStateList.valueOf(
                    ContextCompat.getColor(activity, R.color.brand_destructive_text),
                )
                button.setTextColor(ContextCompat.getColor(activity, R.color.white))
            } else {
                button.backgroundTintList = ColorStateList.valueOf(
                    ContextCompat.getColor(activity, R.color.brand_purple),
                )
                button.setTextColor(ContextCompat.getColor(activity, R.color.white))
            }
        }

        fun bindPrimaryButton(button: MaterialButton) {
            button.text = primaryLabel
            stylePrimaryButton(button)
            button.setOnClickListener {
                dialog.dismiss()
                onPrimary?.invoke()
            }
        }

        when (layoutMode) {
            DialogButtonLayout.SINGLE -> {
                btnPrimary.visibility = View.VISIBLE
                buttonRow.visibility = View.GONE
                bindPrimaryButton(btnPrimary)
            }
            DialogButtonLayout.PAIR -> {
                btnPrimary.visibility = View.GONE
                buttonRow.visibility = View.VISIBLE
                btnSecondary.visibility = View.VISIBLE
                btnTertiary.visibility = View.GONE
                btnPrimaryInline.visibility = View.VISIBLE

                btnSecondary.text = secondaryLabel
                btnSecondary.setOnClickListener {
                    dialog.dismiss()
                    onSecondary?.invoke()
                }
                bindPrimaryButton(btnPrimaryInline)
            }
            DialogButtonLayout.TRIPLE -> {
                btnPrimary.visibility = View.VISIBLE
                buttonRow.visibility = View.VISIBLE
                btnSecondary.visibility = View.VISIBLE
                btnTertiary.visibility = View.VISIBLE
                btnPrimaryInline.visibility = View.GONE

                bindPrimaryButton(btnPrimary)
                btnSecondary.text = secondaryLabel
                btnSecondary.setOnClickListener {
                    dialog.dismiss()
                    onSecondary?.invoke()
                }
                btnTertiary.text = tertiaryLabel
                btnTertiary.setOnClickListener { dialog.dismiss() }
            }
        }

        dialog.setContentView(root)
        dialog.setCancelable(true)
        dialog.show()

        dialog.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)

        val dm = activity.resources.displayMetrics
        val maxDialogHeight = (dm.heightPixels * 0.85f).toInt()
        scroll.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
            override fun onGlobalLayout() {
                scroll.viewTreeObserver.removeOnGlobalLayoutListener(this)
                if (scroll.height > maxDialogHeight) {
                    scroll.layoutParams = scroll.layoutParams.apply {
                        height = maxDialogHeight
                    }
                }
            }
        })
    }

    private enum class DialogButtonLayout {
        SINGLE,
        PAIR,
        TRIPLE,
    }

    private fun msg(languageId: String, key: String, fallback: String): String =
        SessionLogout.message(languageId, key, fallback)
}
