package app.revanced.patches.music.layout.navigationbar

import app.revanced.patcher.extensions.addInstruction
import app.revanced.patcher.extensions.getInstruction
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patcher.patch.resourcePatch
import app.revanced.patches.all.misc.resources.addResources
import app.revanced.patches.all.misc.resources.addResourcesPatch
import app.revanced.patches.music.misc.extension.sharedExtensionPatch
import app.revanced.patches.music.misc.settings.PreferenceScreen
import app.revanced.patches.music.misc.settings.settingsPatch
import app.revanced.patches.shared.misc.mapping.ResourceType
import app.revanced.patches.shared.misc.mapping.resourceMappingPatch
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction

internal var text1 = -1L
    private set

private const val EXTENSION_CLASS_DESCRIPTOR =
    "Lapp/revanced/extension/music/patches/NavigationBarPatch;"

@Suppress("unused")
val navigationBarPatch = bytecodePatch(
    name = "Navigation bar",
    description = "Adds options to hide navigation bar, labels and buttons.",
) {
    dependsOn(
        resourceMappingPatch,
        sharedExtensionPatch,
        settingsPatch,
        addResourcesPatch,
        resourcePatch {
            apply {
                // Ensure the first ImageView has 'layout_weight' to stay properly sized
                // when the TextView is hidden.
                document("res/layout/image_with_text_tab.xml").use { document ->
                    val imageView = document.getElementsByTagName("ImageView").item(0)
                    imageView?.let {
                        if (it.attributes.getNamedItem("android:layout_weight") == null) {
                            val attr = document.createAttribute("android:layout_weight")
                            attr.value = "0.5"
                            it.attributes.setNamedItem(attr)
                        }
                    }
                }
            }
        },
    )

    compatibleWith(
        "com.google.android.apps.youtube.music"(
            "7.29.52",
            "8.10.52",
            "8.37.56",
            "8.40.54",
        ),
    )

    apply {
        text1 = ResourceType.ID["text1"]

        addResources("music", "layout.navigationbar.navigationBarPatch")

        PreferenceScreen.GENERAL.addPreferences(
            PreferenceScreenPreference(
                key = "revanced_music_navigation_bar_screen",
                sorting = PreferenceScreenPreference.Sorting.UNSORTED,
                preferences = setOf(
                    SwitchPreference("revanced_music_hide_navigation_bar_home_button"),
                    SwitchPreference("revanced_music_hide_navigation_bar_samples_button"),
                    SwitchPreference("revanced_music_hide_navigation_bar_explore_button"),
                    SwitchPreference("revanced_music_hide_navigation_bar_library_button"),
                    SwitchPreference("revanced_music_hide_navigation_bar_upgrade_button"),

                    SwitchPreference("revanced_music_hide_navigation_bar"),
                    SwitchPreference("revanced_music_hide_navigation_bar_labels"),
                ),
            ),
        )

        tabLayoutTextMethodMatch.let {
            it.method.apply {
                // Modify in reverse order to preserve match indices.

                // Hide navigation buttons.
                val pivotTabIndex = it[-1]
                val pivotTabRegister =
                    getInstruction<FiveRegisterInstruction>(pivotTabIndex).registerC

                addInstruction(
                    pivotTabIndex,
                    "invoke-static { v$pivotTabRegister }, " +
                            "${EXTENSION_CLASS_DESCRIPTOR}->hideNavigationButton(Landroid/view/View;)V"
                )


                // Set navigation enum and hide navigation buttons.
                val enumIndex = it[7]
                val enumRegister = getInstruction<OneRegisterInstruction>(enumIndex).registerA

                addInstruction(
                    enumIndex + 1,
                    "invoke-static { v$enumRegister }, " +
                            "${EXTENSION_CLASS_DESCRIPTOR}->setLastAppNavigationEnum(Ljava/lang/Enum;)V"
                )


                // Hide navigation labels.
                val labelIndex = it[3]
                val targetParameter = getInstruction<ReferenceInstruction>(labelIndex).reference
                val targetRegister = getInstruction<OneRegisterInstruction>(labelIndex).registerA

                addInstruction(
                    labelIndex + 1,
                    "invoke-static { v$targetRegister }, " +
                            "${EXTENSION_CLASS_DESCRIPTOR}->hideNavigationLabel(Landroid/widget/TextView;)V"
                )
            }
        }
    }
}
