package app.revanced.patches.viber.misc.navbar

import app.revanced.patcher.extensions.addInstructionsWithLabels
import app.revanced.patcher.immutableClassDef
import app.revanced.patcher.patch.booleanOption
import app.revanced.patcher.patch.bytecodePatch
import java.util.logging.Logger

@Suppress("unused")
val hideNavigationButtonsPatch = bytecodePatch(
    name = "Hide navigation buttons",
    description = "Permanently hides navigation bar buttons, such as Explore and Marketplace.",
    use = false,
) {
    compatibleWith("com.viber.voip")

    val hideOptions = AllowedNavigationItems.entries.associateWith {
        booleanOption(
            name = it.optionName,
            default = it.defaultHideOption,
            description = it.description,
        )
    }

    apply {
        // Items that won't be forcefully hidden.
        val allowedItems = hideOptions.filter { (option, enabled) -> enabled.value != true }

        if (allowedItems.size == AllowedNavigationItems.entries.size) {
            return@apply Logger.getLogger(this::class.java.name).warning(
                "No hide navigation buttons options are enabled. No changes applied.",
            )
        }

        val injectionInstructions = allowedItems
            .map { it.key.buildAllowInstruction() }
            .joinToString("\n") + """
                # If we reach this, it means that this tab has been disabled by user
                const/4 v0, 0
                return v0  # return false as "This tab is not enabled"
                       
                # Proceed with default execution
                :continue
                nop
            """

        tabIdClassMethod.immutableClassDef.getShouldShowTabIdMethod()
            .addInstructionsWithLabels(0, injectionInstructions)
    }
}

/**
 * Navigation items taken from source code.
 * They appear in code like new NavigationItem(0, R.string.bottom_tab_chats, R.drawable.ic_tab_chats).
 */
private enum class AllowedNavigationItems(
    val defaultHideOption: Boolean,
    private val itemName: String,
    private vararg val ids: Int,
) {
    CHATS(false, "Chats", 0),
    CALLS(false, "Calls", 1, 7),
    EXPLORE(true, "Explore", 2),
    MORE(false, "More", 3),
    PAY(true, "Pay", 5),
    CAMERA(true, "Camera", 6),
    MARKETPLACE(true, "Marketplace", 8),
    ;

    val optionName = "Hide $itemName"
    val description = "Permanently hides the $itemName button."

    fun buildAllowInstruction(): String = ids.joinToString("\n") { id ->
        """
                const/4 v0, $id  # If tabId == $id ($itemName), don't hide it
                if-eq p1, v0, :continue
            """
    }
}
