package com.rosetta.messenger.ui.chats

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.rosetta.messenger.di.ProtocolGateway
import com.rosetta.messenger.network.PacketSearch
import com.rosetta.messenger.network.SearchUser
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject
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.flow.collectLatest
import kotlinx.coroutines.launch

/**
 * ViewModel для поиска пользователей через протокол
 * Работает аналогично SearchBar в React Native приложении
 */
@HiltViewModel
class SearchUsersViewModel @Inject constructor(
    private val protocolGateway: ProtocolGateway
) : 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 packetFlowJob: Job? = null
    private var privateKeyHash: String = ""
    private val timeFormatter = SimpleDateFormat("HH:mm:ss.SSS", Locale.getDefault())
    
    init {
        packetFlowJob =
            viewModelScope.launch {
                protocolGateway.packetFlow(0x03).collectLatest { packet ->
                    val searchPacket = packet as? PacketSearch ?: return@collectLatest
                    logSearch(
                        "📥 PacketSearch response: search='${searchPacket.search}', users=${searchPacket.users.size}"
                    )
                    if (_searchQuery.value.trim().isEmpty()) {
                        logSearch("⏭ Ignored response: query is empty")
                        return@collectLatest
                    }
                    _searchResults.value = searchPacket.users
                    _isSearching.value = false
                    logSearch("✅ Results updated")
                }
            }
    }
    
    override fun onCleared() {
        super.onCleared()
        searchJob?.cancel()
        packetFlowJob?.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 { protocolGateway.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
            }
            
            protocolGateway.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()
