package com.rosetta.messenger.ui.chats

import android.graphics.BitmapFactory
import android.net.Uri
import com.rosetta.messenger.crypto.CryptoManager
import com.rosetta.messenger.database.RosettaDatabase
import com.rosetta.messenger.domain.chats.usecase.CreateAvatarAttachmentCommand
import com.rosetta.messenger.domain.chats.usecase.CreateFileAttachmentCommand
import com.rosetta.messenger.domain.chats.usecase.CreateVideoCircleAttachmentCommand
import com.rosetta.messenger.domain.chats.usecase.EncodeVideoUriToHexCommand
import com.rosetta.messenger.domain.chats.usecase.EncodeVideoUriToHexUseCase
import com.rosetta.messenger.domain.chats.usecase.EncryptAndUploadAttachmentCommand
import com.rosetta.messenger.domain.chats.usecase.ResolveVideoCircleMetaCommand
import com.rosetta.messenger.domain.chats.usecase.ResolveVideoCircleMetaUseCase
import com.rosetta.messenger.domain.chats.usecase.SendMediaMessageCommand
import com.rosetta.messenger.network.AttachmentType
import com.rosetta.messenger.network.DeliveryStatus
import com.rosetta.messenger.network.MessageAttachment
import com.rosetta.messenger.ui.chats.models.ChatMessage
import com.rosetta.messenger.ui.chats.models.MessageStatus
import com.rosetta.messenger.utils.AttachmentFileManager
import com.rosetta.messenger.utils.AvatarFileManager
import com.rosetta.messenger.utils.MediaUtils
import java.util.Date
import java.util.UUID
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.json.JSONArray
import org.json.JSONObject

internal class AttachmentsFeatureCoordinator(
    private val chatViewModel: ChatViewModel,
    private val resolveVideoCircleMetaUseCase: ResolveVideoCircleMetaUseCase,
    private val encodeVideoUriToHexUseCase: EncodeVideoUriToHexUseCase
) {
    fun sendImageGroupFromUris(imageUris: List<Uri>, caption: String = "") {
        if (imageUris.isEmpty()) return
        if (imageUris.size == 1) {
            chatViewModel.attachmentsViewModel.sendImageFromUri(imageUris.first(), caption)
            return
        }

        val context = chatViewModel.appContext()
        chatViewModel.launchBackgroundUpload {
            val prepared = mutableListOf<ChatViewModel.ImageData>()
            for ((index, uri) in imageUris.withIndex()) {
                val (width, height) = MediaUtils.getImageDimensions(context, uri)
                val imageBase64 = MediaUtils.uriToBase64Image(context, uri) ?: continue
                val blurhash = MediaUtils.generateBlurhash(context, uri)
                chatViewModel.addProtocolLog(
                    "📸 IMG-GROUP convert item#$index: ${width}x$height, base64Len=${imageBase64.length}, blurhashLen=${blurhash.length}"
                )
                prepared.add(
                    ChatViewModel.ImageData(
                        base64 = imageBase64,
                        blurhash = blurhash,
                        width = width,
                        height = height
                    )
                )
            }
            if (prepared.isEmpty()) return@launchBackgroundUpload
            withContext(Dispatchers.Main) {
                sendImageGroup(prepared, caption)
            }
        }
    }

    fun sendImageGroup(images: List<ChatViewModel.ImageData>, caption: String = "") {
        if (images.isEmpty()) return
        if (images.size == 1) {
            val image = images.first()
            chatViewModel.attachmentsViewModel.sendImageMessage(
                imageBase64 = image.base64,
                blurhash = image.blurhash,
                caption = caption,
                width = image.width,
                height = image.height
            )
            return
        }

        val sendContext = chatViewModel.resolveOutgoingSendContext() ?: return
        if (!chatViewModel.tryAcquireSendSlot()) {
            return
        }

        val messageId = UUID.randomUUID().toString().replace("-", "").take(32)
        val timestamp = System.currentTimeMillis()
        val text = caption.trim()
        chatViewModel.logPhotoEvent(
            messageId,
            "group start: count=${images.size}, captionLen=${text.length}"
        )

        val attachmentsList =
            images.mapIndexed { index, imageData ->
                MessageAttachment(
                    id = "img_${timestamp}_$index",
                    type = AttachmentType.IMAGE,
                    preview = imageData.blurhash,
                    blob = imageData.base64,
                    width = imageData.width,
                    height = imageData.height
                )
            }

        chatViewModel.addOutgoingMessageOptimistic(
            ChatMessage(
                id = messageId,
                text = text,
                isOutgoing = true,
                timestamp = Date(timestamp),
                status = MessageStatus.SENDING,
                attachments = attachmentsList
            )
        )
        chatViewModel.clearInputText()

        chatViewModel.launchBackgroundUpload {
            try {
                val groupStartedAt = System.currentTimeMillis()
                val encryptionContext =
                    chatViewModel.buildEncryptionContext(
                        plaintext = text,
                        recipient = sendContext.recipient,
                        privateKey = sendContext.privateKey
                    ) ?: throw IllegalStateException("Cannot resolve chat encryption context")
                val encryptedContent = encryptionContext.encryptedContent
                val encryptedKey = encryptionContext.encryptedKey
                val aesChachaKey = encryptionContext.aesChachaKey
                val privateKeyHash = CryptoManager.generatePrivateKeyHash(sendContext.privateKey)
                val isSavedMessages = sendContext.sender == sendContext.recipient

                val networkAttachments = mutableListOf<MessageAttachment>()
                val attachmentsJsonArray = JSONArray()

                for ((index, imageData) in images.withIndex()) {
                    val attachmentId = "img_${timestamp}_$index"
                    chatViewModel.logPhotoEvent(
                        messageId,
                        "group item#$index start: id=${chatViewModel.shortPhotoLogId(attachmentId)}, size=${imageData.width}x${imageData.height}"
                    )

                    val uploadResult =
                        chatViewModel.encryptAndUploadAttachment(
                            EncryptAndUploadAttachmentCommand(
                                payload = imageData.base64,
                                attachmentPassword = encryptionContext.attachmentPassword,
                                attachmentId = attachmentId,
                                isSavedMessages = isSavedMessages
                            )
                        )
                    val uploadTag = uploadResult.transportTag
                    val attachmentTransportServer = uploadResult.transportServer
                    val previewValue = imageData.blurhash
                    chatViewModel.logPhotoEvent(
                        messageId,
                        "group item#$index upload done: tag=${chatViewModel.shortPhotoLogId(uploadTag)}"
                    )

                    AttachmentFileManager.saveAttachment(
                        context = chatViewModel.appContext(),
                        blob = imageData.base64,
                        attachmentId = attachmentId,
                        publicKey = sendContext.sender,
                        privateKey = sendContext.privateKey
                    )

                    networkAttachments.add(
                        MessageAttachment(
                            id = attachmentId,
                            blob = if (uploadTag.isNotEmpty()) "" else uploadResult.encryptedBlob,
                            type = AttachmentType.IMAGE,
                            preview = previewValue,
                            width = imageData.width,
                            height = imageData.height,
                            transportTag = uploadTag,
                            transportServer = attachmentTransportServer
                        )
                    )

                    attachmentsJsonArray.put(
                        JSONObject().apply {
                            put("id", attachmentId)
                            put("type", AttachmentType.IMAGE.value)
                            put("preview", previewValue)
                            put("blob", "")
                            put("width", imageData.width)
                            put("height", imageData.height)
                            put("transportTag", uploadTag)
                            put("transportServer", attachmentTransportServer)
                        }
                    )
                }

                chatViewModel.sendMediaMessage(
                    SendMediaMessageCommand(
                        fromPublicKey = sendContext.sender,
                        toPublicKey = sendContext.recipient,
                        encryptedContent = encryptedContent,
                        encryptedKey = encryptedKey,
                        aesChachaKey = aesChachaKey,
                        privateKeyHash = privateKeyHash,
                        messageId = messageId,
                        timestamp = timestamp,
                        mediaAttachments = networkAttachments,
                        isSavedMessages = isSavedMessages
                    )
                )

                val storedEncryptedKey =
                    if (encryptionContext.isGroup) {
                        chatViewModel.buildStoredGroupEncryptedKey(
                            encryptionContext.attachmentPassword,
                            sendContext.privateKey
                        )
                    } else {
                        encryptedKey
                    }

                chatViewModel.saveOutgoingMessage(
                    messageId = messageId,
                    text = text,
                    encryptedContent = encryptedContent,
                    encryptedKey = storedEncryptedKey,
                    timestamp = timestamp,
                    delivered = if (isSavedMessages) 1 else 0,
                    attachmentsJson = attachmentsJsonArray.toString(),
                    accountPublicKey = sendContext.sender,
                    accountPrivateKey = sendContext.privateKey,
                    opponentPublicKey = sendContext.recipient
                )

                withContext(Dispatchers.Main) {
                    chatViewModel.updateMessageStatusUi(messageId, MessageStatus.SENT)
                }

                chatViewModel.saveOutgoingDialog(
                    lastMessage = if (text.isNotEmpty()) text else "📷 ${images.size} photos",
                    timestamp = timestamp,
                    accountPublicKey = sendContext.sender,
                    accountPrivateKey = sendContext.privateKey,
                    opponentPublicKey = sendContext.recipient
                )
                chatViewModel.logPhotoEvent(
                    messageId,
                    "group completed; totalElapsed=${System.currentTimeMillis() - groupStartedAt}ms"
                )
            } catch (e: Exception) {
                chatViewModel.logPhotoErrorEvent(messageId, "group-send", e)
                withContext(Dispatchers.Main) {
                    chatViewModel.updateMessageStatusUi(messageId, MessageStatus.ERROR)
                }
            } finally {
                chatViewModel.releaseSendSlot()
            }
        }
    }

    fun sendFileMessage(
        fileBase64: String,
        fileName: String,
        fileSize: Long,
        caption: String = ""
    ) {
        val sendContext = chatViewModel.resolveOutgoingSendContext() ?: return
        if (!chatViewModel.tryAcquireSendSlot()) {
            return
        }

        val messageId = UUID.randomUUID().toString().replace("-", "").take(32)
        val timestamp = System.currentTimeMillis()
        val text = caption.trim()
        val preview = "$fileSize::$fileName"
        val attachmentId = "file_$timestamp"

        chatViewModel.addOutgoingMessageOptimistic(
            ChatMessage(
                id = messageId,
                text = text,
                isOutgoing = true,
                timestamp = Date(timestamp),
                status = MessageStatus.SENDING,
                attachments =
                    listOf(
                        chatViewModel.createFileAttachment(
                            CreateFileAttachmentCommand(
                                attachmentId = attachmentId,
                                preview = preview,
                                blob = fileBase64
                            )
                        )
                    )
            )
        )
        chatViewModel.clearInputText()

        chatViewModel.launchOnIo {
            try {
                runCatching {
                    val appContext = chatViewModel.appContext()
                    val downloadsDir =
                        java.io.File(appContext.filesDir, "rosetta_downloads").apply { mkdirs() }
                    val localFile = java.io.File(downloadsDir, fileName)
                    if (!localFile.exists()) {
                        val base64Data =
                            if (fileBase64.contains(",")) fileBase64.substringAfter(",")
                            else fileBase64
                        val bytes = android.util.Base64.decode(base64Data, android.util.Base64.DEFAULT)
                        localFile.writeBytes(bytes)
                    }
                }

                val encryptionContext =
                    chatViewModel.buildEncryptionContext(
                        plaintext = text,
                        recipient = sendContext.recipient,
                        privateKey = sendContext.privateKey
                    ) ?: throw IllegalStateException("Cannot resolve chat encryption context")
                val privateKeyHash = CryptoManager.generatePrivateKeyHash(sendContext.privateKey)
                val isSavedMessages = (sendContext.sender == sendContext.recipient)
                val uploadResult =
                    chatViewModel.encryptAndUploadAttachment(
                        EncryptAndUploadAttachmentCommand(
                            payload = fileBase64,
                            attachmentPassword = encryptionContext.attachmentPassword,
                            attachmentId = attachmentId,
                            isSavedMessages = isSavedMessages
                        )
                    )

                val fileAttachment =
                    chatViewModel.createFileAttachment(
                        CreateFileAttachmentCommand(
                            attachmentId = attachmentId,
                            preview = preview,
                            blob = "",
                            transportTag = uploadResult.transportTag,
                            transportServer = uploadResult.transportServer
                        )
                    )

                chatViewModel.sendMediaMessage(
                    SendMediaMessageCommand(
                        fromPublicKey = sendContext.sender,
                        toPublicKey = sendContext.recipient,
                        encryptedContent = encryptionContext.encryptedContent,
                        encryptedKey = encryptionContext.encryptedKey,
                        aesChachaKey = encryptionContext.aesChachaKey,
                        privateKeyHash = privateKeyHash,
                        messageId = messageId,
                        timestamp = timestamp,
                        mediaAttachments = listOf(fileAttachment),
                        isSavedMessages = isSavedMessages
                    )
                )

                val attachmentsJson =
                    JSONArray()
                        .apply {
                            put(
                                JSONObject().apply {
                                    put("id", attachmentId)
                                    put("type", AttachmentType.FILE.value)
                                    put("preview", preview)
                                    put("blob", "")
                                    put("transportTag", uploadResult.transportTag)
                                    put("transportServer", uploadResult.transportServer)
                                }
                            )
                        }
                        .toString()

                val storedEncryptedKey =
                    if (encryptionContext.isGroup) {
                        chatViewModel.buildStoredGroupEncryptedKey(
                            encryptionContext.attachmentPassword,
                            sendContext.privateKey
                        )
                    } else {
                        encryptionContext.encryptedKey
                    }

                chatViewModel.saveOutgoingMessage(
                    messageId = messageId,
                    text = text,
                    encryptedContent = encryptionContext.encryptedContent,
                    encryptedKey = storedEncryptedKey,
                    timestamp = timestamp,
                    delivered = if (isSavedMessages) 1 else 0,
                    attachmentsJson = attachmentsJson,
                    accountPublicKey = sendContext.sender,
                    accountPrivateKey = sendContext.privateKey,
                    opponentPublicKey = sendContext.recipient
                )

                withContext(Dispatchers.Main) {
                    if (isSavedMessages) {
                        chatViewModel.updateMessageStatusUi(messageId, MessageStatus.SENT)
                    }
                }

                chatViewModel.saveOutgoingDialog(
                    lastMessage = if (text.isNotEmpty()) text else "file",
                    timestamp = timestamp,
                    accountPublicKey = sendContext.sender,
                    accountPrivateKey = sendContext.privateKey,
                    opponentPublicKey = sendContext.recipient
                )
            } catch (_: Exception) {
                withContext(Dispatchers.Main) {
                    chatViewModel.updateMessageStatusUi(messageId, MessageStatus.ERROR)
                }
                chatViewModel.updateMessageStatusDb(messageId, DeliveryStatus.ERROR.value)
                chatViewModel.saveOutgoingDialog(
                    lastMessage = if (text.isNotEmpty()) text else "file",
                    timestamp = timestamp,
                    accountPublicKey = sendContext.sender,
                    accountPrivateKey = sendContext.privateKey,
                    opponentPublicKey = sendContext.recipient
                )
            } finally {
                chatViewModel.releaseSendSlot()
            }
        }
    }

    fun sendVideoCircleFromUri(videoUri: Uri) {
        val sendContext = chatViewModel.resolveOutgoingSendContext() ?: return
        if (!chatViewModel.tryAcquireSendSlot()) {
            return
        }

        val fileSize = chatViewModel.resolveFileSizeForUri(videoUri)
        if (fileSize > 0L && fileSize > chatViewModel.maxMediaBytes()) {
            chatViewModel.releaseSendSlot()
            return
        }

        val messageId = UUID.randomUUID().toString().replace("-", "").take(32)
        val timestamp = System.currentTimeMillis()
        val attachmentId = "video_circle_$timestamp"
        val meta =
            resolveVideoCircleMetaUseCase(
                ResolveVideoCircleMetaCommand(
                    context = chatViewModel.appContext(),
                    videoUri = videoUri
                )
            )
        val preview = "${meta.durationSec}::${meta.mimeType}"

        chatViewModel.addOutgoingMessageOptimistic(
            ChatMessage(
                id = messageId,
                text = "",
                isOutgoing = true,
                timestamp = Date(timestamp),
                status = MessageStatus.SENDING,
                attachments =
                    listOf(
                        chatViewModel.createVideoCircleAttachment(
                            CreateVideoCircleAttachmentCommand(
                                attachmentId = attachmentId,
                                preview = preview,
                                width = meta.width,
                                height = meta.height,
                                blob = "",
                                localUri = videoUri.toString()
                            )
                        )
                    )
            )
        )
        chatViewModel.clearInputText()

        chatViewModel.launchBackgroundUpload upload@{
            try {
                val optimisticAttachmentsJson =
                    JSONArray()
                        .apply {
                            put(
                                JSONObject().apply {
                                    put("id", attachmentId)
                                    put("type", AttachmentType.VIDEO_CIRCLE.value)
                                    put("preview", preview)
                                    put("blob", "")
                                    put("width", meta.width)
                                    put("height", meta.height)
                                    put("localUri", videoUri.toString())
                                }
                            )
                        }
                        .toString()

                chatViewModel.saveOutgoingMessage(
                    messageId = messageId,
                    text = "",
                    encryptedContent = "",
                    encryptedKey = "",
                    timestamp = timestamp,
                    delivered = 0,
                    attachmentsJson = optimisticAttachmentsJson,
                    accountPublicKey = sendContext.sender,
                    accountPrivateKey = sendContext.privateKey,
                    opponentPublicKey = sendContext.recipient
                )
                chatViewModel.saveOutgoingDialog(
                    lastMessage = "Video message",
                    timestamp = timestamp,
                    accountPublicKey = sendContext.sender,
                    accountPrivateKey = sendContext.privateKey,
                    opponentPublicKey = sendContext.recipient
                )
            } catch (_: Exception) {
            }

            try {
                val videoHex =
                    encodeVideoUriToHexUseCase(
                        EncodeVideoUriToHexCommand(
                            context = chatViewModel.appContext(),
                            videoUri = videoUri
                        )
                    )
                if (videoHex.isNullOrBlank()) {
                    withContext(Dispatchers.Main) {
                        chatViewModel.updateMessageStatusUi(messageId, MessageStatus.ERROR)
                    }
                    return@upload
                }

                chatViewModel.sendVideoCircleMessageInternal(
                    messageId = messageId,
                    attachmentId = attachmentId,
                    timestamp = timestamp,
                    videoHex = videoHex,
                    preview = preview,
                    width = meta.width,
                    height = meta.height,
                    recipient = sendContext.recipient,
                    sender = sendContext.sender,
                    privateKey = sendContext.privateKey
                )
            } catch (_: Exception) {
                withContext(Dispatchers.Main) {
                    chatViewModel.updateMessageStatusUi(messageId, MessageStatus.ERROR)
                }
                chatViewModel.updateMessageStatusDb(messageId, DeliveryStatus.ERROR.value)
            } finally {
                chatViewModel.releaseSendSlot()
            }
        }
    }

    fun sendAvatarMessage() {
        val sendContext = chatViewModel.resolveOutgoingSendContext() ?: return
        if (!chatViewModel.tryAcquireSendSlot()) {
            return
        }

        val messageId = UUID.randomUUID().toString().replace("-", "").take(32)
        val timestamp = System.currentTimeMillis()
        val avatarAttachmentId = "avatar_$timestamp"

        chatViewModel.launchOnIo sendAvatar@{
            try {
                val avatarDao = RosettaDatabase.getDatabase(chatViewModel.appContext()).avatarDao()
                val myAvatar = avatarDao.getLatestAvatar(sendContext.sender)
                if (myAvatar == null) {
                    withContext(Dispatchers.Main) {
                        android.widget.Toast.makeText(
                            chatViewModel.appContext(),
                            "No avatar to send",
                            android.widget.Toast.LENGTH_SHORT
                        ).show()
                    }
                    return@sendAvatar
                }

                val avatarBlob = AvatarFileManager.readAvatar(chatViewModel.appContext(), myAvatar.avatar)
                if (avatarBlob.isNullOrEmpty()) {
                    withContext(Dispatchers.Main) {
                        android.widget.Toast.makeText(
                            chatViewModel.appContext(),
                            "Failed to read avatar",
                            android.widget.Toast.LENGTH_SHORT
                        ).show()
                    }
                    return@sendAvatar
                }

                val avatarDataUrl =
                    if (avatarBlob.startsWith("data:image")) {
                        avatarBlob
                    } else {
                        "data:image/png;base64,$avatarBlob"
                    }

                val avatarBlurhash =
                    runCatching {
                        val cleanBase64 =
                            if (avatarBlob.contains(",")) avatarBlob.substringAfter(",") else avatarBlob
                        val bytes = android.util.Base64.decode(cleanBase64, android.util.Base64.DEFAULT)
                        val bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
                        if (bitmap != null) {
                            MediaUtils.generateBlurhashFromBitmap(bitmap)
                        } else {
                            ""
                        }
                    }.getOrDefault("")

                withContext(Dispatchers.Main) {
                    chatViewModel.addOutgoingMessageOptimistic(
                        ChatMessage(
                            id = messageId,
                            text = "",
                            isOutgoing = true,
                            timestamp = Date(timestamp),
                            status = MessageStatus.SENDING,
                            attachments =
                                listOf(
                                    chatViewModel.createAvatarAttachment(
                                        CreateAvatarAttachmentCommand(
                                            attachmentId = avatarAttachmentId,
                                            preview = avatarBlurhash,
                                            blob = avatarBlob
                                        )
                                    )
                                )
                        )
                    )
                }

                val encryptionContext =
                    chatViewModel.buildEncryptionContext(
                        plaintext = "",
                        recipient = sendContext.recipient,
                        privateKey = sendContext.privateKey
                    ) ?: throw IllegalStateException("Cannot resolve chat encryption context")
                val privateKeyHash = CryptoManager.generatePrivateKeyHash(sendContext.privateKey)
                val isSavedMessages = (sendContext.sender == sendContext.recipient)
                val uploadResult =
                    chatViewModel.encryptAndUploadAttachment(
                        EncryptAndUploadAttachmentCommand(
                            payload = avatarDataUrl,
                            attachmentPassword = encryptionContext.attachmentPassword,
                            attachmentId = avatarAttachmentId,
                            isSavedMessages = isSavedMessages
                        )
                    )

                val avatarAttachment =
                    chatViewModel.createAvatarAttachment(
                        CreateAvatarAttachmentCommand(
                            attachmentId = avatarAttachmentId,
                            preview = avatarBlurhash,
                            blob = "",
                            transportTag = uploadResult.transportTag,
                            transportServer = uploadResult.transportServer
                        )
                    )

                chatViewModel.sendMediaMessage(
                    SendMediaMessageCommand(
                        fromPublicKey = sendContext.sender,
                        toPublicKey = sendContext.recipient,
                        encryptedContent = encryptionContext.encryptedContent,
                        encryptedKey = encryptionContext.encryptedKey,
                        aesChachaKey = encryptionContext.aesChachaKey,
                        privateKeyHash = privateKeyHash,
                        messageId = messageId,
                        timestamp = timestamp,
                        mediaAttachments = listOf(avatarAttachment),
                        isSavedMessages = isSavedMessages
                    )
                )

                AttachmentFileManager.saveAttachment(
                    context = chatViewModel.appContext(),
                    blob = avatarBlob,
                    attachmentId = avatarAttachmentId,
                    publicKey = sendContext.sender,
                    privateKey = sendContext.privateKey
                )

                val attachmentsJson =
                    JSONArray()
                        .apply {
                            put(
                                JSONObject().apply {
                                    put("id", avatarAttachmentId)
                                    put("type", AttachmentType.AVATAR.value)
                                    put("preview", avatarBlurhash)
                                    put("blob", "")
                                    put("transportTag", uploadResult.transportTag)
                                    put("transportServer", uploadResult.transportServer)
                                }
                            )
                        }
                        .toString()

                val storedEncryptedKey =
                    if (encryptionContext.isGroup) {
                        chatViewModel.buildStoredGroupEncryptedKey(
                            encryptionContext.attachmentPassword,
                            sendContext.privateKey
                        )
                    } else {
                        encryptionContext.encryptedKey
                    }

                chatViewModel.saveOutgoingMessage(
                    messageId = messageId,
                    text = "",
                    encryptedContent = encryptionContext.encryptedContent,
                    encryptedKey = storedEncryptedKey,
                    timestamp = timestamp,
                    delivered = if (isSavedMessages) 1 else 0,
                    attachmentsJson = attachmentsJson,
                    accountPublicKey = sendContext.sender,
                    accountPrivateKey = sendContext.privateKey,
                    opponentPublicKey = sendContext.recipient
                )

                withContext(Dispatchers.Main) {
                    if (isSavedMessages) {
                        chatViewModel.updateMessageStatusUi(messageId, MessageStatus.SENT)
                    }
                }

                chatViewModel.saveOutgoingDialog(
                    lastMessage = "\$a=Avatar",
                    timestamp = timestamp,
                    accountPublicKey = sendContext.sender,
                    accountPrivateKey = sendContext.privateKey,
                    opponentPublicKey = sendContext.recipient
                )
            } catch (e: Exception) {
                withContext(Dispatchers.Main) {
                    chatViewModel.updateMessageStatusUi(messageId, MessageStatus.ERROR)
                    android.widget.Toast.makeText(
                        chatViewModel.appContext(),
                        "Failed to send avatar: ${e.message}",
                        android.widget.Toast.LENGTH_SHORT
                    ).show()
                }
                chatViewModel.updateMessageStatusDb(messageId, DeliveryStatus.ERROR.value)
                chatViewModel.saveOutgoingDialog(
                    lastMessage = "\$a=Avatar",
                    timestamp = timestamp,
                    accountPublicKey = sendContext.sender,
                    accountPrivateKey = sendContext.privateKey,
                    opponentPublicKey = sendContext.recipient
                )
            } finally {
                chatViewModel.releaseSendSlot()
            }
        }
    }
}
