package com.rosetta.messenger.network.connection

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import java.util.concurrent.atomic.AtomicLong

class AuthBootstrapCoordinator(
    private val scope: CoroutineScope,
    private val addLog: (String) -> Unit
) {
    private val sessionCounter = AtomicLong(0L)
    private val mutex = Mutex()

    @Volatile private var activeAuthenticatedSessionId = 0L
    @Volatile private var lastBootstrappedSessionId = 0L
    @Volatile private var deferredAuthBootstrap = false

    fun onAuthenticatedSessionStarted(): Long {
        val sessionId = sessionCounter.incrementAndGet()
        activeAuthenticatedSessionId = sessionId
        deferredAuthBootstrap = false
        return sessionId
    }

    fun reset() {
        deferredAuthBootstrap = false
        activeAuthenticatedSessionId = 0L
        lastBootstrappedSessionId = 0L
    }

    fun isBootstrapPending(): Boolean {
        return activeAuthenticatedSessionId > 0L &&
            lastBootstrappedSessionId != activeAuthenticatedSessionId
    }

    fun tryRun(
        trigger: String,
        canRun: () -> Boolean,
        onDeferred: () -> Unit,
        runBootstrap: suspend () -> Unit
    ) {
        val sessionId = activeAuthenticatedSessionId
        if (sessionId <= 0L) return

        scope.launch {
            mutex.withLock {
                if (sessionId != activeAuthenticatedSessionId) return@withLock
                if (sessionId == lastBootstrappedSessionId) return@withLock
                if (!canRun()) {
                    deferredAuthBootstrap = true
                    onDeferred()
                    return@withLock
                }

                deferredAuthBootstrap = false
                addLog("🚀 AUTH bootstrap start session=$sessionId trigger=$trigger")
                runCatching { runBootstrap() }
                    .onSuccess {
                        lastBootstrappedSessionId = sessionId
                        addLog("✅ AUTH bootstrap complete session=$sessionId trigger=$trigger")
                    }
                    .onFailure { error ->
                        addLog(
                            "❌ AUTH bootstrap failed session=$sessionId trigger=$trigger: ${error.message}"
                        )
                    }
            }
        }
    }
}
