package com.syncflow.ui.browser import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.syncflow.data.providers.ProviderFactory import com.syncflow.data.repository.AccountRepository import com.syncflow.domain.model.RemoteFile import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import javax.inject.Inject data class BrowserState( val accountId: Long = -1L, val currentPath: String = "/", val pathStack: List = listOf("/"), val entries: List = emptyList(), val isLoading: Boolean = false, val error: String? = null, ) @HiltViewModel class RemoteBrowserViewModel @Inject constructor( private val accountRepository: AccountRepository, private val providerFactory: ProviderFactory, ) : ViewModel() { private val _state = MutableStateFlow(BrowserState()) val state = _state.asStateFlow() fun init(accountId: Long, startPath: String = "/") { _state.update { it.copy(accountId = accountId, currentPath = startPath, pathStack = listOf(startPath)) } loadPath(accountId, startPath) } fun navigateTo(path: String) { val accountId = _state.value.accountId _state.update { s -> s.copy(currentPath = path, pathStack = s.pathStack + path) } loadPath(accountId, path) } fun navigateUp(): Boolean { val stack = _state.value.pathStack if (stack.size <= 1) return false val newStack = stack.dropLast(1) val parent = newStack.last() _state.update { it.copy(currentPath = parent, pathStack = newStack) } loadPath(_state.value.accountId, parent) return true } private fun loadPath(accountId: Long, path: String) { viewModelScope.launch { _state.update { it.copy(isLoading = true, error = null) } val account = accountRepository.getAccount(accountId) if (account == null) { _state.update { it.copy(isLoading = false, error = "Account not found") } return@launch } val provider = runCatching { providerFactory.create(account) }.getOrElse { e -> _state.update { it.copy(isLoading = false, error = e.message) } return@launch } provider.listFiles(path) .onSuccess { files -> _state.update { it.copy(isLoading = false, entries = files.sortedWith(compareBy({ !it.isDirectory }, { it.name.lowercase() }))) } } .onFailure { e -> _state.update { it.copy(isLoading = false, error = e.message ?: "Failed to list files") } } } } }