// SPDX-FileCopyrightText: 2026 Reactorcoremeltdown
// SPDX-License-Identifier: GPL-3.0-or-later

package space.rcmd.android.sizzle.playback

import android.content.Context
import android.content.Intent
import androidx.media3.common.util.UnstableApi
import androidx.media3.session.MediaSession
import androidx.media3.session.MediaSessionService
import space.rcmd.android.sizzle.SizzleApp
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch

/**
 * A media3 [MediaSessionService] that owns the audio engine's lifecycle and hosts
 * a [MediaSession] wrapping it (via [EnginePlayer]). media3 automatically provides
 * the media notification, lock-screen controls, and Bluetooth/headset media-button
 * handling from the session — so the same transport the on-screen buttons drive is
 * also controllable from outside the app, and playback continues in the background.
 */
@UnstableApi
class PlaybackService : MediaSessionService() {

    private val engine get() = (application as SizzleApp).audioEngine
    private var session: MediaSession? = null
    private val scope = CoroutineScope(Dispatchers.Main + SupervisorJob())

    override fun onCreate() {
        super.onCreate()
        engine.start()
        val player = EnginePlayer(engine)
        session = MediaSession.Builder(this, player).build()
        // Keep the session's reported state in sync with the engine (the on-screen
        // Play/Pause talks to the engine directly, so we mirror it here).
        scope.launch { engine.transport.collect { player.refresh() } }
    }

    override fun onGetSession(controllerInfo: MediaSession.ControllerInfo): MediaSession? = session

    override fun onDestroy() {
        scope.cancel()
        session?.run { player.release(); release() }
        session = null
        engine.release()
        super.onDestroy()
    }

    companion object {
        /** Start the service from a foreground context (safe: plain startService,
         *  MediaSessionService promotes itself to foreground when playback begins). */
        fun start(context: Context) {
            context.startService(Intent(context, PlaybackService::class.java))
        }
    }
}
