package com.syncflow.ui.pairdetail import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import androidx.work.WorkInfo import androidx.work.WorkManager import com.syncflow.data.db.SyncConflictDao import com.syncflow.data.db.SyncEventDao import com.syncflow.data.db.SyncPairDao import com.syncflow.domain.model.SyncStatus import com.syncflow.worker.SyncWorker import dagger.hilt.android.lifecycle.HiltViewModel import com.syncflow.ui.shared.SyncProgress import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch import javax.inject.Inject @HiltViewModel class PairDetailViewModel @Inject constructor( private val syncPairDao: SyncPairDao, private val eventDao: SyncEventDao, private val conflictDao: SyncConflictDao, private val workManager: WorkManager, savedState: SavedStateHandle, ) : ViewModel() { private val pairId = savedState.get("pairId")!! val pair = syncPairDao.observeById(pairId) .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), null) val events = eventDao.observeRecent(pairId) .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), emptyList()) val unresolvedConflicts = conflictDao.observeUnresolvedCount(pairId) .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), 0) val syncProgress = workManager.getWorkInfosByTagFlow("sync_$pairId") .map { infos -> infos.firstOrNull { it.state == WorkInfo.State.RUNNING }?.progress?.let { data -> SyncProgress( uploaded = data.getInt(SyncWorker.KEY_PROGRESS_UPLOADED, 0), downloaded = data.getInt(SyncWorker.KEY_PROGRESS_DOWNLOADED, 0), deleted = data.getInt(SyncWorker.KEY_PROGRESS_DELETED, 0), bytesTransferred = data.getLong(SyncWorker.KEY_PROGRESS_BYTES, 0L), ).takeIf { it.uploaded > 0 || it.downloaded > 0 || it.deleted > 0 } } } .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), null) fun syncNow() { val p = pair.value ?: return workManager.enqueue(SyncWorker.buildOneTimeRequest(p.id, wifiOnly = false, chargingOnly = false)) } fun pauseSync() { val p = pair.value ?: return workManager.cancelAllWorkByTag("sync_${p.id}") viewModelScope.launch { syncPairDao.updateStatus(p.id, SyncStatus.PAUSED) } } fun delete() { viewModelScope.launch { pair.value?.let { syncPairDao.delete(it) } } } }