package ch.threema.app.processors.reflectedoutgoingmessage

import ch.threema.app.eventbus.GlobalEventBuses
import ch.threema.app.eventbus.events.MessageEvent
import ch.threema.app.managers.ServiceManager
import ch.threema.base.utils.getThreemaLogger
import ch.threema.domain.protocol.csp.messages.location.LocationMessage
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.LocationDataModel
import ch.threema.storage.models.data.MessageContentsType
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject

private val logger = getThreemaLogger("ReflectedOutgoingLocationTask")

internal class ReflectedOutgoingLocationTask(
    outgoingMessage: OutgoingMessage,
    serviceManager: ServiceManager,
) : ReflectedOutgoingContactMessageTask<LocationMessage>(
    outgoingMessage = outgoingMessage,
    message = LocationMessage.fromReflected(outgoingMessage),
    type = CspE2eMessageType.LOCATION,
    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.LOCATION,
            MessageContentsType.LOCATION,
        )
        messageModel.locationData = LocationDataModel(
            latitude = message.latitude,
            longitude = message.longitude,
            accuracy = message.accuracy,
            poi = message.poi,
        )
        messageService.save(messageModel)
        globalEventBuses.messages.emit(MessageEvent.NewMessage(messageModel))
    }
}
