package com.rosetta.messenger.ui.chats

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.rosetta.messenger.network.PacketSearch
import com.rosetta.messenger.network.ProtocolManager
import com.rosetta.messenger.network.SearchUser
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch

/**
 * ViewModel для поиска пользователей через протокол
 * Работает аналогично SearchBar в React Native приложении
 */
class SearchUsersViewModel : ViewModel() {
    
    // Состояние поиска
    private val _searchQuery = MutableStateFlow("")
    val searchQuery: StateFlow<String> = _searchQuery.asStateFlow()
    
    private val _searchResults = MutableStateFlow<List<SearchUser>>(emptyList())
    val searchResults: StateFlow<List<SearchUser>> = _searchResults.asStateFlow()
    
    private val _isSearching = MutableStateFlow(false)
    val isSearching: StateFlow<Boolean> = _isSearching.asStateFlow()
    
    private val _isSearchExpanded = MutableStateFlow(false)
    val isSearchExpanded: StateFlow<Boolean> = _isSearchExpanded.asStateFlow()

    private val _searchLogs = MutableStateFlow<List<String>>(emptyList())
    val searchLogs: StateFlow<List<String>> = _searchLogs.asStateFlow()
    
    // Приватные переменные
    private var searchJob: Job? = null
    private var privateKeyHash: String = ""
    private val timeFormatter = SimpleDateFormat("HH:mm:ss.SSS", Locale.getDefault())
    
    // Callback для обработки ответа поиска
    private val searchPacketHandler: (com.rosetta.messenger.network.Packet) -> Unit = handler@{ packet ->
        if (packet is PacketSearch) {
            logSearch(
                    "📥 PacketSearch response: search='${packet.search}', users=${packet.users.size}"
            )
            // Desktop parity: любой ответ PacketSearch обновляет результаты
            // пока в поле есть активный поисковый запрос.
            if (_searchQuery.value.trim().isEmpty()) {
                logSearch("⏭ Ignored response: query is empty")
                return@handler
            }
            _searchResults.value = packet.users
            _isSearching.value = false
            logSearch("✅ Results updated")
        }
    }
    
    init {
        // Регистрируем обработчик пакетов поиска
        ProtocolManager.waitPacket(0x03, searchPacketHandler)
    }
    
    override fun onCleared() {
        super.onCleared()
        // Отписываемся от пакетов при уничтожении ViewModel
        ProtocolManager.unwaitPacket(0x03, searchPacketHandler)
        searchJob?.cancel()
    }
    
    /**
     * Установить приватный ключ для поиска
     */
    fun setPrivateKeyHash(hash: String) {
        privateKeyHash = hash.trim()
        val shortHash =
                if (privateKeyHash.length > 12) {
                    "${privateKeyHash.take(8)}...${privateKeyHash.takeLast(4)}"
                } else {
                    privateKeyHash
                }
        logSearch("🔑 privateKeyHash set: $shortHash")
    }
    
    /**
     * Обработка изменения текста поиска
     * Аналогично handleSearch в React Native
     */
    fun onSearchQueryChange(query: String) {
        val normalizedQuery = sanitizeSearchInput(query)
        _searchQuery.value = normalizedQuery
        logSearch("⌨️ Query changed: '$query' -> '$normalizedQuery'")
        
        // Отменяем предыдущий поиск
        searchJob?.cancel()
        
        // Если пустой запрос - очищаем результаты
        if (normalizedQuery.trim().isEmpty()) {
            _searchResults.value = emptyList()
            _isSearching.value = false
            logSearch("🧹 Cleared results: empty query")
            return
        }

        // Показываем индикатор загрузки
        _isSearching.value = true
        logSearch("⏳ Debounce started (1000ms)")
        
        // Запускаем поиск с задержкой 1 секунда (как в React Native)
        searchJob = viewModelScope.launch {
            delay(1000) // debounce
            
            // Проверяем, не изменился ли запрос
            if (normalizedQuery != _searchQuery.value) {
                logSearch("⏭ Skip send: query changed during debounce")
                return@launch
            }

            val effectivePrivateHash =
                    privateKeyHash.ifBlank { ProtocolManager.getProtocol().getPrivateHash().orEmpty() }
            if (effectivePrivateHash.isBlank()) {
                _isSearching.value = false
                logSearch("❌ Skip send: private hash is empty")
                return@launch
            }
            
            // Создаем и отправляем пакет поиска
            val packetSearch = PacketSearch().apply {
                this.privateKey = effectivePrivateHash
                this.search = normalizedQuery
            }
            
            ProtocolManager.sendPacket(packetSearch)
            logSearch("📤 PacketSearch sent: '$normalizedQuery'")
        }
    }
    
    /**
     * Открыть панель поиска
     */
    fun expandSearch() {
        _isSearchExpanded.value = true
    }
    
    /**
     * Закрыть панель поиска и очистить результаты
     */
    fun collapseSearch() {
        _isSearchExpanded.value = false
        _searchQuery.value = ""
        _searchResults.value = emptyList()
        _isSearching.value = false
        searchJob?.cancel()
        logSearch("↩️ Search collapsed")
    }
    
    /**
     * Очистить только поисковый запрос
     */
    fun clearSearchQuery() {
        _searchQuery.value = ""
        _searchResults.value = emptyList()
        _isSearching.value = false
        searchJob?.cancel()
        logSearch("🧹 Query cleared")
    }

    fun clearSearchLogs() {
        _searchLogs.value = emptyList()
    }

    private fun logSearch(message: String) {
        val timestamp = synchronized(timeFormatter) { timeFormatter.format(Date()) }
        _searchLogs.value = (_searchLogs.value + "[$timestamp] $message").takeLast(200)
    }
}

private fun sanitizeSearchInput(input: String): String = input.replace("@", "").trimStart()
