package com.rosetta.messenger.network.connection

import com.rosetta.messenger.data.MessageRepository
import com.rosetta.messenger.network.DeliveryStatus
import com.rosetta.messenger.network.PacketMessage
import com.rosetta.messenger.utils.RosettaDev1Log
import kotlinx.coroutines.CoroutineScope

class OutgoingMessagePipelineService(
    scope: CoroutineScope,
    private val getRepository: () -> MessageRepository?,
    private val sendPacket: (PacketMessage) -> Unit,
    isAuthenticated: () -> Boolean,
    addLog: (String) -> Unit
) {
    private val retryQueueService =
        RetryQueueService(
            scope = scope,
            sendPacket = sendPacket,
            isAuthenticated = isAuthenticated,
            addLog = addLog,
            markOutgoingAsError = ::markOutgoingAsError
        )

    fun sendWithRetry(packet: PacketMessage) {
        RosettaDev1Log.d(
            "net/pipeline sendWithRetry msg=${packet.messageId.take(8)} " +
                "to=${packet.toPublicKey.take(12)} from=${packet.fromPublicKey.take(12)}"
        )
        sendPacket(packet)
        retryQueueService.register(packet)
    }

    fun resolveOutgoingRetry(messageId: String) {
        RosettaDev1Log.d("net/pipeline resolveRetry msg=${messageId.take(8)}")
        retryQueueService.resolve(messageId)
    }

    fun clearRetryQueue() {
        RosettaDev1Log.d("net/pipeline clearRetryQueue")
        retryQueueService.clear()
    }

    private suspend fun markOutgoingAsError(messageId: String, packet: PacketMessage) {
        val repository = getRepository() ?: return
        val opponentKey =
            if (packet.fromPublicKey == repository.getCurrentAccountKey()) {
                packet.toPublicKey
            } else {
                packet.fromPublicKey
            }
        val dialogKey = repository.getDialogKey(opponentKey)
        RosettaDev1Log.w("net/pipeline markError msg=${messageId.take(8)} dialog=${dialogKey.take(16)}")
        repository.updateMessageDeliveryStatus(dialogKey, messageId, DeliveryStatus.ERROR)
    }
}
