package com.rugvedsarika.voicereader.ui

import android.app.Application
import android.content.Intent
import android.os.Build
import android.os.CountDownTimer
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.rugvedsarika.voicereader.data.TTSManager
import com.rugvedsarika.voicereader.TTSService
import com.rugvedsarika.voicereader.R
import java.io.File
import java.util.Locale



class MainViewModel(application: Application) : AndroidViewModel(application) {

    private val ttsManager = TTSManager(application)
    private val prefManager = com.rugvedsarika.voicereader.data.PreferenceManager(application)

    val textToSpeak = MutableLiveData<String>("")
    val speed = MutableLiveData<Float>(prefManager.getSpeed())
    val pitch = MutableLiveData<Float>(prefManager.getPitch())
    val selectedLanguage = MutableLiveData<Locale>(prefManager.getLanguage())
    val wordRange = MutableLiveData<Pair<Int, Int>>()
    val isSpeaking = MutableLiveData<Boolean>(false)
    val isPaused = MutableLiveData<Boolean>(false)
    val languageError = MutableLiveData<String?>(null)
    val textSize = MutableLiveData<Float>(prefManager.getTextSize()) // Load saved text size
    val backgroundPlaybackEnabled = MutableLiveData<Boolean>(true)
    
    val sleepTimerActive = MutableLiveData<Boolean>(false)

    val timerRemainingSeconds = MutableLiveData<Int>(0)
    private var countDownTimer: CountDownTimer? = null



    private val _isTtsReady = MutableLiveData<Boolean>(false)
    val isTtsReady: LiveData<Boolean> = _isTtsReady


    init {
        ttsManager.setOnInitListener {
            _isTtsReady.postValue(true)
            // Apply saved language after TTS is ready
            setLanguage(prefManager.getLanguage())
        }
        ttsManager.setSpeechProgressListener(
            onWord = { start, end ->
                wordRange.postValue(Pair(start, end))
            },
            onDone = {
                isSpeaking.postValue(false)
                wordRange.postValue(Pair(0, 0))
            }
        )

        // Observe and save settings
        speed.observeForever { prefManager.saveSpeed(it) }
        pitch.observeForever { prefManager.savePitch(it) }
        textSize.observeForever { prefManager.saveTextSize(it) }

        // Generate dummy data if first run/empty
        _isTtsReady.observeForever { ready ->
            if (ready) {
                generateSampleData()
            }
        }
    }

    private fun generateSampleData() {
        val app = getApplication<Application>()
        if (prefManager.isDummyDataGenerated()) return
        
        val storageDir = app.getExternalFilesDir(android.os.Environment.DIRECTORY_MUSIC)
        
        val samples = listOf(
            Triple("Sample_English.wav", Locale.ENGLISH, "Welcome to VoiceReader! This is a high-quality neural voice for English. Enjoy natural listening!"),
            Triple("Sample_Hindi.wav", Locale("hi", "IN"), "वॉइसरीडर में आपका स्वागत है! यह हिंदी के लिए एक उच्च गुणवत्ता वाली आवाज़ है।"),
            Triple("Sample_Marathi.wav", Locale("mr", "IN"), "व्हॉइसरीडरमध्ये आपले स्वागत आहे! ही मराठीसाठी एक उत्तम दर्जाची नैसर्गिक आवाज़ आहे."),
            Triple("Daily_News_EN.wav", Locale.ENGLISH, "Today's top stories: Markets reached an all-time high, while technology stocks led the surge."),
            Triple("Technical_Guide_HI.wav", Locale("hi", "IN"), "यह एक तकनीकी मार्गदर्शिका है जो आपको वॉइसरीडर का सर्वोत्तम उपयोग करने में मदद करेगी।"),
            Triple("Business_Update_MR.wav", Locale("mr", "IN"), "व्यवसाय जगतातील आजच्या ठळक घडामोडी: नफा-तोटा आणि बाजारातील नवीन संधी."),
            Triple("Personal_Note.wav", Locale.ENGLISH, "Don't forget to scan your medical reports tomorrow for easy listening during the commute."),
            Triple("Quick_OCR_Scan.wav", Locale("mr", "IN"), "स्कॅन केलेला मजकूर आता ऑडिओ स्वरूपात उपलब्ध आहे, ज्यामुळे वाचणे अधिक सोपे झाले आहे.")
        )

        samples.forEach { (fileName, locale, text) ->
            val file = File(storageDir, fileName)
            if (!file.exists()) {
                ttsManager.setLanguage(locale)
                ttsManager.synthesizeToFile(text, file, 1.0f, 1.0f) { success ->
                    if (success) {
                        android.util.Log.d("MainViewModel", "Generated sample: $fileName")
                    }
                }
            }
        }
        
        prefManager.setDummyDataGenerated(true)
        // Restore default language after generation
        setLanguage(prefManager.getLanguage())
    }


    fun speak() {
        val text = textToSpeak.value ?: ""
        if (text.isNotEmpty()) {
            if (isPaused.value == true) {
                resume()
            } else {
                isSpeaking.value = true
                isPaused.value = false
                ttsManager.speak(text, speed.value ?: 1.0f, pitch.value ?: 1.0f)
                
                if (backgroundPlaybackEnabled.value == true) {
                    startForegroundService(text)
                }
            }
        }
    }


    fun pause() {
        if (isSpeaking.value == true) {
            ttsManager.pause()
            isPaused.value = true
            isSpeaking.value = false
        }
    }

    fun resume() {
        if (isPaused.value == true) {
            isPaused.value = false
            isSpeaking.value = true
            ttsManager.resume(speed.value ?: 1.0f, pitch.value ?: 1.0f)
        }
    }

    fun stop() {
        ttsManager.stop()
        isSpeaking.value = false
        isPaused.value = false
        wordRange.value = Pair(0, 0)
        cancelSleepTimer()
        stopForegroundService()
    }

    private fun startForegroundService(text: String) {
        val app = getApplication<Application>()
        val intent = Intent(app, TTSService::class.java).apply {
            action = "START"
            putExtra("TEXT", text)
            putExtra("SPEED", speed.value ?: 1.0f)
            putExtra("PITCH", pitch.value ?: 1.0f)
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            app.startForegroundService(intent)
        } else {
            app.startService(intent)
        }
    }

    private fun stopForegroundService() {
        val app = getApplication<Application>()
        val intent = Intent(app, TTSService::class.java).apply {
            action = "STOP"
        }
        app.startService(intent)
    }





    fun saveToFile(file: File, onComplete: (Boolean) -> Unit) {
        val text = textToSpeak.value ?: ""
        if (text.isNotEmpty()) {
            ttsManager.synthesizeToFile(text, file, speed.value ?: 1.0f, pitch.value ?: 1.0f, onComplete)
        } else {
            onComplete(false)
        }
    }

    fun getAvailableLanguages(): List<Locale> {
        return ttsManager.getAvailableLanguages()
    }



    val currentEngine = MutableLiveData<String>("")
    val isGoogleEngine = MutableLiveData<Boolean>(false)
    val isHighQualityVoice = MutableLiveData<Boolean>(false)

    fun setLanguage(locale: Locale) {
        selectedLanguage.value = locale
        prefManager.saveLanguage(locale)
        val result = ttsManager.setLanguage(locale)
        
        currentEngine.value = ttsManager.getCurrentEngineInfo()
        isGoogleEngine.value = ttsManager.isGoogleEngine()
        
        // Check if the current voice is high quality (neural)
        val currentVoice = ttsManager.getVoice()
        isHighQualityVoice.value = currentVoice?.let { 
            val name = it.name.lowercase()
            name.contains("network") || name.contains("neural") || 
            name.contains("-x-") || it.isNetworkConnectionRequired
        } ?: false

        if (result == android.speech.tts.TextToSpeech.LANG_MISSING_DATA || 
            result == android.speech.tts.TextToSpeech.LANG_NOT_SUPPORTED) {
            languageError.value = "Voice data for ${locale.displayName} is missing on this device."
        } else {
            languageError.value = null
        }
    }

    fun startSleepTimer(minutes: Int) {
        cancelSleepTimer()
        if (minutes <= 0) return
        
        sleepTimerActive.value = true
        countDownTimer = object : CountDownTimer(minutes * 60 * 1000L, 1000) {
            override fun onTick(millisUntilFinished: Long) {
                timerRemainingSeconds.value = (millisUntilFinished / 1000).toInt()
            }

            override fun onFinish() {
                stop()
                sleepTimerActive.value = false
                timerRemainingSeconds.value = 0
            }
        }.start()
    }

    fun cancelSleepTimer() {
        countDownTimer?.cancel()
        sleepTimerActive.value = false
        timerRemainingSeconds.value = 0
    }



    override fun onCleared() {
        super.onCleared()
        ttsManager.release()
    }
}
