package com.isidroid.c23.domain.use_case

import android.content.Context
import com.isidroid.c23.data.mapper.createListItem
import com.isidroid.c23.domain.dto.PrintJobListItem
import com.isidroid.c23.ext.getPrintJobStatus
import com.isidroid.c23.ext.getPrintJobStatusColor
import com.isidroid.core.FlowResult
import com.isidroid.job.repository.JobRepository
import com.isidroid.job_sender.domain.dto.JobSenderResult
import com.isidroid.spot.repository.SpotRepository
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.flow.flow
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class PrintJobsUseCase @Inject constructor(
    @ApplicationContext private val context: Context,
    private val jobRepository: JobRepository,
    private val spotRepository: SpotRepository
) {
    fun load() = flow {
        emit(FlowResult.Loading)
        val jobList = jobRepository.readLocalList()
        val spots = jobList
            .asSequence()
            .sortedByDescending { it.createdAt }
            .map { it.spotId }
            .distinct()
            .let { spotRepository.findLocalRichSpots(it.toList()) }
            ?.associateBy({ it.spot.id }, { it })

        val result = jobList.map { job -> job.createListItem(context = context, richSpot = spots?.get(job.spotId)) }
        emit(FlowResult.Success(result))
    }

    fun findSpot(spotCode: String) = flow {
        emit(FlowResult.Loading)
        val result = spotRepository.findRichSpot(spotCode)?.spot
        emit(FlowResult.Success(result))
    }

    fun updateStatuses(jobs: Collection<PrintJobListItem>?, info: JobSenderResult.Statuses): List<PrintJobListItem>? {
        val list = jobs?.toMutableList() ?: return null

        for (index in list.indices) {
            val job = list[index]
            if (job.id in info.jobIds)
                list[index] = job.copy(
                    statusName = context.getString(getPrintJobStatus(info.status)),
                    statusColor = getPrintJobStatusColor(info.status)
                )
        }

        return list
    }
}