package com.seven.ikar.kotlin.feature.folders

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.seven.ikar.kotlin.app.AppContainer
import com.seven.ikar.kotlin.core.model.ChatFolderDto
import com.seven.ikar.kotlin.core.model.ChatStateRequest
import com.seven.ikar.kotlin.core.model.ChatSummaryDto
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch

data class ChatFoldersUiState(
    val folders: List<ChatFolderDto> = emptyList(),
    val chats: List<ChatSummaryDto> = emptyList(),
    val selectedChatIds: Set<String> = emptySet(),
    val newFolderKey: String = "",
    val selectedFolderKey: String? = null,
    val isLoading: Boolean = false,
    val isSaving: Boolean = false,
    val errorMessage: String? = null
)

class ChatFoldersViewModel(private val container: AppContainer) : ViewModel() {
    private val _uiState = MutableStateFlow(ChatFoldersUiState())
    val uiState: StateFlow<ChatFoldersUiState> = _uiState.asStateFlow()

    init {
        refresh()
    }

    fun refresh() {
        viewModelScope.launch {
            _uiState.value = _uiState.value.copy(isLoading = true, errorMessage = null)
            runCatching {
                container.executeAuthorized { session ->
                    val folders = container.apiClient.getChatFolders(session.accessToken)
                    val chats = container.apiClient.getChats(session.accessToken)
                    folders to chats
                }
            }.onSuccess { (folders, chats) ->
                _uiState.value = _uiState.value.copy(
                    folders = folders,
                    chats = chats,
                    selectedChatIds = _uiState.value.selectedChatIds.intersect(chats.mapTo(mutableSetOf(), ChatSummaryDto::id)),
                    isLoading = false
                )
            }.onFailure { error ->
                _uiState.value = _uiState.value.copy(isLoading = false, errorMessage = error.message)
            }
        }
    }

    fun updateNewFolderKey(value: String) {
        val normalized = normalizeFolderKey(value)
        _uiState.value = _uiState.value.copy(newFolderKey = normalized, selectedFolderKey = normalized.ifBlank { null })
    }

    fun selectFolder(folderKey: String?) {
        _uiState.value = _uiState.value.copy(selectedFolderKey = folderKey, newFolderKey = folderKey.orEmpty())
    }

    fun toggleChat(chatId: String) {
        val current = _uiState.value.selectedChatIds
        _uiState.value = _uiState.value.copy(
            selectedChatIds = if (current.contains(chatId)) current - chatId else current + chatId
        )
    }

    fun assignSelectedToFolder() {
        val state = _uiState.value
        val folderKey = normalizeFolderKey(state.selectedFolderKey ?: state.newFolderKey)
        if (folderKey.isBlank() || state.selectedChatIds.isEmpty() || state.isSaving) {
            return
        }
        updateSelectedChats(ChatStateRequest(folderKey = folderKey))
    }

    fun clearSelectedFolders() {
        val state = _uiState.value
        if (state.selectedChatIds.isEmpty() || state.isSaving) {
            return
        }
        updateSelectedChats(ChatStateRequest(folderKey = ""))
    }

    private fun updateSelectedChats(request: ChatStateRequest) {
        val chatIds = _uiState.value.selectedChatIds.toList()
        viewModelScope.launch {
            _uiState.value = _uiState.value.copy(isSaving = true, errorMessage = null)
            runCatching {
                container.executeAuthorized { session ->
                    chatIds.forEach { chatId ->
                        container.apiClient.updateChatState(session.accessToken, chatId, request)
                    }
                }
            }.onSuccess {
                _uiState.value = _uiState.value.copy(isSaving = false, selectedChatIds = emptySet())
                refresh()
            }.onFailure { error ->
                _uiState.value = _uiState.value.copy(isSaving = false, errorMessage = error.message)
            }
        }
    }
}

private fun normalizeFolderKey(value: String): String =
    value.trim()
        .lowercase()
        .replace(Regex("\\s+"), "-")
        .replace(Regex("[^a-z0-9_-]"), "")
        .take(32)
