package app.closer.notifications

import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import javax.inject.Inject
import javax.inject.Singleton

/** State for the floating in-app message bubble (a chat-head shown over the app's own UI). */
data class IncomingMessageBubble(
    val coupleId: String,
    val conversationId: String,
    val count: Int = 1,
    val avatarUrl: String? = null
)

/**
 * App-scoped holder for the in-app message bubble. The FCM foreground path posts here when a
 * partner message arrives while the app is open but that conversation isn't on screen; the root
 * UI observes [bubble] and renders a draggable chat-head. Opening or dismissing clears it.
 */
@Singleton
class MessageBubbleController @Inject constructor() {
    private val _bubble = MutableStateFlow<IncomingMessageBubble?>(null)
    val bubble: StateFlow<IncomingMessageBubble?> = _bubble.asStateFlow()

    /** Show the bubble for [conversationId], or bump its unread count if it's already showing. */
    fun show(coupleId: String, conversationId: String, avatarUrl: String?) {
        if (coupleId.isBlank() || conversationId.isBlank()) return
        _bubble.update { current ->
            if (current != null && current.conversationId == conversationId) {
                current.copy(count = current.count + 1, avatarUrl = avatarUrl ?: current.avatarUrl)
            } else {
                IncomingMessageBubble(coupleId, conversationId, 1, avatarUrl)
            }
        }
    }

    fun dismiss() {
        _bubble.value = null
    }

    /** Clear the bubble once its conversation is opened (the message has been read). */
    fun dismissFor(conversationId: String) {
        _bubble.update { current -> if (current?.conversationId == conversationId) null else current }
    }
}
