package com.isidroid.job_sender

import android.content.Context
import androidx.hilt.work.HiltWorker
import androidx.work.Constraints
import androidx.work.CoroutineWorker
import androidx.work.Data
import androidx.work.ExistingWorkPolicy
import androidx.work.NetworkType
import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkManager
import androidx.work.WorkerParameters
import com.isidroid.job_sender.domain.use_case.SendPrintJobsUseCase
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
import timber.log.Timber
import java.util.UUID
import java.util.concurrent.TimeUnit

@HiltWorker
class SendJobWorker @AssistedInject constructor(
    @Assisted appContext: Context,
    @Assisted workerParams: WorkerParameters,
    private val useCase: SendPrintJobsUseCase,
    private val collector: SendJobEventCollectorFlow
) : CoroutineWorker(appContext, workerParams) {

    override suspend fun doWork(): Result = coroutineScope {
        val collectorJob = launch { runCollector() }

        try {
            useCase.start()
            Result.success()
        } catch (t: Throwable) {
            Timber.e(t)
            Result.failure()
        } finally {
            collectorJob.cancel()
        }
    }

    private suspend fun runCollector() {
        coroutineScope {
            collector.eventsFlow.collect {

            }
        }
    }

    companion object {
        fun create(context: Context) {
            val workManager = WorkManager.getInstance(context)

            val constraints = Constraints.Builder()
                .setRequiredNetworkType(NetworkType.CONNECTED)
                .build()

            val builder = OneTimeWorkRequestBuilder<SendJobWorker>().keepResultsForAtLeast(1, TimeUnit.SECONDS)
            val data = Data.Builder().build()
            val requestBuilder = builder
                .setConstraints(constraints)
                .setInputData(data)
                .setId(UUID.randomUUID())

            // We use KEEP to avoid duplicate runs of SyncRepository
            workManager.beginUniqueWork(SendJobWorker::class.java.simpleName, ExistingWorkPolicy.REPLACE, requestBuilder.build()).enqueue()
        }
    }
}