package space.nstart.pcp.pcp_satellites_service.service

import org.springframework.beans.factory.ObjectProvider
import org.springframework.beans.factory.annotation.Value
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
import org.springframework.web.reactive.function.client.WebClient
import space.nstart.pcp.pcp_types_lib.dto.satellite.SatelliteBatchRequestDTO
import space.nstart.pcp.pcp_types_lib.dto.satellite.SatelliteDTO
import space.nstart.pcp.pcp_types_lib.dto.satellite.SatelliteSummaryDTO
import kotlin.system.measureTimeMillis

interface SatelliteCatalogClient {
    fun allSatellites(): List<SatelliteDTO>
}

@Service
class SatelliteCatalogWebClient(
    webClientBuilderProvider: ObjectProvider<WebClient.Builder>
) : SatelliteCatalogClient {

    private val webClientBuilder: WebClient.Builder = webClientBuilderProvider.ifAvailable ?: WebClient.builder()
    private val logger = LoggerFactory.getLogger(this::class.java)

    @Value("\${settings.satellite-catalog-service:pcp-satellite-catalog-service}")
    private val satelliteCatalogServiceUrl = ""

    override fun allSatellites(): List<SatelliteDTO> {
        var summaries = emptyList<SatelliteSummaryDTO>()
        val summariesMs = measureTimeMillis {
            summaries = webClientBuilder.build()
                .get()
                .uri("$satelliteCatalogServiceUrl/api/satellites")
                .retrieve()
                .bodyToFlux(SatelliteSummaryDTO::class.java)
                .collectList()
                .block()
                .orEmpty()
        }
        logger.info(
            "satellite-catalog-service summaries loaded: satellites={}, durationMs={}",
            summaries.size,
            summariesMs
        )
        if (summaries.isEmpty()) {
            return emptyList()
        }

        var satellites = emptyList<SatelliteDTO>()
        val detailsMs = measureTimeMillis {
            satellites = webClientBuilder.build()
                .post()
                .uri("$satelliteCatalogServiceUrl/api/satellites/batch")
                .bodyValue(SatelliteBatchRequestDTO(ids = summaries.map { it.id }))
                .retrieve()
                .bodyToFlux(SatelliteDTO::class.java)
                .collectList()
                .block()
                .orEmpty()
        }
        logger.info(
            "satellite-catalog-service details loaded: requested={}, returned={}, durationMs={}",
            summaries.size,
            satellites.size,
            detailsMs
        )
        return satellites
    }
}
