package com.tomhempel.rbarometer.ui

import android.app.Activity
import android.view.View
import android.view.ViewGroup
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.updatePadding
import com.tomhempel.rbarometer.R
import kotlin.math.max

/**
 * Keeps interactive UI above system bars and preserves layout padding from XML.
 * [ensureMinContentPadding] adds [R.dimen.screen_content_padding] on sides that have
 * no XML padding (used by MainActivity for full-bleed questionnaire layouts).
 */
object SystemBarInsets {

    private val insetTypes =
        WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.displayCutout()

    private data class Padding4(
        val left: Int,
        val top: Int,
        val right: Int,
        val bottom: Int,
    )

    fun applyToContentRoot(
        activity: Activity,
        ensureMinContentPadding: Boolean = false,
    ) {
        val content = activity.findViewById<ViewGroup>(android.R.id.content) ?: return
        content.setPadding(0, 0, 0, 0)

        val root = content.getChildAt(0) ?: return
        captureBasePadding(root)

        val minPad = if (ensureMinContentPadding) {
            activity.resources.getDimensionPixelSize(R.dimen.screen_content_padding)
        } else {
            0
        }

        ViewCompat.setOnApplyWindowInsetsListener(root) { view, windowInsets ->
            val bars = windowInsets.getInsets(insetTypes)
            val base = basePadding(view)
            view.updatePadding(
                left = max(base.left, minPad) + bars.left,
                top = max(base.top, minPad) + bars.top,
                right = max(base.right, minPad) + bars.right,
                bottom = max(base.bottom, minPad) + bars.bottom,
            )
            WindowInsetsCompat.CONSUMED
        }
        ViewCompat.requestApplyInsets(root)
    }

    private fun captureBasePadding(root: View) {
        if (root.getTag(R.id.system_bars_base_padding) != null) return
        root.setTag(
            R.id.system_bars_base_padding,
            Padding4(
                root.paddingLeft,
                root.paddingTop,
                root.paddingRight,
                root.paddingBottom,
            ),
        )
    }

    private fun basePadding(view: View): Padding4 {
        return (view.getTag(R.id.system_bars_base_padding) as? Padding4) ?: Padding4(0, 0, 0, 0)
    }
}
