package com.aiwazian.messenger.viewModels

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.aiwazian.messenger.api.RetrofitInstance
import com.aiwazian.messenger.data.KanbanBoard
import com.aiwazian.messenger.data.KanbanMoveTaskRequest
import com.aiwazian.messenger.data.KanbanTaskRequest
import com.aiwazian.messenger.data.KanbanTitleRequest
import com.aiwazian.messenger.enums.WebSocketAction
import com.aiwazian.messenger.utils.WebSocketManager
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch

class KanbanViewModel : ViewModel() {
    private val _boards = MutableStateFlow<List<KanbanBoard>>(emptyList())
    val boards = _boards.asStateFlow()

    init {
        WebSocketManager.registerMessageHandler<KanbanBoard>(WebSocketAction.KANBAN_UPDATE) { update(it) }
        refresh()
    }

    fun refresh() = viewModelScope.launch {
        RetrofitInstance.api.getKanbanBoards().body()?.let { _boards.value = it }
    }

    fun createBoard(title: String) = call { RetrofitInstance.api.createKanbanBoard(KanbanTitleRequest(title)).body() }
    fun renameBoard(boardId: Int, title: String) = call {
        RetrofitInstance.api.renameKanbanBoard(boardId, KanbanTitleRequest(title)).body()
    }
    fun deleteBoard(boardId: Int) = viewModelScope.launch {
        if (RetrofitInstance.api.deleteKanbanBoard(boardId).isSuccessful) {
            _boards.value = _boards.value.filterNot { it.id == boardId }
        }
    }
    fun createColumn(boardId: Int, title: String) = call { RetrofitInstance.api.createKanbanColumn(boardId, KanbanTitleRequest(title)).body() }
    fun createTask(columnId: Int, title: String) = call { RetrofitInstance.api.createKanbanTask(columnId, KanbanTaskRequest(title)).body() }
    fun moveTask(taskId: Int, columnId: Int) = call { RetrofitInstance.api.moveKanbanTask(taskId, KanbanMoveTaskRequest(columnId)).body() }
    fun deleteTask(taskId: Int) = call { RetrofitInstance.api.deleteKanbanTask(taskId).body() }

    private fun call(block: suspend () -> KanbanBoard?) = viewModelScope.launch { block()?.let(::update) }
    private fun update(board: KanbanBoard) {
        _boards.value = (_boards.value.filterNot { it.id == board.id } + board).sortedByDescending { it.updatedAt }
    }
}
