package ch.threema.app.processors.reflectedoutgoingmessage

import androidx.core.util.component1
import androidx.core.util.component2
import ch.threema.app.eventbus.GlobalEventBuses
import ch.threema.app.eventbus.events.MessageEvent
import ch.threema.app.managers.ServiceManager
import ch.threema.app.utils.QuoteUtil
import ch.threema.base.utils.getThreemaLogger
import ch.threema.domain.protocol.csp.messages.TextMessage
import ch.threema.protobuf.common.CspE2eMessageType
import ch.threema.protobuf.d2d.OutgoingMessage
import ch.threema.storage.models.MessageModel
import ch.threema.storage.models.MessageType
import ch.threema.storage.models.data.MessageContentsType
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject

private val logger = getThreemaLogger("ReflectedOutgoingTextTask")

internal class ReflectedOutgoingTextTask(
    outgoingMessage: OutgoingMessage,
    serviceManager: ServiceManager,
) : ReflectedOutgoingContactMessageTask<TextMessage>(
    outgoingMessage = outgoingMessage,
    message = TextMessage.fromReflected(outgoingMessage),
    type = CspE2eMessageType.TEXT,
    serviceManager = serviceManager,
),
    KoinComponent {
    private val globalEventBuses: GlobalEventBuses by inject()
    private val messageService by lazy { serviceManager.messageService }

    override fun processOutgoingMessage() {
        messageService.getMessageModelByApiMessageIdAndReceiver(message.messageId.toString(), messageReceiver)?.run {
            // It is possible that a message gets reflected twice when the reflecting task gets restarted.
            logger.info("Skipping message {} as it already exists.", message.messageId)
            return
        }

        val messageModel: MessageModel = createMessageModel(
            MessageType.TEXT,
            MessageContentsType.TEXT,
        )
        val (body, messageId) = QuoteUtil.getBodyAndQuotedMessageId(message.text)
        messageModel.body = body
        messageModel.quotedMessageId = messageId
        messageService.save(messageModel)
        globalEventBuses.messages.emit(MessageEvent.NewMessage(messageModel))
    }
}
