package io.nexilis.service.data.repositories

import androidx.lifecycle.LiveData
import io.nexilis.service.Service
import io.nexilis.service.core.Data
import io.nexilis.service.core.toStupidString
import io.nexilis.service.data.daos.GroupMemberDao
import io.nexilis.service.data.daos.MessageDao
import io.nexilis.service.data.daos.MessageStatusDao
import io.nexilis.service.data.entities.MainEntity
import io.nexilis.service.data.entities.Message
import io.nexilis.service.data.entities.MessageStatus
import javax.inject.Inject

class MessageRepository @Inject constructor(
    private val dao: MessageDao,
    private val messageStatusDao: MessageStatusDao,
    private val groupMemberDao: GroupMemberDao
) : Repository {

    val all: LiveData<List<Message>> = dao.getAll()

    fun get(id: String): LiveData<Message> {
        return dao.get(id)
    }

    fun getOpposite(pin: String): LiveData<List<Message>> {
        return dao.getOpposite(pin)
    }

    override suspend fun insert(entity: MainEntity) {
        dao.insert(entity as Message)
    }

    suspend fun send(entity: MainEntity) {
        val message = entity as Message
        dao.insert(message)
        if (message.message_scope_id == "4") {
            val id = message.chat_id.ifEmpty { message.l_pin }
            groupMemberDao.get(id).value?.let {
                it.forEach { member ->
                    messageStatusDao.insert(
                        MessageStatus(
                            message_id = message.message_id,
                            f_pin = member.f_pin,
                            user_id = member.f_pin,
                            last_update = System.currentTimeMillis(),
                            time_delivered = 0,
                            time_read = 0,
                            time_ack = 0,
                        )
                    )
                }
            }
        } else {
            messageStatusDao.insert(
                MessageStatus(
                    message_id = message.message_id,
                    f_pin = message.opposite_pin,
                    user_id = message.opposite_pin,
                    last_update = System.currentTimeMillis(),
                    time_delivered = 0,
                    time_read = 0,
                    time_ack = 0,
                )
            )
        }
        val bodies = mutableMapOf(
            "A18" to message.message_id,
            "A00" to message.f_pin,
            "A01" to message.l_pin,
            "A19" to message.server_date.toString(),
            "lcltm" to message.local_timestamp.toString(),
            "A06" to message.message_scope_id,
            "A15" to message.status,
            "A07" to message.message_text.toStupidString(),
            "A118" to message.credential,
            "A149" to message.attachment_flag.toString(),
            "A52" to message.blog_id,
            "A36" to message.message_large_text,
            "ics" to message.is_consult.toString(),
            "icc" to message.is_call_center.toString(),
            "ccid" to message.call_center_id,
            "iwm" to message.is_work_mode.toString(),
            "Bf" to message.read_receipts.toString()
        )
        if (message.message_scope_id == "5") {
            bodies["BR"] = message.f_display_name
        }
        if (message.contact.isNotEmpty()) {
            bodies["A116"] = message.contact
        }
        if (message.image_id.isNotEmpty()) {
            bodies["A57"] = message.image_id
        }
        if (message.audio_id.isNotEmpty()) {
            bodies["A63"] = message.audio_id
        }
        if (message.video_id.isNotEmpty()) {
            bodies["A47"] = message.video_id
        }
        if (message.file_id.isNotEmpty()) {
            bodies["BN"] = message.file_id
        }
        if (message.thumb_id.isNotEmpty()) {
            bodies["A74"] = message.thumb_id
        }
        if (message.reff_id.isNotEmpty()) {
            bodies["A121"] = message.reff_id
        }
        if (message.chat_id.isNotEmpty()) {
            bodies["BA"] = message.chat_id
        }
        if (message.broadcast_flag > 0) {
            bodies["B4"] = message.broadcast_flag.toString()
        }
        Service.sendSync(
            Data(
                code = "S0",
                status = message.message_id,
                f_pin = message.f_pin,
                bodies = bodies
            )
        )?.let {
            messageStatusDao.updateStatus(
                status = it.bodies["A15"]?.toInt() ?: 2, // delivering
                messageId = message.message_id,
                pin = message.opposite_pin
            )
        }

    }
}