package app.closer.ui.messages

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import app.closer.data.local.QuestionDao
import app.closer.data.local.mapper.toQuestion
import app.closer.domain.model.Conversation
import app.closer.domain.repository.ConversationRepository
import app.closer.domain.repository.CoupleRepository
import app.closer.domain.repository.UserRepository
import com.google.firebase.auth.FirebaseAuth
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import javax.inject.Inject

data class MessagesInboxUiState(
    val isLoading: Boolean = true,
    val coupleId: String = "",
    val isPaired: Boolean = true,
    val partnerPhotoUrl: String? = null,
    val conversations: List<Conversation> = emptyList()
)

@HiltViewModel
class MessagesInboxViewModel @Inject constructor(
    private val repository: ConversationRepository,
    private val coupleRepository: CoupleRepository,
    private val userRepository: UserRepository,
    private val questionDao: QuestionDao
) : ViewModel() {

    private val currentUserId: String = FirebaseAuth.getInstance().currentUser?.uid ?: ""

    private val _uiState = MutableStateFlow(MessagesInboxUiState())
    val uiState: StateFlow<MessagesInboxUiState> = _uiState.asStateFlow()

    init { load() }

    private fun load() {
        viewModelScope.launch {
            val couple = runCatching { coupleRepository.getCoupleForUser(currentUserId) }.getOrNull()
            if (couple == null) {
                _uiState.update { it.copy(isLoading = false, isPaired = false) }
                return@launch
            }
            val coupleId = couple.id
            val partnerId = couple.userIds.firstOrNull { it != currentUserId }
            val partner = partnerId?.let { runCatching { userRepository.getUser(it) }.getOrNull() }
            val partnerName = partner?.displayName?.takeIf { it.isNotBlank() } ?: "Your partner"
            // Show the pinned main conversation immediately so the inbox is never blank while the
            // live read warms up.
            val mainEntry = Conversation(id = "main", type = "main", title = partnerName)
            _uiState.update {
                it.copy(coupleId = coupleId, partnerPhotoUrl = partner?.photoUrl, isLoading = false, conversations = listOf(mainEntry))
            }

            runCatching { repository.ensureMainConversation(coupleId) }

            repository.observeConversations(coupleId, currentUserId).collect { convs ->
                val titled = buildList {
                    for (c in convs) {
                        val title = if (c.isMain) {
                            partnerName
                        } else {
                            runCatching { questionDao.getQuestionById(c.questionId)?.toQuestion()?.text }
                                .getOrNull() ?: "Discussion"
                        }
                        add(c.copy(title = title))
                    }
                }
                // Pin the main conversation on top; the rest by most-recent activity.
                val main = titled.firstOrNull { it.isMain }
                    ?: Conversation(id = "main", type = "main", title = partnerName)
                val rest = titled.filterNot { it.isMain }.sortedByDescending { it.lastMessageAt }
                _uiState.update { it.copy(isLoading = false, conversations = listOf(main) + rest) }
            }
        }
    }
}
