package com.github.nullptroma.wallenc.usecases

import com.github.nullptroma.wallenc.domain.interfaces.IStorageSyncGroupStore
import com.github.nullptroma.wallenc.domain.interfaces.IVaultsManager
import kotlinx.coroutines.delay
import kotlin.coroutines.coroutineContext
import kotlinx.coroutines.ensureActive
import javax.inject.Inject
import javax.inject.Singleton

/**
 * Ожидание готовности хранилищ перед синхронизацией (холодный старт из WorkManager).
 */
@Singleton
class StorageSyncReadiness @Inject constructor(
    private val vaultsManager: IVaultsManager,
    private val groupStore: IStorageSyncGroupStore,
    private val findStorageUseCase: FindStorageUseCase,
) {
    suspend fun awaitReady(
        timeoutMs: Long = DEFAULT_TIMEOUT_MS,
        pollIntervalMs: Long = POLL_INTERVAL_MS,
    ) {
        val groups = groupStore.getGroups()
        if (groups.isEmpty()) {
            return
        }
        val requiredUuids = groups.flatMap { it.storageUuids }.toSet()
        val deadline = System.currentTimeMillis() + timeoutMs

        while (System.currentTimeMillis() < deadline) {
            coroutineContext.ensureActive()
            if (!isAnyVaultScanning()) {
                break
            }
            delay(pollIntervalMs)
        }

        while (System.currentTimeMillis() < deadline) {
            coroutineContext.ensureActive()
            if (requiredUuids.all { uuid -> findStorageUseCase.find(uuid) != null }) {
                return
            }
            delay(pollIntervalMs)
        }
    }

    private fun isAnyVaultScanning(): Boolean =
        vaultsManager.vaults.value.any { it.storagesScanInProgress.value }

    private companion object {
        private const val DEFAULT_TIMEOUT_MS = 120_000L
        private const val POLL_INTERVAL_MS = 250L
    }
}
