package dev.zxq5.chatapp.android.feature.chat

import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dev.zxq5.chatapp.android.data.repository.ChatRepository
import dev.zxq5.chatapp.android.api.model.Message
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch



class ChatViewModel(private val chatRepository: ChatRepository) : ViewModel() {

    private val _messages = MutableStateFlow<List<Message>>(emptyList())
    val messages: StateFlow<List<Message>> = _messages

    private val _channelId = MutableStateFlow<Int?>(null)
    val channelId: StateFlow<Int?> = _channelId

    private val _currentScreen = MutableStateFlow(Screen.CHAT)
    val currentScreen: StateFlow<Screen> = _currentScreen

    private val _currentUserId = MutableStateFlow<Int?>(null)
    val currentUserId: StateFlow<Int?> = _currentUserId

    private var streamJob: Job? = null

    init {
        _currentUserId.value = chatRepository.getUserId()
        observeChannel()
    }

    private fun observeChannel() {
        viewModelScope.launch {
            _channelId.collect { id ->
                streamJob?.cancel()
                _messages.value = emptyList()
                if (id != null) {
                    streamJob = launch {
                        chatRepository.messageStream(id)
                            .catch { e -> 
                                Log.e("Chat", "Stream error", e)
                            }
                            .collect { message ->
                                _messages.update { it + message }
                            }
                    }
                }
            }
        }
    }

    fun navigateTo(screen: Screen) {
        _currentScreen.value = screen
    }

    fun switchChannel(id: Int?) {
        _channelId.value = id
        if (id != null) {
            // Refresh user ID just in case it wasn't available at init
            _currentUserId.value = chatRepository.getUserId()
            chatRepository.resetClient() 
        }
    }

    fun sendMessage(text: String) {
        val currentId = _channelId.value ?: return
        viewModelScope.launch {
            runCatching {
                chatRepository.sendMessage(
                    channelId = currentId,
                    text = text
                )
            }.onFailure { e ->
                Log.e("Chat", "Send message error", e)
            }
        }
    }
    
    fun clearChat() {
        _messages.value = emptyList()
        _channelId.value = null
        _currentUserId.value = null
        streamJob?.cancel()
        chatRepository.resetClient()
    }
}

