package com.crm.chat.ui.main

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.crm.chat.data.api.ApiClient
import com.crm.chat.data.model.*
import com.crm.chat.data.repository.ChatRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

class MainViewModel : ViewModel() {

    companion object {
        private var instance: MainViewModel? = null

        fun getInstance(): MainViewModel {
            if (instance == null) {
                instance = MainViewModel()
                println("DEBUG: Created new MainViewModel singleton instance")
            } else {
                println("DEBUG: Reusing existing MainViewModel singleton instance")
            }
            return instance!!
        }
    }

    private val _chatsState = MutableLiveData<ChatsState>()
    val chatsState: LiveData<ChatsState> = _chatsState
    private var lastChatsData: List<com.crm.chat.data.model.Chat>? = null

    private val _providersState = MutableLiveData<ProvidersState>()
    val providersState: LiveData<ProvidersState> = _providersState

    private val _unseenCountState = MutableLiveData<UnseenCountState>()
    val unseenCountState: LiveData<UnseenCountState> = _unseenCountState

    private lateinit var apiClient: ApiClient
    private lateinit var chatRepository: ChatRepository
    private lateinit var applicationContext: android.content.Context

    // User cache for displaying names in chats
    val userCache = mutableMapOf<Long, com.crm.chat.data.api.User>()

    // Address book - all users
    private val _addressBookState = MutableLiveData<AddressBookState>()
    val addressBookState: LiveData<AddressBookState> = _addressBookState
    private var lastAddressBookData: List<com.crm.chat.data.api.User>? = null

    // Polling job tracking
    private var pollingJob: kotlinx.coroutines.Job? = null

    var badgeUpdateCallback: ((Int, String?, String?, android.graphics.Bitmap?) -> Unit)? = null



    fun loadChats() {
        println("DEBUG: MainViewModel.loadChats() called")
        viewModelScope.launch {
            try {
                val result = chatRepository.getChats()
                result.fold(
                    onSuccess = { chats ->
                        println("DEBUG: MainViewModel loaded ${chats.size} chats")
                        // Sort chats by last message date (newest first)
                        val sortedChats = chats.sortedByDescending { chat ->
                            chat.lastMessage?.createdAt ?: ""
                        }

                        // Only update if data has changed
                        val dataChanged = hasChatsDataChanged(sortedChats)
                        println("DEBUG: loadChats - dataChanged: $dataChanged, oldSize: ${lastChatsData?.size}, newSize: ${sortedChats.size}")
                        if (dataChanged) {
                            println("DEBUG: loadChats - updating UI with ${sortedChats.size} chats")
                            _chatsState.value = ChatsState.Success(sortedChats)
                            lastChatsData = sortedChats.toList()
                            // Update app icon badge with total unread count
                            // Delay badge update slightly to ensure address book is loaded
                            kotlinx.coroutines.delay(100)
                            updateAppIconBadge(sortedChats.sumOf { it.unseenCount })
                        } else {
                            println("DEBUG: loadChats - no changes detected")
                        }
                    },
                    onFailure = { exception ->
                        println("DEBUG: MainViewModel failed to load chats: ${exception.message}")
                        // Only set error state if we're not already in an error state
                        if (_chatsState.value !is ChatsState.Error) {
                            _chatsState.value = ChatsState.Error(exception.message ?: "Ошибка загрузки чатов")
                        }
                    }
                )
            } catch (e: Exception) {
                println("DEBUG: MainViewModel exception in loadChats: ${e.message}")
                // Only set error state if we're not already in an error state
                if (_chatsState.value !is ChatsState.Error) {
                    _chatsState.value = ChatsState.Error("Неожиданная ошибка: ${e.message}")
                }
            }
        }
    }

    private fun hasChatsDataChanged(newChats: List<com.crm.chat.data.model.Chat>): Boolean {
        val oldChats = lastChatsData ?: run {
            println("DEBUG: hasChatsDataChanged - first load (oldChats is null)")
            return true // First load
        }

        println("DEBUG: hasChatsDataChanged - comparing oldSize=${oldChats.size} vs newSize=${newChats.size}")

        // Check if sizes differ (covers additions and deletions)
        if (oldChats.size != newChats.size) {
            println("DEBUG: hasChatsDataChanged - size changed from ${oldChats.size} to ${newChats.size}")
            return true
        }

        // Check if any chat data has changed
        for (newChat in newChats) {
            val oldChat = oldChats.find { it.id == newChat.id } ?: run {
                println("DEBUG: hasChatsDataChanged - new chat ${newChat.id} not found in old chats (addition)")
                return true
            }
            if (hasChatChanged(oldChat, newChat)) {
                println("DEBUG: hasChatsDataChanged - chat ${newChat.id} has changed")
                return true
            }
        }

        // Check if any old chats are missing from new chats (deletions)
        for (oldChat in oldChats) {
            val newChat = newChats.find { it.id == oldChat.id }
            if (newChat == null) {
                println("DEBUG: hasChatsDataChanged - old chat ${oldChat.id} missing from new chats (deletion)")
                return true // Chat was deleted
            }
        }

        println("DEBUG: hasChatsDataChanged - no changes detected")
        return false
    }

    private fun hasChatChanged(oldChat: com.crm.chat.data.model.Chat, newChat: com.crm.chat.data.model.Chat): Boolean {
        // Compare properties that affect chat display
        if (oldChat.unseenCount != newChat.unseenCount) return true
        if (oldChat.title != newChat.title) return true
        if (oldChat.type != newChat.type) return true

        // Compare last message content (but not timestamps that change on every poll)
        val oldMsg = oldChat.lastMessage
        val newMsg = newChat.lastMessage

        if ((oldMsg == null) != (newMsg == null)) return true // One has message, other doesn't

        if (oldMsg != null && newMsg != null) {
            if (oldMsg.id != newMsg.id) return true
            if (oldMsg.text != newMsg.text) return true
            if (oldMsg.chatUserId != newMsg.chatUserId) return true
            // Note: We don't compare createdAt as it may change on every poll
        }

        return false
    }



    fun loadProviders() {
        _providersState.value = ProvidersState.Loading
        viewModelScope.launch {
            try {
                val result = chatRepository.getChatProviders()
                result.fold(
                    onSuccess = { providers ->
                        _providersState.value = ProvidersState.Success(providers)
                    },
                    onFailure = { exception ->
                        _providersState.value = ProvidersState.Error(exception.message ?: "Ошибка загрузки провайдеров")
                    }
                )
            } catch (e: Exception) {
                _providersState.value = ProvidersState.Error("Неожиданная ошибка: ${e.message}")
            }
        }
    }

    fun loadUnseenCount() {
        _unseenCountState.value = UnseenCountState.Loading
        viewModelScope.launch {
            try {
                val result = chatRepository.getUnseenCount()
                result.fold(
                    onSuccess = { count ->
                        _unseenCountState.value = UnseenCountState.Success(count)
                    },
                    onFailure = { exception ->
                        _unseenCountState.value = UnseenCountState.Error(exception.message ?: "Ошибка загрузки счетчика")
                    }
                )
            } catch (e: Exception) {
                _unseenCountState.value = UnseenCountState.Error("Неожиданная ошибка: ${e.message}")
            }
        }
    }

    fun deleteChat(chatId: Long) {
        viewModelScope.launch {
            try {
                val result = chatRepository.deleteChat(chatId)
                result.fold(
                    onSuccess = {
                        println("DEBUG: Chat deleted successfully, forcing complete refresh")
                        // Clear cached data to force UI update
                        lastChatsData = null
                        // Stop current polling
                        pollingJob?.cancel()
                        pollingJob = null
                        // Force immediate refresh
                        loadChats()
                        // Restart polling to get fresh data
                        startForegroundPolling()
                    },
                    onFailure = { exception ->
                        _chatsState.value = ChatsState.Error(exception.message ?: "Ошибка удаления чата")
                    }
                )
            } catch (e: Exception) {
                _chatsState.value = ChatsState.Error("Неожиданная ошибка: ${e.message}")
            }
        }
    }

    fun createPersonalChat(providerId: Long, companionId: Long) {
        viewModelScope.launch {
            try {
                // First check if personal chat already exists with this user
                val existingChat = lastChatsData?.find { chat ->
                    chat.type == "personal" && chat.users?.any { user ->
                        user.userId == companionId
                    } == true
                }

                if (existingChat != null) {
                    // Chat already exists, just return it
                    _chatsState.value = ChatsState.Success(lastChatsData ?: emptyList())
                    return@launch
                }

                // Create new chat if it doesn't exist
                val request = CreatePersonalChatRequest(providerId, companionId)
                val result = chatRepository.createPersonalChat(request)
                result.fold(
                    onSuccess = { chat ->
                        // Refresh chats list
                        loadChats()
                    },
                    onFailure = { exception ->
                        _chatsState.value = ChatsState.Error(exception.message ?: "Ошибка создания личного чата")
                    }
                )
            } catch (e: Exception) {
                _chatsState.value = ChatsState.Error("Неожиданная ошибка: ${e.message}")
            }
        }
    }

    fun createGroupChat(providerId: Long, participantIds: List<Long>, title: String, entityId: Long? = null) {
        val request = CreateGroupChatRequest(providerId, participantIds, title, entityId)
        viewModelScope.launch {
            try {
                val result = chatRepository.createGroupChat(request)
                result.fold(
                    onSuccess = { chat ->
                        // Refresh chats list
                        loadChats()
                    },
                    onFailure = { exception ->
                        _chatsState.value = ChatsState.Error(exception.message ?: "Ошибка создания группового чата")
                    }
                )
            } catch (e: Exception) {
                _chatsState.value = ChatsState.Error("Неожиданная ошибка: ${e.message}")
            }
        }
    }

    fun createExternalChat(title: String, entityId: Long? = null, externalUser: ChatUserExternal? = null) {
        val request = CreateExternalChatRequest(title, entityId, externalUser)
        viewModelScope.launch {
            try {
                val result = chatRepository.createExternalChat(request)
                result.fold(
                    onSuccess = { chat ->
                        // Refresh chats list
                        loadChats()
                    },
                    onFailure = { exception ->
                        _chatsState.value = ChatsState.Error(exception.message ?: "Ошибка создания внешнего чата")
                    }
                )
            } catch (e: Exception) {
                _chatsState.value = ChatsState.Error("Неожиданная ошибка: ${e.message}")
            }
        }
    }

    fun searchChats(query: String) {
        if (query.isBlank()) {
            loadChats() // If empty query, just reload all chats
            return
        }

        val filters = mapOf("search" to query)
        _chatsState.value = ChatsState.Loading
        viewModelScope.launch {
            try {
                val result = chatRepository.findChatsFull(filters)
                result.fold(
                    onSuccess = { chats ->
                        _chatsState.value = ChatsState.Success(chats)
                    },
                    onFailure = { exception ->
                        _chatsState.value = ChatsState.Error(exception.message ?: "Ошибка поиска чатов")
                    }
                )
            } catch (e: Exception) {
                _chatsState.value = ChatsState.Error("Неожиданная ошибка: ${e.message}")
            }
        }
    }

    fun initialize(context: android.content.Context, serverUrl: String, token: String, apiKey: String) {
        // Store application context
        applicationContext = context.applicationContext

        // Create API client with authentication token
        apiClient = ApiClient(serverUrl, apiKey, token)
        chatRepository = ChatRepository(apiClient)

        // Load address book first, then chats and background sync
        loadAddressBookFirst()
    }

    private fun loadAddressBookFirst() {
        println("DEBUG: Loading address book first")
        viewModelScope.launch {
            try {
                val result = chatRepository.getUsers(null) // Load all users without search filter
                result.fold(
                    onSuccess = { users ->
                        // Cache all users and avatars asynchronously
                        users.forEach { user ->
                            cacheUser(user)
                            // Cache avatar asynchronously to avoid blocking UI
                            kotlinx.coroutines.CoroutineScope(kotlinx.coroutines.Dispatchers.IO).launch {
                                try {
                                    com.crm.chat.utils.NotificationHelper.cacheUserAvatar(applicationContext, user)
                                } catch (e: Exception) {
                                    println("DEBUG: Error caching avatar for user ${user.id}: ${e.message}")
                                }
                            }
                        }
                        _addressBookState.value = AddressBookState.Success(users)
                        lastAddressBookData = users.toList()
                        println("DEBUG: Address book loaded first, now loading chats")

                        // Now load chats and start polling
                        loadChats()
                        startForegroundPolling()
                    },
                    onFailure = { exception ->
                        _addressBookState.value = AddressBookState.Error(exception.message ?: "Ошибка загрузки адресной книги")
                        println("DEBUG: Address book load failed: ${exception.message}")
                        // Still try to load chats even if address book fails
                        loadChats()
                        startForegroundPolling()
                    }
                )
            } catch (e: Exception) {
                _addressBookState.value = AddressBookState.Error("Неожиданная ошибка: ${e.message}")
                // Still try to load chats even if address book fails
                loadChats()
                startForegroundPolling()
            }
        }
    }

    fun ensurePollingIsActive() {
        // Check if polling coroutine is still active, restart if needed
        if (pollingJob == null || !pollingJob!!.isActive) {
            println("DEBUG: Restarting chat polling")
            startForegroundPolling()
        }
    }

    private fun startForegroundPolling() {
        println("DEBUG: MainViewModel.startForegroundPolling() called")
        pollingJob = viewModelScope.launch {
            println("DEBUG: MainViewModel polling job started")
            // Address book polling every 10 seconds
            launch {
                while (true) {
                    kotlinx.coroutines.delay(10000) // 10 seconds
                    println("DEBUG: MainViewModel address book polling tick")
                    loadAddressBook()
                }
            }

            // Chats polling every 1 second
            launch {
                while (true) {
                    kotlinx.coroutines.delay(1000) // 1 second
                    println("DEBUG: MainViewModel chats polling tick")
                    loadChats()
                }
            }
        }
    }

    fun refreshChats() {
        // Force immediate refresh by clearing cached data
        lastChatsData = null
        loadChats()
    }

    fun notifyChatUpdated(chatId: Long) {
        // Trigger an immediate refresh of chats when a specific chat is updated
        loadChats()
    }

    fun getUsers(search: String? = null): androidx.lifecycle.LiveData<Result<List<com.crm.chat.data.api.User>>> {
        val liveData = androidx.lifecycle.MutableLiveData<Result<List<com.crm.chat.data.api.User>>>()

        viewModelScope.launch {
            try {
                val result = chatRepository.getUsers(search)
                liveData.value = result
            } catch (e: Exception) {
                liveData.value = Result.failure(e)
            }
        }

        return liveData
    }

    fun getUserName(userId: Long): String {
        val user = userCache[userId]
        val result = if (user != null) {
            "${user.lastName} ${user.firstName}"
        } else {
            "User $userId"
        }
        return result
    }

    fun getUserAvatarUrl(userId: Long): String? {
        return userCache[userId]?.avatarUrl
    }

    fun cacheUser(user: com.crm.chat.data.api.User) {
        userCache[user.id] = user
    }



    fun loadAddressBook() {
        println("DEBUG: Starting address book load")
        viewModelScope.launch {
            try {
                val result = chatRepository.getUsers(null) // Load all users without search filter
                result.fold(
                    onSuccess = { users ->
                        // Only update if data has changed
                        if (hasAddressBookDataChanged(users)) {
                            // Cache all users for future use
                            users.forEach { user ->
                                cacheUser(user)
                                // Cache user avatar for notifications
                                com.crm.chat.utils.NotificationHelper.cacheUserAvatar(applicationContext, user)
                            }
                            _addressBookState.value = AddressBookState.Success(users)
                            lastAddressBookData = users.toList()
                            println("DEBUG: Address book loaded successfully with ${users.size} users")
                        }

                        // Notify that user data has been updated (chat names will refresh automatically)
                        // Don't refresh the entire chat list, just the display names
                    },
                    onFailure = { exception ->
                        // Only set error state if we're not already in an error state
                        if (_addressBookState.value !is AddressBookState.Error) {
                            _addressBookState.value = AddressBookState.Error(exception.message ?: "Ошибка загрузки адресной книги")
                            println("DEBUG: Address book load failed: ${exception.message}")
                        }
                    }
                )
            } catch (e: Exception) {
                // Only set error state if we're not already in an error state
                if (_addressBookState.value !is AddressBookState.Error) {
                    _addressBookState.value = AddressBookState.Error("Неожиданная ошибка: ${e.message}")
                    println("DEBUG: Address book load exception: ${e.message}")
                }
            }
        }
    }

    private fun hasAddressBookDataChanged(newUsers: List<com.crm.chat.data.api.User>): Boolean {
        val oldUsers = lastAddressBookData ?: return true // First load

        // Check if sizes differ
        if (oldUsers.size != newUsers.size) return true

        // Check if any user data has changed
        for (newUser in newUsers) {
            val oldUser = oldUsers.find { it.id == newUser.id } ?: return true
            if (hasUserChanged(oldUser, newUser)) return true
        }

        return false
    }

    private fun hasUserChanged(oldUser: com.crm.chat.data.api.User, newUser: com.crm.chat.data.api.User): Boolean {
        return oldUser.firstName != newUser.firstName ||
               oldUser.lastName != newUser.lastName ||
               oldUser.avatarUrl != newUser.avatarUrl
    }

    private fun updateAppIconBadge(unreadCount: Int) {
        // Only show detailed notifications after address book is loaded
        if (userCache.isNotEmpty() && unreadCount > 0) {
            val (senderName, latestMessage, senderAvatar) = findLatestMessageWithAvatar()
            badgeUpdateCallback?.invoke(unreadCount, senderName, latestMessage, senderAvatar)
        } else {
            // Show basic notification if address book not loaded yet
            badgeUpdateCallback?.invoke(unreadCount, null, null, null)
        }
    }

    private fun findLatestMessageWithAvatar(): Triple<String?, String?, android.graphics.Bitmap?> {
        val chats = lastChatsData ?: return Triple(null, null, null)

        // Find the chat with the most recent message
        val chatWithLatestMessage = chats
            .filter { it.lastMessage != null }
            .maxByOrNull { it.lastMessage?.createdAt ?: "" }

        return chatWithLatestMessage?.let { chat ->
            val message = chat.lastMessage ?: return@let Triple(null, null, null)

            // Map chatUserId to actual userId using chat.users if available
            val senderUserId = chat.users?.find { it.id == message.chatUserId }?.userId ?: message.chatUserId

            val senderName = getUserName(senderUserId)
            val messageText = message.text ?: "Новое сообщение"

            // Create chat avatar (not sender avatar)
            val chatAvatar = createChatAvatar(chat, senderUserId, senderName)

            Triple(senderName, messageText, chatAvatar)
        } ?: Triple(null, null, null)
    }

    private fun createChatAvatar(chat: com.crm.chat.data.model.Chat, senderUserId: Long, senderName: String): android.graphics.Bitmap? {
        return when {
            // For personal chats, show the OTHER user's avatar (not the sender)
            chat.type == "personal" && chat.users != null && chat.users.size >= 2 -> {
                val currentUserId = applicationContext.getSharedPreferences("crm_chat_prefs", android.content.Context.MODE_PRIVATE)
                    .getLong("current_user_id", 12033923L)
                val otherUser = chat.users.find { it.userId != currentUserId }
                if (otherUser != null) {
                    createUserAvatar(otherUser.userId, getUserName(otherUser.userId))
                } else {
                    createUserAvatar(senderUserId, senderName) // fallback
                }
            }
            // For group chats, use sender avatar or create group avatar
            chat.title != null -> {
                // Group chat - could create a group avatar here, but for now use sender
                createUserAvatar(senderUserId, senderName)
            }
            // Default fallback
            else -> {
                createUserAvatar(senderUserId, senderName)
            }
        }
    }

    private fun createUserAvatar(userId: Long, userName: String): android.graphics.Bitmap? {
        // First try to get cached avatar from NotificationHelper
        val cacheDir = applicationContext.cacheDir
        val cacheFile = java.io.File(cacheDir, "user_avatars/avatar_$userId.png")

        println("DEBUG: MainViewModel.createUserAvatar - Looking for cached avatar at: ${cacheFile.absolutePath}, exists: ${cacheFile.exists()}")

        if (cacheFile.exists()) {
            println("DEBUG: Cache file exists, size: ${cacheFile.length()}")
            return try {
                val cachedBitmap = android.graphics.BitmapFactory.decodeFile(cacheFile.absolutePath)
                println("DEBUG: Loaded cached bitmap for user $userId: ${cachedBitmap != null}")
                if (cachedBitmap != null) {
                    println("DEBUG: Bitmap size: ${cachedBitmap.width}x${cachedBitmap.height}")
                    // Resize to notification size and make circular
                    val circularAvatar = createCircularAvatar(cachedBitmap, 192)
                    println("DEBUG: Created circular avatar for user $userId: ${circularAvatar != null}")
                    circularAvatar
                } else {
                    println("DEBUG: Bitmap decode returned null")
                    createGeneratedAvatar(userId, userName)
                }
            } catch (e: Exception) {
                println("DEBUG: Exception loading cached avatar for user $userId: ${e.message}")
                e.printStackTrace()
                createGeneratedAvatar(userId, userName)
            }
        }

        // If no cached avatar, create generated one
        println("DEBUG: No cached avatar for user $userId, using generated avatar")
        return createGeneratedAvatar(userId, userName)
    }

    private fun createGeneratedAvatar(userId: Long, userName: String): android.graphics.Bitmap? {
        // Generate avatar with user initials
        return try {
            val size = 192
            val bitmap = android.graphics.Bitmap.createBitmap(size, size, android.graphics.Bitmap.Config.ARGB_8888)
            val canvas = android.graphics.Canvas(bitmap)

            // Get initials from full name (Фамилия Имя)
            val initials = userName.split(" ").let { parts ->
                when (parts.size) {
                    1 -> parts[0].take(1).uppercase()
                    2 -> "${parts[0].take(1)}${parts[1].take(1)}".uppercase()
                    else -> parts.firstOrNull()?.take(1)?.uppercase() ?: "U"
                }
            }

            // Generate color based on user ID
            val colors = arrayOf(
                android.graphics.Color.parseColor("#E53935"),
                android.graphics.Color.parseColor("#1E88E5"),
                android.graphics.Color.parseColor("#43A047"),
                android.graphics.Color.parseColor("#FB8C00"),
                android.graphics.Color.parseColor("#8E24AA")
            )
            val backgroundColor = colors[(userId % colors.size).toInt()]

            // Draw circle background
            val paint = android.graphics.Paint().apply {
                color = backgroundColor
                isAntiAlias = true
                style = android.graphics.Paint.Style.FILL
            }
            val rect = android.graphics.RectF(0f, 0f, size.toFloat(), size.toFloat())
            canvas.drawOval(rect, paint)

            // Draw initials text
            paint.apply {
                color = android.graphics.Color.WHITE
                textSize = size * 0.4f
                textAlign = android.graphics.Paint.Align.CENTER
                style = android.graphics.Paint.Style.FILL
            }
            val xPos = size / 2f
            val yPos = size / 2f - (paint.descent() + paint.ascent()) / 2f
            canvas.drawText(initials, xPos, yPos, paint)

            bitmap
        } catch (e: Exception) {
            null // Return null if avatar creation fails
        }
    }

    private fun createCircularAvatar(sourceBitmap: android.graphics.Bitmap, diameter: Int): android.graphics.Bitmap {
        val output = android.graphics.Bitmap.createBitmap(diameter, diameter, android.graphics.Bitmap.Config.ARGB_8888)
        val canvas = android.graphics.Canvas(output)

        val paint = android.graphics.Paint().apply {
            isAntiAlias = true
        }

        // Calculate scaling to fit the bitmap in the circle
        val minEdge = minOf(sourceBitmap.width, sourceBitmap.height)
        val scale = diameter.toFloat() / minEdge
        val matrix = android.graphics.Matrix()
        matrix.postScale(scale, scale)

        // Center the bitmap
        val xOffset = (diameter - sourceBitmap.width * scale) / 2
        val yOffset = (diameter - sourceBitmap.height * scale) / 2
        matrix.postTranslate(xOffset, yOffset)

        // Create circular mask
        val radius = diameter / 2f
        canvas.drawCircle(radius, radius, radius, paint)

        // Apply Porter-Duff mode to clip the bitmap to circle
        paint.xfermode = android.graphics.PorterDuffXfermode(android.graphics.PorterDuff.Mode.SRC_IN)
        canvas.drawBitmap(sourceBitmap, matrix, paint)

        sourceBitmap.recycle()

        return output
    }





    fun updateApiClient(serverUrl: String, token: String) {
        val updatedApiClient = ApiClient(serverUrl, com.crm.chat.data.AppConstants.API_KEY)
        // Note: We need to create a new ChatRepository with the updated ApiClient
        // This is a limitation of the current architecture
        // In a real app, we would use dependency injection to handle this properly
    }

    sealed class ChatsState {
        object Loading : ChatsState()
        data class Success(val chats: List<Chat>) : ChatsState()
        data class Error(val message: String) : ChatsState()
    }

    sealed class ProvidersState {
        object Loading : ProvidersState()
        data class Success(val providers: List<ChatProvider>) : ProvidersState()
        data class Error(val message: String) : ProvidersState()
    }

    sealed class UnseenCountState {
        object Loading : UnseenCountState()
        data class Success(val count: Int) : UnseenCountState()
        data class Error(val message: String) : UnseenCountState()
    }

    sealed class AddressBookState {
        object Loading : AddressBookState()
        data class Success(val users: List<com.crm.chat.data.api.User>) : AddressBookState()
        data class Error(val message: String) : AddressBookState()
    }
}
