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<Long>("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) }
        }
    }
}
