package com.rosetta.messenger.network.connection

import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.launch

class InboundTaskQueueService(
    private val scope: CoroutineScope,
    private val onTaskQueued: () -> Unit,
    private val onTaskFailure: (String, Throwable?) -> Unit
) {
    private val inboundTaskChannel = Channel<suspend () -> Unit>(Channel.UNLIMITED)
    @Volatile private var inboundQueueDrainJob: Job? = null

    fun enqueue(block: suspend () -> Unit): Boolean {
        ensureDrainRunning()
        onTaskQueued()
        val result = inboundTaskChannel.trySend(block)
        if (result.isFailure) {
            onTaskFailure("Failed to enqueue inbound task", result.exceptionOrNull())
            return false
        }
        return true
    }

    suspend fun whenTasksFinish(): Boolean {
        val done = CompletableDeferred<Unit>()
        if (!enqueue { done.complete(Unit) }) {
            return false
        }
        done.await()
        return true
    }

    private fun ensureDrainRunning() {
        if (inboundQueueDrainJob?.isActive == true) return
        inboundQueueDrainJob = scope.launch {
            for (task in inboundTaskChannel) {
                try {
                    task()
                } catch (t: Throwable) {
                    onTaskFailure("Dialog queue error", t)
                }
            }
        }
    }
}
