package space.nstart.pcp_tgu_service.integration.api

import com.fasterxml.jackson.databind.ObjectMapper
import org.springframework.stereotype.Component
import space.nstart.pcp_tgu_service.domain.InsertionPoint
import space.nstart.pcp_tgu_service.domain.ObservationWindow
import space.nstart.pcp_tgu_service.domain.SpacecraftPoints
import space.nstart.pcp_tgu_service.dto.ExternalRvaItemDto
import space.nstart.pcp.pcp_types_lib.utils.UtcDateTimes
import java.time.LocalDateTime
import java.time.temporal.ChronoUnit

/**
 * Парсит raw payload баллистики в доменную модель расчёта без доступа к БД.
 */
@Component
class VisibilityPayloadParser(
    private val objectMapper: ObjectMapper
) {

    /** Группирует RVA records по станциям и сортирует окна для алгоритма планирования. */
    fun parse(spacecraftId: String, payloadJson: String): SpacecraftPoints {
        val response = objectMapper.readValue(payloadJson, Array<ExternalRvaItemDto>::class.java).toList()
        val points = response
            .groupBy { item -> item.stationId }
            .map { (stationId, items) ->
                InsertionPoint(
                    pointId = stationId.toString(),
                    observationWindows = items.map { item ->
                        ObservationWindow(
                            startTime = toLocalDateTime(item.onStart.time),
                            endTime = toLocalDateTime(item.onStop.time),
                            elevationAngle = item.onMaximum.elevation
                        )
                    }.sortedBy { window -> window.startTime }
                )
            }
            .sortedBy { point -> point.pointId }

        return SpacecraftPoints(spacecraftId = spacecraftId, points = points)
    }

    /**
     * Разбирает ISO-строку времени баллистики в UTC-naive `LocalDateTime`.
     *
     * Явные UTC/offset-строки нормализуются в UTC, legacy naive-строки считаются UTC-naive.
     * Обрезаем до микросекунд — это эффективная точность persisted-планов в БД.
     */
    private fun toLocalDateTime(value: String): LocalDateTime =
        UtcDateTimes.parse(value).truncatedTo(ChronoUnit.MICROS)
}
