package com.divya.animaltap.util

import android.content.Context
import android.media.MediaPlayer
import androidx.annotation.RawRes

class SoundPlayer(private val context: Context) {

    private var mediaPlayer: MediaPlayer? = null
    private var textToSpeech: android.speech.tts.TextToSpeech? = null
    private var isTtsReady = false

    init {
        textToSpeech = android.speech.tts.TextToSpeech(context) { status ->
            if (status == android.speech.tts.TextToSpeech.SUCCESS) {
                textToSpeech?.language = java.util.Locale.US
                isTtsReady = true
            }
        }
    }

    fun playAnimalSound(@RawRes nameSoundRes: Int, @RawRes animalSoundRes: Int) {
        // We ignore nameSoundRes (raw) and instead use the Context to get the String name?
        // Wait, playAnimalSound signature in MainActivity passes nameSoundRes (Raw ID).
        // But we want to speak the API name.
        // We'll overload or just pass the common name if possible?
        // Actually, MainActivity passes: R.raw.dog_name
        // But we want to speak "Dog".
        // Animal object has "nameRes" (String ID). 
        // We should update the method signature to take nameRes (String ID) instead of nameSoundRes (Raw ID).
        stop() 
    }
    
    // Updated signature to take String Res ID for name
    fun playDetailedSound(@androidx.annotation.StringRes nameRes: Int, @RawRes animalSoundRes: Int) {
        stop()
        
        val text = context.getString(nameRes)
        
        if (isTtsReady) {
            val params = android.os.Bundle()
            params.putString(android.speech.tts.TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "ANIMAL_NAME_CHAIN")
            
            // Speak Name
            textToSpeech?.speak(text, android.speech.tts.TextToSpeech.QUEUE_FLUSH, params, "ANIMAL_NAME_CHAIN")
            
            // Set listener to play sound after speaking
            textToSpeech?.setOnUtteranceProgressListener(object : android.speech.tts.UtteranceProgressListener() {
                override fun onStart(utteranceId: String?) {}

                override fun onDone(utteranceId: String?) {
                    if (utteranceId == "ANIMAL_NAME_CHAIN") {
                        playRawSound(animalSoundRes)
                    }
                }

                override fun onError(utteranceId: String?) {}
            })
        } else {
            // Fallback if TTS not ready
            playRawSound(animalSoundRes)
        }
    }

    fun speakAnimalName(@androidx.annotation.StringRes nameRes: Int) {
        stop()
        val text = context.getString(nameRes)
        if (isTtsReady) {
            val params = android.os.Bundle()
            // We use a different ID so it doesn't trigger the chain listener
            params.putString(android.speech.tts.TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "ANIMAL_NAME_ONLY")
            textToSpeech?.speak(text, android.speech.tts.TextToSpeech.QUEUE_FLUSH, params, "ANIMAL_NAME_ONLY")
        }
    }

    fun playAnimalSoundEffect(@RawRes soundRes: Int) {
        stop()
        playRawSound(soundRes)
    }

    private fun playRawSound(@RawRes soundRes: Int) {
        try {
            mediaPlayer = MediaPlayer.create(context, soundRes)
            mediaPlayer?.isLooping = true // Enable looping
            
            // Stop after 5 seconds
            android.os.Handler(android.os.Looper.getMainLooper()).postDelayed({
                mediaPlayer?.let {
                    if (it.isPlaying) {
                        it.stop()
                        it.release()
                        mediaPlayer = null
                    }
                }
            }, 5000) // 5 seconds
            
            mediaPlayer?.start()
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    fun stop() {
        if (textToSpeech?.isSpeaking == true) {
            textToSpeech?.stop()
        }
        mediaPlayer?.stop()
        mediaPlayer?.release()
        mediaPlayer = null
    }
    
    fun release() {
        stop()
        textToSpeech?.shutdown()
    }
}
