package ch.threema.app.mediagallery

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import ch.threema.app.messagereceiver.MessageReceiver
import ch.threema.app.services.MessageService
import ch.threema.common.DispatcherProvider
import ch.threema.storage.models.AbstractMessageModel
import ch.threema.storage.models.MessageType
import kotlinx.coroutines.withContext

class MediaGalleryRepository(
    private val dispatcherProvider: DispatcherProvider,
) {

    private val _messages: MutableLiveData<List<AbstractMessageModel>?> = MutableLiveData(null)
    val messages: LiveData<List<AbstractMessageModel>?> = _messages

    /**
     *  Loads the message models from database where the content type is in [contentTypes] and publish the results
     *  through [messages] observable.
     *
     *  @param contentTypes An empty set will always lead to zero results
     */
    suspend fun loadMessages(messageReceiver: MessageReceiver<*>, contentTypes: Set<Int>) {
        if (contentTypes.isEmpty()) {
            _messages.value = emptyList()
            return
        }

        _messages.value = withContext(dispatcherProvider.worker) {
            messageReceiver.loadMessages(
                buildMessageFilter(
                    contentTypes = contentTypes,
                ),
            )
        }
    }

    /**
     * @param contentTypes This filter will only query message models that are of a type contained in this set.
     *                     An empty set is an invalid value, as it would always lead to zero message results.
     */
    private fun buildMessageFilter(contentTypes: Set<Int>): MessageService.MessageFilter {
        require(contentTypes.isNotEmpty()) { "Must at least query messages of one specified content type" }
        return object : MessageService.MessageFilter {
            override fun getPageSize(): Long = 0
            override fun getPageReferenceId(): Int = 0
            override fun withStatusMessages(): Boolean = false
            override fun withUnsaved(): Boolean = true
            override fun onlyUnread(): Boolean = false
            override fun onlyDownloaded(): Boolean = false
            override fun types(): Array<MessageType>? = null
            override fun contentTypes(): IntArray = contentTypes.toIntArray()
            override fun displayTags(): IntArray? = null
        }
    }
}
