package wang.yaojia.webterm.push

import com.google.firebase.messaging.FirebaseMessaging
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch
import wang.yaojia.webterm.hostregistry.Host
import javax.inject.Inject
import javax.inject.Singleton

/**
 * Drives [PushRegistrar] from the app's lifecycle edges (plan §5 A31, §4.5): it resolves the CURRENT
 * FCM registration token from Firebase and (re)registers it with the hosts that need it.
 *
 *  - [registerAllHosts] — **app start**: POST the current token to every paired host.
 *  - [registerHost] — a **newly paired host**: POST the current token to just that host.
 *
 * Token rotation self-heals separately through [PushRegistrarTokenSink] (`onNewToken`), so this only
 * covers the "app came up" / "host added" edges. The Firebase token fetch is wrapped in `runCatching`
 * so a missing `google-services.json` / uninitialised `FirebaseApp` degrades to a no-op instead of
 * crashing (best-effort push per R1). The token is handed straight to the registrar and never logged.
 */
@Singleton
public class PushCoordinator @Inject constructor(
    private val registrar: PushRegistrar,
) {
    /** App-lifetime scope for the fire-and-forget best-effort fan-out. */
    private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Default)

    /** App start: register the current token with every paired host. Best-effort; safe to call repeatedly. */
    public fun registerAllHosts() {
        withCurrentToken { token -> scope.launch { registrar.registerAllHosts(token) } }
    }

    /** A newly paired [host]: register the current token with just that host. */
    public fun registerHost(host: Host) {
        withCurrentToken { token -> scope.launch { registrar.registerHost(host, token) } }
    }

    /** Resolve the current FCM token, then invoke [use]. A Firebase fault degrades to a no-op. */
    private fun withCurrentToken(use: (String) -> Unit) {
        runCatching {
            FirebaseMessaging.getInstance().token.addOnSuccessListener { token ->
                if (!token.isNullOrEmpty()) use(token)
            }
        }
    }
}
