package com.rosetta.messenger.utils

import android.util.Log
import com.rosetta.messenger.network.ProtocolRuntimeAccess

/**
 * Утилита для логирования сообщений
 * Безопасна для release сборки - логи не выводятся в production
 * 
 * Логи отображаются:
 * 1. В Logcat (всегда в debug)
 * 2. В Debug Logs внутри чата (через ProtocolRuntimeAccess.get().debugLogs)
 */
object MessageLogger {
    private const val TAG = "RosettaMsg"

    @Volatile
    private var isEnabled: Boolean = false

    fun setEnabled(enabled: Boolean) {
        isEnabled = enabled
    }
    
    /**
     * Добавить лог в UI (Debug Logs в чате)
     */
    private fun addToUI(message: String) {
        ProtocolRuntimeAccess.get().addLog(message)
    }
    
    /**
     * Логирование отправки сообщения
     */
    fun logSendStart(
        messageId: String,
        toPublicKey: String,
        textLength: Int,
        attachmentsCount: Int,
        isSavedMessages: Boolean,
        replyToMessageId: String?
    ) {
        if (!isEnabled) return
        val shortId = messageId.take(8)
        val shortKey = toPublicKey.take(12)
        val replyStr = replyToMessageId?.take(8) ?: "-"
        val msg = "📤 SEND | id:$shortId to:$shortKey len:$textLength att:$attachmentsCount saved:$isSavedMessages reply:$replyStr"
        Log.d(TAG, msg)
        addToUI(msg)
    }
    
    /**
     * Логирование успешного шифрования
     */
    fun logEncryptionSuccess(
        messageId: String,
        encryptedContentLength: Int,
        encryptedKeyLength: Int
    ) {
        if (!isEnabled) return
        val shortId = messageId.take(8)
        val msg = "🔐 ENCRYPT | id:$shortId content:${encryptedContentLength}b key:${encryptedKeyLength}b"
        Log.d(TAG, msg)
        addToUI(msg)
    }
    
    /**
     * Логирование сохранения в БД
     */
    fun logDbSave(
        messageId: String,
        dialogKey: String,
        isNew: Boolean
    ) {
        if (!isEnabled) return
        val shortId = messageId.take(8)
        val shortDialog = dialogKey.take(12)
        val msg = "💾 DB | id:$shortId dialog:$shortDialog new:$isNew"
        Log.d(TAG, msg)
        addToUI(msg)
    }
    
    /**
     * Логирование отправки пакета на сервер
     */
    fun logPacketSend(
        messageId: String,
        toPublicKey: String,
        timestamp: Long
    ) {
        if (!isEnabled) return
        val shortId = messageId.take(8)
        val shortKey = toPublicKey.take(12)
        val msg = "📡 PACKET→ | id:$shortId to:$shortKey ts:$timestamp"
        Log.d(TAG, msg)
        addToUI(msg)
    }
    
    /**
     * Логирование успешной отправки
     */
    fun logSendSuccess(messageId: String, duration: Long) {
        if (!isEnabled) return
        val shortId = messageId.take(8)
        val msg = "✅ SENT | id:$shortId time:${duration}ms"
        Log.d(TAG, msg)
        addToUI(msg)
    }
    
    /**
     * Логирование ошибки отправки
     */
    fun logSendError(messageId: String, error: Throwable) {
        if (!isEnabled) return
        val shortId = messageId.take(8)
        val errMsg = error.message?.take(50) ?: "unknown"
        val msg = "❌ SEND ERR | id:$shortId err:$errMsg"
        Log.e(TAG, msg, error)
        addToUI(msg)
    }
    
    /**
     * Логирование входящего сообщения
     */
    fun logReceiveStart(
        messageId: String,
        fromPublicKey: String,
        toPublicKey: String,
        contentLength: Int,
        attachmentsCount: Int,
        timestamp: Long
    ) {
        if (!isEnabled) return
        val shortId = messageId.take(8)
        val shortFrom = fromPublicKey.take(12)
        val shortTo = toPublicKey.take(12)
        val msg = "📥 RECV | id:$shortId from:$shortFrom to:$shortTo len:${contentLength}b att:$attachmentsCount ts:$timestamp"
        Log.d(TAG, msg)
        addToUI(msg)
    }
    
    /**
     * Логирование проверки на дубликат
     */
    fun logDuplicateCheck(messageId: String, isDuplicate: Boolean) {
        if (!isEnabled) return
        val shortId = messageId.take(8)
        val status = if (isDuplicate) "⚠️DUP" else "✓NEW"
        val msg = "🔍 CHECK | id:$shortId $status"
        Log.d(TAG, msg)
        addToUI(msg)
    }
    
    /**
     * Логирование блокировки отправителя
     */
    fun logBlockedSender(fromPublicKey: String) {
        if (!isEnabled) return
        val shortKey = fromPublicKey.take(12)
        val msg = "🚫 BLOCKED | from:$shortKey"
        Log.d(TAG, msg)
        addToUI(msg)
    }
    
    /**
     * Логирование успешной расшифровки
     */
    fun logDecryptionSuccess(
        messageId: String,
        plainTextLength: Int,
        attachmentsCount: Int
    ) {
        if (!isEnabled) return
        val shortId = messageId.take(8)
        val msg = "🔓 DECRYPT | id:$shortId text:${plainTextLength}c att:$attachmentsCount"
        Log.d(TAG, msg)
        addToUI(msg)
    }
    
    /**
     * Логирование ошибки расшифровки
     */
    fun logDecryptionError(messageId: String, error: Throwable) {
        if (!isEnabled) return
        val shortId = messageId.take(8)
        val errMsg = error.message?.take(50) ?: "unknown"
        val msg = "❌ DECRYPT ERR | id:$shortId err:$errMsg"
        Log.e(TAG, msg, error)
        addToUI(msg)
    }
    
    /**
     * Логирование успешного получения
     */
    fun logReceiveSuccess(messageId: String, duration: Long) {
        if (!isEnabled) return
        val shortId = messageId.take(8)
        val msg = "✅ RECEIVED | id:$shortId time:${duration}ms"
        Log.d(TAG, msg)
        addToUI(msg)
    }
    
    /**
     * Логирование обновления статуса доставки
     */
    fun logDeliveryStatus(
        messageId: String,
        toPublicKey: String,
        status: String
    ) {
        if (!isEnabled) return
        val shortId = messageId.take(8)
        val shortKey = toPublicKey.take(12)
        val msg = "📬 DELIVERY | id:$shortId to:$shortKey status:$status"
        Log.d(TAG, msg)
        addToUI(msg)
    }
    
    /**
     * Логирование прочтения сообщений
     */
    fun logReadStatus(
        fromPublicKey: String,
        messagesCount: Int
    ) {
        if (!isEnabled) return
        val shortKey = fromPublicKey.take(12)
        val msg = "👁 READ | from:$shortKey count:$messagesCount"
        Log.d(TAG, msg)
        addToUI(msg)
    }
    
    /**
     * Логирование обновления диалога
     */
    fun logDialogUpdate(
        dialogKey: String,
        lastMessage: String?,
        unreadCount: Int
    ) {
        if (!isEnabled) return
        val shortDialog = dialogKey.take(12)
        val shortMsg = lastMessage?.take(20) ?: "-"
        val msg = "📋 DIALOG | key:$shortDialog last:\"$shortMsg\" unread:$unreadCount"
        Log.d(TAG, msg)
        addToUI(msg)
    }
    
    /**
     * Логирование обновления кэша
     */
    fun logCacheUpdate(dialogKey: String, totalMessages: Int) {
        if (!isEnabled) return
        val shortDialog = dialogKey.take(12)
        val msg = "🗃 CACHE | dialog:$shortDialog total:$totalMessages"
        Log.d(TAG, msg)
        addToUI(msg)
    }
    
    /**
     * Логирование расшифровки фото (inline blob)
     */
    fun logPhotoDecryptStart(
        messageId: String,
        attachmentId: String,
        blobSize: Int
    ) {
        if (!isEnabled) return
        val shortMsgId = messageId.take(8)
        val shortAttId = attachmentId.take(8)
        val msg = "🖼️ PHOTO DECRYPT | msg:$shortMsgId att:$shortAttId blob:${blobSize}b"
        Log.d(TAG, msg)
        addToUI(msg)
    }

    /**
     * Логирование успешной расшифровки фото
     */
    fun logPhotoDecryptSuccess(
        messageId: String,
        attachmentId: String,
        saved: Boolean
    ) {
        if (!isEnabled) return
        val shortMsgId = messageId.take(8)
        val shortAttId = attachmentId.take(8)
        val msg = "✅ PHOTO OK | msg:$shortMsgId att:$shortAttId saved:$saved"
        Log.d(TAG, msg)
        addToUI(msg)
    }

    /**
     * Логирование ошибки расшифровки фото (blob null)
     */
    fun logPhotoDecryptFailed(
        messageId: String,
        attachmentId: String
    ) {
        if (!isEnabled) return
        val shortMsgId = messageId.take(8)
        val shortAttId = attachmentId.take(8)
        val msg = "❌ PHOTO DECRYPT FAIL | msg:$shortMsgId att:$shortAttId (decryptedBlob=null)"
        Log.e(TAG, msg)
        addToUI(msg)
    }

    /**
     * Логирование ошибки сохранения фото
     */
    fun logPhotoSaveFailed(
        messageId: String,
        attachmentId: String
    ) {
        if (!isEnabled) return
        val shortMsgId = messageId.take(8)
        val shortAttId = attachmentId.take(8)
        val msg = "⚠️ PHOTO SAVE FAIL | msg:$shortMsgId att:$shortAttId"
        Log.e(TAG, msg)
        addToUI(msg)
    }

    /**
     * Логирование исключения при расшифровке фото
     */
    fun logPhotoDecryptError(
        messageId: String,
        attachmentId: String,
        error: Throwable
    ) {
        if (!isEnabled) return
        val shortMsgId = messageId.take(8)
        val shortAttId = attachmentId.take(8)
        val errMsg = error.message?.take(80) ?: "unknown"
        val msg = "❌ PHOTO ERR | msg:$shortMsgId att:$shortAttId err:$errMsg"
        Log.e(TAG, msg, error)
        addToUI(msg)
    }

    /**
     * Логирование CDN загрузки фото
     */
    fun logPhotoCdnDownload(message: String) {
        if (!isEnabled) return
        val msg = "🖼️ $message"
        Log.d(TAG, msg)
        addToUI(msg)
    }

    /**
     * Логирование успешной отправки read receipt
     */
    fun logReadReceiptSent(opponentKey: String, retry: Boolean = false) {
        if (!isEnabled) return
        val shortKey = opponentKey.take(12)
        val retryStr = if (retry) " (retry)" else ""
        val msg = "👁 READ RECEIPT SENT$retryStr | to:$shortKey"
        Log.d(TAG, msg)
        addToUI(msg)
    }

    /**
     * Логирование ошибки отправки read receipt
     */
    fun logReadReceiptFailed(opponentKey: String, error: Throwable, retry: Boolean = false) {
        if (!isEnabled) return
        val shortKey = opponentKey.take(12)
        val errMsg = error.message?.take(50) ?: "unknown"
        val retryStr = if (retry) " (retry)" else ""
        val msg = "❌ READ RECEIPT FAIL$retryStr | to:$shortKey err:$errMsg"
        Log.e(TAG, msg, error)
        addToUI(msg)
    }

    /**
     * Общий debug лог
     */
    fun debug(message: String) {
        if (!isEnabled) return
        Log.d(TAG, message)
        addToUI(message)
    }
    
    /**
     * Общий error лог
     */
    fun error(message: String, error: Throwable? = null) {
        if (!isEnabled) return
        if (error != null) {
            Log.e(TAG, message, error)
        } else {
            Log.e(TAG, message)
        }
        addToUI("❌ $message")
    }
}
