package com.rosetta.messenger.ui.components

import android.content.Context
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import coil.imageLoader
import coil.request.ImageRequest
import kotlinx.coroutines.*

/**
 * 🚀 Оптимизированный кэш эмодзи с предзагрузкой
 * 
 * Особенности:
 * - Асинхронная загрузка списка эмодзи
 * - Предзагрузка первых N изображений в память
 * - Группировка по категориям в фоне
 * - Прогрессивная загрузка (сначала популярные)
 */
object OptimizedEmojiCache {
    private var allEmojis: List<String>? = null
    private var emojisByCategory: Map<String, List<String>>? = null
    private var preloadedCount = 0
    
    var isLoaded by mutableStateOf(false)
        private set
    
    var isPreloading by mutableStateOf(false)
        private set
    
    var loadProgress by mutableStateOf(0f)
        private set
    
    private const val PRELOAD_COUNT = 200 // Предзагружаем первые 200 эмодзи
    private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
    
    /**
     * Предзагрузка при старте приложения
     * Вызывать из MainActivity.onCreate()
     */
    fun preload(context: Context) {
        if (allEmojis != null) {
            isLoaded = true
            return
        }
        
        scope.launch {
            try {
                // Шаг 1: Загружаем список эмодзи (быстро)
                loadEmojiList(context)
                loadProgress = 0.3f

                // Шаг 2: Группируем по категориям (средне)
                groupEmojisByCategories()
                loadProgress = 0.6f

                // 🔥 Сразу отмечаем как загруженный - предзагрузка идёт в фоне
                isLoaded = true

                // Шаг 3: Предзагружаем популярные изображения (в фоне, не блокирует UI)
                preloadPopularEmojis(context)
                loadProgress = 1f
                isPreloading = false
            } catch (e: Exception) {
                allEmojis = emptyList()
                emojisByCategory = emptyMap()
                isLoaded = true
                isPreloading = false
            }
        }
    }
    
    /**
     * Шаг 1: Загружаем список эмодзи из assets
     */
    private suspend fun loadEmojiList(context: Context) = withContext(Dispatchers.IO) {
        val emojis = context.assets.list("emoji")
            ?.filter { it.endsWith(".png") }
            ?.map { it.removeSuffix(".png") }
            ?.sorted()
            ?: emptyList()
        
        allEmojis = emojis
    }
    
    /**
     * Шаг 2: Группируем эмодзи по категориям
     */
    private suspend fun groupEmojisByCategories() = withContext(Dispatchers.Default) {
        val emojis = allEmojis ?: return@withContext
        
        // Инициализируем пустые списки для всех категорий
        val result = EMOJI_CATEGORIES.associate { it.key to mutableListOf<String>() }
        
        // Один проход по всем эмодзи
        for (emoji in emojis) {
            var assigned = false
            for (category in EMOJI_CATEGORIES) {
                if (emojiMatchesCategory(emoji, category)) {
                    result[category.key]?.add(emoji)
                    assigned = true
                    break
                }
            }
            // Нераспределенные → Symbols
            if (!assigned) {
                result["Symbols"]?.add(emoji)
            }
        }
        
        // Сортируем каждую категорию по Unicode порядку
        emojisByCategory = result.mapValues { (key, emojis) ->
            val category = EMOJI_CATEGORIES.find { it.key == key }
            if (category != null && emojis.size > 1) {
                emojis.sortedWith { a, b ->
                    getEmojiSortIndex(a, category).compareTo(getEmojiSortIndex(b, category))
                }
            } else {
                emojis
            }
        }
        
    }
    
    /**
     * Шаг 3: Предзагружаем популярные эмодзи в память
     */
    private suspend fun preloadPopularEmojis(context: Context) = withContext(Dispatchers.IO) {
        isPreloading = true
        
        // Берем первые N эмодзи из категории Smileys (самые популярные)
        val smileysToPreload = emojisByCategory?.get("Smileys")
            ?.take(PRELOAD_COUNT)
            ?: emptyList()
        
        
        // Предзагружаем параллельно, но с ограничением
        val jobs = smileysToPreload.chunked(20).map { chunk ->
            async {
                chunk.forEach { unified ->
                    try {
                        val request = ImageRequest.Builder(context)
                            .data("file:///android_asset/emoji/${unified.lowercase()}.png")
                            .size(64) // Small size for cache
                            .memoryCacheKey("emoji_$unified")
                            .diskCacheKey("emoji_$unified")
                            .build()
                        
                        context.imageLoader.execute(request)
                        preloadedCount++
                    } catch (e: Exception) {
                        // Ignore individual failures
                    }
                }
            }
        }
        
        jobs.awaitAll()
        isPreloading = false
    }
    
    /**
     * Получить эмодзи для категории
     */
    fun getEmojisForCategory(categoryKey: String): List<String> {
        return emojisByCategory?.get(categoryKey) ?: emptyList()
    }
    
    /**
     * Получить все эмодзи
     */
    fun getAllEmojis(): List<String> {
        return allEmojis ?: emptyList()
    }
    
    /**
     * Проверка загрузки
     */
    fun isEmojiLoaded(): Boolean = isLoaded
    
    /**
     * Очистка кэша (для тестирования)
     */
    fun clear() {
        scope.cancel()
        allEmojis = null
        emojisByCategory = null
        preloadedCount = 0
        isLoaded = false
        isPreloading = false
        loadProgress = 0f
    }
    
    // ==================== HELPER FUNCTIONS ====================
    
    /**
     * Проверяет, попадает ли emoji в диапазон категории
     */
    private fun emojiMatchesCategory(emoji: String, category: EmojiCategory): Boolean {
        val unified = emoji.lowercase().split("-").firstOrNull() ?: return false
        val codePoint = try { 
            unified.toInt(16) 
        } catch (e: Exception) { 
            return false 
        }
        return category.ranges.any { (start, end) -> codePoint in start..end }
    }
    
    /**
     * Получает индекс emoji согласно Unicode порядку
     */
    private fun getEmojiSortIndex(emoji: String, category: EmojiCategory): Int {
        val unified = emoji.lowercase().split("-").firstOrNull() ?: return Int.MAX_VALUE
        val codePoint = try { 
            unified.toInt(16) 
        } catch (e: Exception) { 
            return Int.MAX_VALUE 
        }
        
        for ((rangeIndex, range) in category.ranges.withIndex()) {
            val (start, end) = range
            if (codePoint in start..end) {
                return rangeIndex * 100000 + (codePoint - start)
            }
        }
        return Int.MAX_VALUE
    }
}
