package com.pixelized.desktop.lwa.ui.screen.campaign.chatbox

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.pixelized.desktop.lwa.repository.campaign.CampaignRepository
import com.pixelized.desktop.lwa.repository.network.NetworkRepository
import com.pixelized.desktop.lwa.repository.settings.SettingsRepository
import com.pixelized.shared.lwa.protocol.websocket.SocketMessage
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.runningFold
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch


class CampaignChatViewModel(
    private val settingsRepository: SettingsRepository,
    campaignRepository: CampaignRepository,
    networkRepository: NetworkRepository,
    textMessageFactory: TextMessageFactory,
) : ViewModel() {

    val settings = settingsRepository.settingsFlow().map {
        ChatSettingsUio(
            show = it.chat.showChat,
            autoScroll = it.chat.autoScrollChat,
        )
    }.stateIn(
        scope = viewModelScope,
        started = SharingStarted.Eagerly,
        initialValue = ChatSettingsUio.default(),
    )

    val messages = combine(
        settingsRepository.settingsFlow(),
        campaignRepository.campaignFlow(),
        networkRepository.data.runningFold(
            initial = mutableListOf(),
            operation = List<SocketMessage>::plus
        )
    ) { settings, campaign, messages ->
        messages.mapNotNull { message ->
            textMessageFactory.convertToTextMessage(
                settings = settings,
                campaign = campaign,
                message = message,
            )
        }.takeLast(
            n = settings.chat.maxLineCount,
        )
    }.stateIn(
        scope = viewModelScope,
        started = SharingStarted.Eagerly,
        initialValue = emptyList(),
    )

    fun toggleChat() {
        viewModelScope.launch {
            val settings = settingsRepository.settingsFlow().value
            settingsRepository.update(
                settings = settings.copy(
                    chat = settings.chat.copy(showChat = settings.chat.showChat.not())
                )
            )
        }
    }
}