package com.example.jarvis_stts

import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.Service
import android.content.Intent
import android.os.Build
import android.os.IBinder
import android.util.Log
import androidx.core.app.NotificationCompat
import org.vosk.Model
import org.vosk.Recognizer
import org.vosk.android.RecognitionListener
import org.vosk.android.SpeechService
import java.io.File
import android.content.pm.ServiceInfo
import org.json.JSONObject

class JarvisService : Service(), RecognitionListener {

    private var voskService: SpeechService? = null
    private var voskModel: Model? = null
    private var isInteracting = false

    companion object {
        const val CHANNEL_ID = "JarvisServiceChannel"
        const val ACTION_START = "ACTION_START"
        const val ACTION_PAUSE = "ACTION_PAUSE"
        const val ACTION_RESUME = "ACTION_RESUME"
    }

    override fun onCreate() {
        super.onCreate()
        createNotificationChannel()

        // Für Android 14 (API 34) und höher müssen wir den Typ beim Starten mitgeben
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
            startForeground(
                1,
                createNotification("JARVIS hört zu..."),
                ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE
            )
        } else {
            startForeground(1, createNotification("JARVIS hört zu..."))
        }

        initVosk()
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        when (intent?.action) {
            ACTION_START -> resumeListening()
            ACTION_PAUSE -> pauseListening()
            ACTION_RESUME -> resumeListening()
        }
        return START_STICKY
    }

    private fun createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                CHANNEL_ID,
                "JARVIS Background Service",
                NotificationManager.IMPORTANCE_LOW
            )
            val manager = getSystemService(NotificationManager::class.java)
            manager.createNotificationChannel(channel)
        }
    }

    private fun createNotification(text: String): android.app.Notification {
        val notificationIntent = Intent(this, MainActivity::class.java)
        val pendingIntent = PendingIntent.getActivity(
            this, 0, notificationIntent, PendingIntent.FLAG_IMMUTABLE
        )

        return NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle("JARVIS ist aktiv")
            .setContentText(text)
            .setSmallIcon(android.R.drawable.ic_btn_speak_now) // Standard Android Icon
            .setContentIntent(pendingIntent)
            .setOngoing(true)
            .build()
    }

    private fun updateNotification(text: String) {
        val manager = getSystemService(NotificationManager::class.java)
        manager.notify(1, createNotification(text))
    }

    private fun initVosk() {
        val baseDir = getExternalFilesDir(null)
        val modelFolder = File(baseDir, "model/model-de")

        if (modelFolder.exists()) {
            Log.d("JARVIS", "Modell gefunden unter: ${modelFolder.absolutePath}")
            try {
                // Wir laden das Modell und speichern es in der Klassen-Variable 'voskModel'
                voskModel = Model(modelFolder.absolutePath)

                Log.d("JARVIS", "Modell bereit, starte Hintergrund-Dienst...")

                // Jetzt, wo das Modell da ist, können wir das Zuhören starten
                resumeListening()

            } catch (e: Exception) {
                Log.e("JARVIS", "Vosk Fehler beim Modell-Laden: ${e.message}")
                updateNotification("Fehler: Modell konnte nicht geladen werden")
            }
        } else {
            Log.e("JARVIS", "ORDNER NICHT GEFUNDEN! Pfad: ${modelFolder.absolutePath}")
            updateNotification("Fehler: Modell-Ordner fehlt")
        }
    }

    private fun pauseListening() {
        Log.d("JARVIS", "Service: Pausiere Zuhören")
        voskService?.stop()
        updateNotification("Pausiert (verarbeitet Anfrage...)")
    }

    private fun resumeListening() {
        if (voskModel == null) return
        Log.d("JARVIS", "Service: Starte Zuhören (Volles Wörterbuch)")
        voskService?.stop()

        // GANZ WICHTIG: Keine Grammar (Wortliste) mehr übergeben!
        // Wir nutzen das volle deutsche Vokabular, um Fehlinterpretationen zu vermeiden.
        val rec = Recognizer(voskModel, 16000.0f) 
        
        voskService = SpeechService(rec, 16000.0f)
        voskService?.startListening(this)

        isInteracting = false
        updateNotification("Warte auf 'Jarvis'")
    }

    override fun onPartialResult(hypothesis: String) {
        if (isInteracting) return

        try {
            val json = JSONObject(hypothesis)
            val partialText = json.optString("partial").lowercase().trim()

            // Wir ignorieren leere Strings und bekannte Rausch-Wörter für das Log
            if (partialText.isNotEmpty() && partialText != "nun" && partialText.length > 2) {
                Log.d("JARVIS_DEBUG", "Vosk hört: $partialText")
            }

            // Unser Regex-Check (den passen wir gleich an)
            if (Regex("\\b(hey joe avis|hey gravis|bei gravis|hey joe|hey ich habe es|naja bis|welche avis|jarvis)\\b").containsMatchIn(partialText)) {
                Log.d("JARVIS", "WAKE WORD ERKANNT: $partialText")
                triggerJarvis()
            }
        } catch (e: Exception) {
            Log.e("JARVIS", "Fehler beim Parsen: ${e.message}")
        }
    }

    // onResult bleibt leer oder loggt nur zur Kontrolle
    override fun onResult(hypothesis: String) {}

    private fun triggerJarvis() {
        isInteracting = true
        pauseListening()
        val intent = Intent(this, MainActivity::class.java).apply {
            addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_SINGLE_TOP)
            putExtra("WAKE_WORD_TRIGGERED", true)
        }
        startActivity(intent)
    }

    override fun onFinalResult(hypothesis: String) {}
    override fun onError(e: Exception) { Log.e("JARVIS", "Service Error: ${e.message}") }
    override fun onTimeout() {}

    override fun onDestroy() {
        super.onDestroy()
        voskService?.stop()
        voskService?.shutdown()
    }

    override fun onBind(intent: Intent?): IBinder? = null
}