package com.github.nullptroma.wallenc.ui.screens.main.screens.tasks

import androidx.lifecycle.ViewModel
import com.github.nullptroma.wallenc.domain.tasks.ITaskOrchestrator
import com.github.nullptroma.wallenc.domain.tasks.TaskLogLevel
import com.github.nullptroma.wallenc.domain.tasks.TaskProgressLabel
import com.github.nullptroma.wallenc.ui.R
import com.github.nullptroma.wallenc.ui.resources.UiStringResolver
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import javax.inject.Inject

@HiltViewModel
class TaskPipelineViewModel @Inject constructor(
    val orchestrator: ITaskOrchestrator,
    private val uiStrings: UiStringResolver,
) : ViewModel() {

    fun startTestTask(durationSec: Int, infinityIndeterminateProgress: Boolean) {
        val safeDurationSec = durationSec.coerceIn(0, 60)
        val title =
            if (infinityIndeterminateProgress) {
                uiStrings(R.string.task_pipeline_test_running_infinity, safeDurationSec)
            } else {
                uiStrings(R.string.task_pipeline_test_running, safeDurationSec)
            }
        orchestrator.enqueue(
            title = title,
            dispatcher = Dispatchers.Default,
            work = { ctx ->
                val steps = if (safeDurationSec == 0) 1 else safeDurationSec * 10
                ctx.log(TaskLogLevel.Info, uiStrings(R.string.task_log_test_started, safeDurationSec))
                for (step in 0..steps) {
                    val fraction = step.toFloat() / steps.toFloat()
                    val elapsedSec = ((fraction * safeDurationSec * 1000).toInt()) / 1000
                    ctx.reportProgress(
                        fraction = if (infinityIndeterminateProgress) null else fraction,
                        label = TaskProgressLabel.TestElapsed(elapsedSec, safeDurationSec),
                    )
                    if (step < steps) delay(100)
                }
                ctx.log(TaskLogLevel.Info, uiStrings(R.string.task_log_test_finished))
            },
        )
    }
}
