package com.example.gesturerecognition

import android.hardware.Sensor
import android.hardware.SensorEvent
import android.hardware.SensorEventListener
import android.hardware.SensorManager
import android.os.Bundle
import android.widget.Button
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity(), SensorEventListener {
    private lateinit var sensorManager: SensorManager
    private var accelerometer: Sensor? = null
    private var gestureClassifier: GestureClassifier? = null
    private var soundManager: SoundManager? = null // Novo: gerenciador de sons

    private lateinit var statusText: TextView
    private lateinit var resultText: TextView
    private lateinit var recordButton: Button

    private var isRecording = false
    private var accelerometerData: MutableList<Float> = mutableListOf()
    private var recordingStartTime: Long = 0
    private val windowSize = 315
    private val recordingDurationMs = 2000

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

        initializeViews()
        initializeSensors()
        initializeClassifier()
        initializeSoundManager() // Novo: inicializa sistema de sons
        setupButtons()
    }

    private fun initializeViews() {
        statusText = findViewById(R.id.statusText)
        resultText = findViewById(R.id.resultText)
        recordButton = findViewById(R.id.recordButton)

        statusText.text = "Pressione e segure o botão para gravar"
    }

    private fun initializeSensors() {
        sensorManager = getSystemService(SENSOR_SERVICE) as SensorManager
        accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)

        if (accelerometer == null) {
            Toast.makeText(this, "Acelerômetro não disponível", Toast.LENGTH_LONG).show()
            finish()
        }
    }

    private fun initializeClassifier() {
        try {
            gestureClassifier = GestureClassifier(this)
            Toast.makeText(this, "Modelo carregado com sucesso", Toast.LENGTH_SHORT).show()
        } catch (e: Exception) {
            Toast.makeText(this, "Erro ao carregar modelo: ${e.message}", Toast.LENGTH_LONG).show()
            e.printStackTrace()
        }
    }

    // Novo: Inicializa o sistema de sons
    private fun initializeSoundManager() {
        try {
            soundManager = SoundManager(this)
            Toast.makeText(this, "Sistema de áudio inicializado", Toast.LENGTH_SHORT).show()
        } catch (e: Exception) {
            Toast.makeText(this, "Erro ao inicializar áudio: ${e.message}", Toast.LENGTH_LONG).show()
            e.printStackTrace()
        }
    }

    private fun setupButtons() {
        recordButton.setOnTouchListener { _, event ->
            when (event.action) {
                android.view.MotionEvent.ACTION_DOWN -> {
                    startRecording()
                    recordButton.performClick() // Para acessibilidade
                    true
                }
                android.view.MotionEvent.ACTION_UP,
                android.view.MotionEvent.ACTION_CANCEL -> {
                    stopRecording()
                    true
                }
                else -> false
            }
        }
    }

    private fun startRecording() {
        accelerometerData.clear()
        isRecording = true
        recordingStartTime = System.currentTimeMillis()

        accelerometer?.let {
            sensorManager.registerListener(this, it, SensorManager.SENSOR_DELAY_FASTEST)
        }

        statusText.text = "🔴 Gravando... Faça o gesto!"
        recordButton.text = "GRAVANDO"
        resultText.text = ""
    }

    private fun stopRecording() {
        if (!isRecording) return

        isRecording = false
        sensorManager.unregisterListener(this)

        recordButton.text = "GRAVAR"
        statusText.text = "Processando dados..."

        if (accelerometerData.size >= 60) {
            classifyGesture()
        } else {
            statusText.text = "Gesto muito curto. Tente novamente."
            // Removido: som de erro não é mais necessário

            recordButton.postDelayed({
                statusText.text = "Pressione e segure o botão para gravar"
            }, 2000)
        }
    }

    private fun classifyGesture() {
        try {
            val inputData = prepareInputData()
            val result = gestureClassifier?.classify(inputData) ?: "Erro no classificador"

            statusText.text = "Classificação concluída"
            resultText.text = "Gesto reconhecido: $result"

            // Reproduz som baseado no gesto reconhecido
            playGestureSound(result)

            recordButton.postDelayed({
                statusText.text = "Pressione e segure o botão para gravar"
            }, 3000)

        } catch (e: Exception) {
            statusText.text = "Erro na classificação"
            resultText.text = "Erro: ${e.message}"

            // Removido: som de erro não é mais necessário
            e.printStackTrace()
        }
    }

    // Função para reproduzir som baseado no gesto
    private fun playGestureSound(gestureResult: String) {
        soundManager?.let { manager ->
            val gestureId = manager.mapGestureResultToId(gestureResult)

            // Log detalhado para debug
            when (gestureId) {
                "gesture1" -> println("🛑 Parando todos os sons")
                "gesture2" -> println("🔊 Tocando Eraser (uma vez)")
                "gesture3" -> println("💥 Tocando Explosion (uma vez)")
                "gesture4" -> println("🎵 Tocando Do It Again Baby (uma vez)")
                "gesture7" -> println("🎼 Iniciando loop: brush_beat_brazil")
                "gesture8" -> println("🎼 Iniciando loop: loose_brazil2")
                "unknown" -> println("❓ Gesto não reconhecido: $gestureResult")
            }

            manager.playGestureSound(gestureId)
        }
    }

    private fun prepareInputData(): FloatArray {
        val totalFeatures = windowSize * 3
        val input = FloatArray(totalFeatures)

        val availableDataSize = accelerometerData.size
        val availableSamples = availableDataSize / 3

        if (availableSamples >= windowSize) {
            val step = availableSamples.toFloat() / windowSize
            var dataIndex = 0

            for (i in 0 until windowSize) {
                val sampleIndex = (i * step).toInt() * 3
                if (sampleIndex + 2 < availableDataSize) {
                    input[dataIndex++] = accelerometerData[sampleIndex]
                    input[dataIndex++] = accelerometerData[sampleIndex + 1]
                    input[dataIndex++] = accelerometerData[sampleIndex + 2]
                }
            }
        } else {
            var inputIndex = 0
            val repetitions = windowSize / availableSamples
            val remainder = windowSize % availableSamples

            for (rep in 0 until repetitions) {
                for (i in 0 until availableDataSize step 3) {
                    if (inputIndex + 2 < totalFeatures && i + 2 < availableDataSize) {
                        input[inputIndex++] = accelerometerData[i]
                        input[inputIndex++] = accelerometerData[i + 1]
                        input[inputIndex++] = accelerometerData[i + 2]
                    }
                }
            }

            for (i in 0 until remainder * 3 step 3) {
                if (inputIndex + 2 < totalFeatures && i + 2 < availableDataSize) {
                    input[inputIndex++] = accelerometerData[i]
                    input[inputIndex++] = accelerometerData[i + 1]
                    input[inputIndex++] = accelerometerData[i + 2]
                }
            }
        }

        normalizeData(input)
        return input
    }

    private fun normalizeData(data: FloatArray) {
        for (i in data.indices) {
            data[i] = data[i] / 9.8f
        }
    }

    override fun onSensorChanged(event: SensorEvent?) {
        if (isRecording && event?.sensor?.type == Sensor.TYPE_ACCELEROMETER) {
            event.values?.let { values ->
                accelerometerData.add(values[0])
                accelerometerData.add(values[1])
                accelerometerData.add(values[2])

                val sampleCount = accelerometerData.size / 3
                statusText.text = "🔴 Gravando... $sampleCount amostras"
            }
        }
    }

    override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {}

    // Novo: Gerencia o ciclo de vida do áudio
    override fun onPause() {
        super.onPause()
        soundManager?.stopAllSounds()
    }

    override fun onResume() {
        super.onResume()
        soundManager?.resumeAllSounds()
    }

    override fun onDestroy() {
        super.onDestroy()
        gestureClassifier?.close()
        sensorManager.unregisterListener(this)
        soundManager?.release() // Novo: libera recursos de áudio
    }
}