package com.rosetta.messenger.ui.components

import android.graphics.Bitmap
import android.util.Base64
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.ui.graphics.Shape
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.rosetta.messenger.R
import com.rosetta.messenger.data.MessageRepository
import com.rosetta.messenger.repository.AvatarRepository
import com.rosetta.messenger.ui.chats.AvatarColors
import com.rosetta.messenger.ui.chats.getAvatarColor
import com.rosetta.messenger.ui.chats.getAvatarText
import com.rosetta.messenger.ui.chats.getInitials
import com.rosetta.messenger.utils.AvatarFileManager
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

/**
 * LRU-кэш декодированных Bitmap аватаров (макс. 100 записей, ~11 MB)
 */
private object AvatarBitmapCache {
    private val cache = object : LinkedHashMap<String, Bitmap>(50, 0.75f, true) {
        override fun removeEldestEntry(eldest: MutableMap.MutableEntry<String, Bitmap>?): Boolean {
            return size > 100
        }
    }

    fun get(key: String): Bitmap? = synchronized(cache) { cache[key] }
    fun put(key: String, bitmap: Bitmap) = synchronized(cache) { cache[key] = bitmap }
}

/**
 * Composable для отображения аватара пользователя
 * Совместимо с desktop версией (AvatarProvider)
 * 
 * Приоритет отображения:
 * 1. Реальный аватар из AvatarRepository (если есть)
 * 2. Цветной placeholder с инициалами (fallback)
 * 
 * @param publicKey Публичный ключ пользователя
 * @param avatarRepository Репозиторий аватаров
 * @param size Размер аватара
 * @param isDarkTheme Темная тема
 * @param onClick Обработчик клика (опционально)
 * @param showOnlineIndicator Показывать индикатор онлайн
 * @param isOnline Пользователь онлайн
 * @param shape Форма аватара (по умолчанию круг)
 */
@Composable
fun AvatarImage(
    publicKey: String,
    avatarRepository: AvatarRepository?,
    size: Dp = 40.dp,
    isDarkTheme: Boolean,
    onClick: (() -> Unit)? = null,
    showOnlineIndicator: Boolean = false,
    isOnline: Boolean = false,
    shape: Shape = CircleShape,
    displayName: String? = null,  // 🔥 Имя для инициалов (title/username)
    enableBlurPrewarm: Boolean = false
) {
    val context = LocalContext.current
    val isSystemSafeAccount = publicKey == MessageRepository.SYSTEM_SAFE_PUBLIC_KEY
    val isSystemUpdatesAccount = publicKey == MessageRepository.SYSTEM_UPDATES_PUBLIC_KEY

    // Получаем аватары из репозитория
    val avatars by avatarRepository?.getAvatars(publicKey, allDecode = false)?.collectAsState() 
        ?: remember { mutableStateOf(emptyList()) }
    
    // 🔥 FIX: Используем стабильный ключ (timestamp первого аватара) вместо reference списка
    // Это предотвращает сброс bitmap при recomposition когда данные не изменились
    val avatarKey = remember(avatars) { 
        avatars.firstOrNull()?.timestamp ?: 0L 
    }
    
    // 🔥 FIX: Состояние для bitmap - НЕ сбрасываем при изменении ключа
    // Показываем предыдущий bitmap пока грузится новый (double buffering)
    var bitmap by remember { mutableStateOf<Bitmap?>(null) }
    
    // 🔥 FIX: Декодируем только когда avatarKey (timestamp) реально изменился
    // Сбрасываем bitmap в null ТОЛЬКО когда аватар удалён (avatars пустой)
    LaunchedEffect(avatarKey, avatars.isEmpty()) {
        val currentAvatars = avatars
        if (currentAvatars.isNotEmpty()) {
            val cacheKey = "${publicKey}_${avatarKey}"
            val cachedBitmap = AvatarBitmapCache.get(cacheKey)
            if (cachedBitmap != null) {
                bitmap = cachedBitmap
            } else {
                val newBitmap = withContext(Dispatchers.IO) {
                    AvatarFileManager.base64ToBitmap(currentAvatars.first().base64Data)
                }
                if (newBitmap != null) {
                    AvatarBitmapCache.put(cacheKey, newBitmap)
                    bitmap = newBitmap
                }
            }
        } else {
            bitmap = null
        }
    }

    LaunchedEffect(enableBlurPrewarm, publicKey, avatarKey, bitmap) {
        if (!enableBlurPrewarm) return@LaunchedEffect
        val source = bitmap ?: return@LaunchedEffect
        prewarmBlurredAvatarFromBitmap(
            context = context,
            publicKey = publicKey,
            avatarTimestamp = avatarKey,
            sourceBitmap = source,
            blurRadius = 20f
        )
    }
    
    Box(
        modifier = Modifier
            .size(size)
            .clip(shape)
            .then(
                if (onClick != null) {
                    Modifier.clickable(onClick = onClick)
                } else {
                    Modifier
                }
            ),
        contentAlignment = Alignment.Center
    ) {
        // Log what we're showing
        LaunchedEffect(bitmap) {
        }
        
        if (isSystemSafeAccount) {
            Image(
                painter = painterResource(id = R.drawable.safe_account),
                contentDescription = "Safe avatar",
                modifier = Modifier.fillMaxSize(),
                contentScale = ContentScale.Crop
            )
        } else if (isSystemUpdatesAccount) {
            Image(
                painter = painterResource(id = R.drawable.updates_account),
                contentDescription = "Rosetta Updates avatar",
                modifier = Modifier.fillMaxSize(),
                contentScale = ContentScale.Crop
            )
        } else if (bitmap != null) {
            // Отображаем реальный аватар
            Image(
                bitmap = bitmap!!.asImageBitmap(),
                contentDescription = "Avatar",
                modifier = Modifier.fillMaxSize(),
                contentScale = ContentScale.Crop
            )
        } else {
            // Fallback: цветной placeholder
            AvatarPlaceholder(
                publicKey = publicKey,
                size = size,
                isDarkTheme = isDarkTheme,
                shape = shape,
                displayName = displayName
            )
        }
        
        // Индикатор онлайн
        if (showOnlineIndicator && isOnline) {
            OnlineIndicator(
                modifier = Modifier
                    .align(Alignment.BottomEnd)
                    .size(size / 4)
            )
        }
    }
}

/**
 * Цветной placeholder аватара с инициалами
 * (используется как fallback если нет реального аватара)
 */
@Composable
fun AvatarPlaceholder(
    publicKey: String,
    size: Dp = 40.dp,
    isDarkTheme: Boolean,
    fontSize: TextUnit? = null,
    shape: Shape = CircleShape,
    displayName: String? = null  // 🔥 Имя для инициалов
) {
    val avatarColors = getAvatarColor(publicKey, isDarkTheme)
    // 🔥 Используем displayName для инициалов, если оно есть
    val avatarText = if (!displayName.isNullOrEmpty() && displayName != publicKey && !displayName.startsWith(publicKey.take(7))) {
        getInitials(displayName)
    } else {
        getAvatarText(publicKey)
    }
    val resolvedFontSize = fontSize ?: (size.value / 2.5).sp
    
    Box(
        modifier = Modifier
            .size(size)
            .clip(shape)
            .background(avatarColors.backgroundColor),
        contentAlignment = Alignment.Center
    ) {
        if (containsEmojiAvatarText(avatarText)) {
            AppleEmojiText(
                text = avatarText,
                color = avatarColors.textColor,
                fontSize = resolvedFontSize,
                fontWeight = FontWeight.Medium,
                maxLines = 1,
                overflow = android.text.TextUtils.TruncateAt.END,
                enableLinks = false
            )
        } else {
            Text(
                text = avatarText,
                color = avatarColors.textColor,
                fontSize = resolvedFontSize,
                fontWeight = FontWeight.Medium,
                maxLines = 1
            )
        }
    }
}

private fun containsEmojiAvatarText(text: String): Boolean {
    if (text.contains(":emoji_", ignoreCase = true)) return true
    return text.any { ch ->
        val type = java.lang.Character.getType(ch.code)
        type == java.lang.Character.SURROGATE.toInt() ||
            type == java.lang.Character.OTHER_SYMBOL.toInt()
    }
}

/**
 * Индикатор онлайн статуса
 */
@Composable
private fun OnlineIndicator(modifier: Modifier = Modifier) {
    Box(
        modifier = modifier
            .clip(CircleShape)
            .background(Color(0xFF4CAF50))
    )
}

/**
 * Composable для выбора аватара (Image Picker)
 * Использует Android intent для выбора изображения
 */
@Composable
fun AvatarPicker(
    @Suppress("UNUSED_PARAMETER") onAvatarSelected: (String) -> Unit
) {
    // TODO: Реализовать выбор изображения через ActivityResultContract
    // 1. Использовать rememberLauncherForActivityResult с ActivityResultContracts.GetContent()
    // 2. Конвертировать URI в ByteArray
    // 3. Использовать AvatarFileManager.imagePrepareForNetworkTransfer()
    // 4. Вызвать onAvatarSelected с Base64 PNG
}
