MainActivity

    
package com.example.ventas2

import android.os.Bundle
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import android.graphics.Color
import android.graphics.Typeface
import android.view.GestureDetector
import android.view.Gravity
import android.view.MotionEvent
import android.view.View
import android.widget.ArrayAdapter
import android.widget.EditText
import android.widget.FrameLayout
import android.widget.LinearLayout
import android.widget.ListView
import android.widget.TextView
import android.widget.Toast
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AlertDialog
import kotlin.math.abs

class MainActivity : AppCompatActivity() {


    data class NodoMenu(
        var nombre: String,
        val hijos: MutableList = mutableListOf(),
        var unidad: String? = null,
        var abreviatura: String? = null
    )

    private val ruta = mutableListOf()
    private val pila = mutableListOf>()

    private lateinit var menuPrincipal: MutableList
    private lateinit var nivelActual: MutableList

    private fun obtenerNodoVentas(): NodoMenu? {
        return menuPrincipal.find { it.nombre == "Ventas" }
    }

    private fun agregarCategoria(nombre: String) {
        val ventas = obtenerNodoVentas() ?: return

        val nuevaCategoria = NodoMenu(nombre)

        ventas.hijos.add(nuevaCategoria)

        preguntarSubnivel(nuevaCategoria)
        //actualizarLista()
    }

    private fun agregarSubcategoria(
        categoria: NodoMenu,
        nombre: String,
        abreviatura: String
    ) {
        val nuevaSub = NodoMenu(
            nombre = nombre,
            abreviatura = abreviatura
        )

        categoria.hijos.add(nuevaSub)

        //actualizarLista()
    }


    //private val ruta = mutableListOf()
    //private val ruta = mutableListOf()

    private lateinit var gestureDetectorMain: GestureDetector

    private lateinit var fragmentContainer: View

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

        supportFragmentManager.beginTransaction()
            .replace(R.id.fragment_container, FragmentTicketVenta())
            .commit()

        val sidePanel = findViewById(R.id.sidePanel)
        //val rootLayout = findViewById(R.id.main)
        //val rootLayout = findViewById(R.id.rootLayout)
        //val rootLayout = findViewById(R.id.fragment_container)

        fragmentContainer = findViewById(R.id.fragment_container)

        sidePanel.post {
            sidePanel.translationX = -sidePanel.width.toFloat()
        }

        val contentFrame = findViewById(R.id.contentFrame)
        val tvRuta = findViewById(R.id.tvRuta)

        val listView = ListView(this)
        contentFrame.addView(listView)

        /////////////////////////////////////////////////////////
/*
        data class NodoMenu(
            val nombre: String,
            val hijos: List = emptyList(),
            //val hijos: MutableList = mutableListOf(),
            val unidad: String? = null,
            val abreviatura: String? = null   // 👈 nuevo
        )
*/
        //val ruta = mutableListOf()

        menuPrincipal = mutableListOf(

            NodoMenu("Inicio"),

            NodoMenu(
                "Ventas",
                mutableListOf(
                    NodoMenu(
                        "Cierres",
                        mutableListOf(
                            NodoMenu(
                                "Común",

                                mutableListOf(
                                    NodoMenu("Rojo", unidad = "u", abreviatura = "ro"),
                                    NodoMenu("Azul", unidad = "u", abreviatura = "az")
                                ),abreviatura = "c"
                            ),
                            NodoMenu("Diente de Perro", unidad = "u", abreviatura = "dp"),
                            NodoMenu("Metal", unidad = "u", abreviatura = "mt")
                        )
                    ),
                    NodoMenu(
                        "Botones",
                        mutableListOf(
                            NodoMenu("Redondos", unidad = "u", abreviatura = "re"),
                            NodoMenu("Cuadrados", unidad = "u", abreviatura = "cu")
                        )
                    ),
                    NodoMenu(
                        "Cintas",
                        mutableListOf(
                            NodoMenu("Negra", unidad = "m", abreviatura = "ne"),
                            NodoMenu("Roja", unidad = "m", abreviatura = "ro")
                        )
                    )
                )
            ),

            NodoMenu(
                "Configuracion",
                mutableListOf(
                    NodoMenu("Agregar"),
                    NodoMenu("Editar"),
                    NodoMenu("Eliminar")
                )
            ),

            NodoMenu("Salir")
        )
        val prueba = NodoMenu("Prueba", abreviatura = "pr")
        menuPrincipal.add(prueba)

        nivelActual = menuPrincipal
        //val pila = mutableListOf>()

        fun actualizarLista() {
            val nombres = nivelActual.map { it.nombre }
            listView.adapter = ArrayAdapter(
                this,
                android.R.layout.simple_list_item_1,
                nombres
            )
        }

        actualizarLista()


        fun abrirMenu() {
            sidePanel.animate()
                .translationX(0f)
                .setDuration(200)
                .start()
        }

        fun cerrarMenu() {
            sidePanel.animate()
                .translationX(-sidePanel.width.toFloat())
                .setDuration(200)
                .start()
        }

        var startX = 0f
/*
        rootLayout.setOnTouchListener { _, event ->
            when (event.action) {

                MotionEvent.ACTION_DOWN -> {
                    startX = event.rawX
                    true
                }

                MotionEvent.ACTION_UP -> {
                    val delta = event.rawX - startX

                    if (delta > 120) {
                        abrirMenu()
                    } else if (delta < -120) {
                        cerrarMenu()
                    }
                    true
                }

                else -> false
            }
        }
 */

        /*       fun actualizarRuta() {
                   tvRuta.text = if (ruta.isEmpty()) {
                       "Ventas"
                   } else {
                       "Ventas > " + ruta.joinToString(" > ")
                   }
               }
       */
        fun actualizarRuta() {
            //tvRuta.text = ruta.joinToString(" > ")
            tvRuta.text = ruta.joinToString(" > ") { it.nombre }
        }

        fun animarLista(direccion: Int) {
            val fromX = if (direccion > 0) 1f else -1f

            listView.translationX = fromX * listView.width

            val width = if (listView.width == 0) 300 else listView.width
            listView.translationX = fromX * width

            listView.animate()
                .translationX(0f)
                .setDuration(180)
                .start()
        }

        fun volverNivel() {
            if (pila.isNotEmpty()) {
                nivelActual = pila[pila.size - 1]
                pila.removeAt(pila.size - 1)


                if (ruta.isNotEmpty()) {
                    ruta.removeAt(ruta.size - 1) // o ruta.removeAt(ruta.lastIndex)
                }
                actualizarRuta()

                actualizarLista()
                animarLista(-1)
            }
        }

        val gestureDetector = GestureDetector(this,
            object : GestureDetector.SimpleOnGestureListener() {

                private val SWIPE_THRESHOLD = 100
                private val SWIPE_VELOCITY_THRESHOLD = 100


                override fun onFling(
                    e1: MotionEvent?,
                    e2: MotionEvent,
                    velocityX: Float,
                    velocityY: Float
                ): Boolean {
                    val diffX = e2.x - (e1?.x ?: 0f)
                    val diffY = e2.y - (e1?.y ?: 0f)

                    if (abs(diffX) > abs(diffY) &&
                        abs(diffX) > SWIPE_THRESHOLD &&
                        abs(velocityX) > SWIPE_VELOCITY_THRESHOLD
                    )
                    // if (kotlin.math.abs(diffX) > SWIPE_THRESHOLD &&
                    //     kotlin.math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD
                    // )
                    {
                        if (diffX > 0) {
                            volverNivel()
                        }

                        return true
                    }
                    return false
                }
            })
        listView.setOnTouchListener { _, event ->
            gestureDetector.onTouchEvent(event)
            false
        }

        // SELECTOR DE ITEM
        listView.setOnItemClickListener { _, _, position, _ ->

            val seleccionado = nivelActual[position]

            // 🔥 PRIMERO detectamos casos especiales

            if (seleccionado.nombre == "Inicio") {
                // futura lógica
                return@setOnItemClickListener
            }

            if (seleccionado.nombre == "Salir") {
                // futura lógica
                return@setOnItemClickListener
            }

            if (seleccionado.nombre == "Agregar") {
                mostrarDialogAgregarCategoria()
                actualizarLista()
                return@setOnItemClickListener
            }

            if (seleccionado.nombre == "Editar") {
                // futura lógica
                return@setOnItemClickListener
            }

            if (seleccionado.nombre == "Eliminar") {
                // futura lógica
                return@setOnItemClickListener
            }

            if (seleccionado.hijos.isNotEmpty()) {
                pila.add(nivelActual)
                nivelActual = seleccionado.hijos

                //ruta.add(seleccionado.nombre)
                ruta.add(seleccionado)
                actualizarRuta()

                actualizarLista()
                animarLista(1)
            } else {
                cerrarMenu()
/*
                Toast.makeText(
                    this,
                    "Producto: ${seleccionado.nombre}",
                    Toast.LENGTH_SHORT
                ).show()
*/
                // Acá después conectamos con tu diálogo real


                val fragment = supportFragmentManager
                .findFragmentById(R.id.fragment_container)

                if (fragment is FragmentTicketVenta) {

                    val producto = seleccionado.nombre
                    val unidad = seleccionado.unidad ?: "u"

                    fragment.procesarSeleccionProducto(producto, unidad)
                }

            }
        }

        // GESTURE DE APERTURA Y CIERRA
        gestureDetectorMain = GestureDetector(this,
            object : GestureDetector.SimpleOnGestureListener() {

                private val SWIPE_THRESHOLD = 80  // 70
                private val SWIPE_VELOCITY_THRESHOLD = 50  // 40

                // Usar onScroll() o usar onFling().
                override fun onFling(
                    e1: MotionEvent?,
                    e2: MotionEvent,
                    velocityX: Float,
                    velocityY: Float
                ): Boolean {

                    val diffX = e2.x - (e1?.x ?: 0f)
                    val diffY = e2.y - (e1?.y ?: 0f)

                    if (kotlin.math.abs(diffX) > kotlin.math.abs(diffY) &&
                        kotlin.math.abs(diffX) > SWIPE_THRESHOLD &&
                        kotlin.math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD
                    ) {

                        if (diffX > 0) {
                            abrirMenu()
                        } else {
                            cerrarMenu()
                        }

                        return true
                    }

                    return false
                }
            })
        fragmentContainer.setOnTouchListener { _: View, event: MotionEvent ->
            gestureDetectorMain.onTouchEvent(event)
            true
        }

    }
    private fun mostrarDialogAgregarCategoria() {
        val input = EditText(this)

        AlertDialog.Builder(this)
            .setTitle("Nueva Categoría")
            .setView(input)
            .setPositiveButton("Guardar") { _, _ ->
                val nombre = input.text.toString()
                if (nombre.isNotBlank()) {
                    agregarCategoria(nombre)
                    //actualizarLista()
                }
            }
            .setNegativeButton("Cancelar", null)
            .show()
    }
    private fun preguntarSubnivel(padre: NodoMenu) {

        val layout = LinearLayout(this)
        layout.orientation = LinearLayout.VERTICAL

        val inputNombre = EditText(this)
        inputNombre.hint = "Nombre Subcategoría"

        val inputAbreviatura = EditText(this)
        inputAbreviatura.hint = "Abreviatura"

        layout.addView(inputNombre)
        layout.addView(inputAbreviatura)

        AlertDialog.Builder(this)
            .setTitle("Agregar Subnivel a ${padre.nombre}")
            .setView(layout)
            .setPositiveButton("Agregar") { _, _ ->

                val nombre = inputNombre.text.toString()
                val abrev = inputAbreviatura.text.toString()

                if (nombre.isNotBlank() && abrev.isNotBlank()) {

                    val nuevo = NodoMenu(
                        nombre = nombre,
                        abreviatura = abrev
                    )

                    padre.hijos.add(nuevo)

                    // 🔥 Preguntamos si quiere otro subnivel dentro del nuevo
                    preguntarSubnivel(nuevo)

                } else {
                    // si no completa, simplemente termina
                    volverAVentas()
                    //actualizarRuta()
                    //actualizarLista()
                }
            }
            .setNegativeButton("Terminar") { _, _ ->
                volverAVentas()
            }
            .show()
    }
    private fun volverAVentas() {

        val ventas = obtenerNodoVentas() ?: return

        nivelActual = ventas.hijos
        ruta.clear()
        ruta.add(ventas)

        //actualizarRuta()
        //actualizarLista()
    }
}