package space.nstart.pcp_tgu_service.dto

import com.fasterxml.jackson.core.JsonGenerator
import com.fasterxml.jackson.databind.JsonSerializer
import com.fasterxml.jackson.databind.SerializerProvider
import com.fasterxml.jackson.databind.SerializationFeature
import com.fasterxml.jackson.databind.module.SimpleModule
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertFalse
import org.junit.jupiter.api.Test
import space.nstart.pcp_tgu_service.entity.PlannedPlanStatus
import space.nstart.pcp.pcp_types_lib.utils.UtcDateTimes
import java.time.LocalDateTime
import java.util.UUID

/**
 * Контракт формата времени на проводе для [PlanResponse]: UTC-naive `LocalDateTime` → ISO UTC с Z
 * (напр. `"2026-05-29T01:00:00Z"`). Тест ловит случайный возврат к naive-строкам или числовым меткам.
 */
class PlanResponseContractTest {

    private val mapper = jacksonObjectMapper().findAndRegisterModules()
        .registerModule(
            SimpleModule().addSerializer(LocalDateTime::class.java, object : JsonSerializer<LocalDateTime>() {
                override fun serialize(value: LocalDateTime, gen: JsonGenerator, serializers: SerializerProvider) {
                    gen.writeString(UtcDateTimes.format(value))
                }
            })
        )
        .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)

    @Test
    fun `serializes plan times as UTC ISO with Z`() {
        val response = PlanResponse(
            planId = UUID.fromString("00000000-0000-0000-0000-000000000001"),
            spacecraftId = "25544",
            startTime = LocalDateTime.of(2026, 5, 29, 1, 0, 0),
            endTime = LocalDateTime.of(2026, 5, 29, 2, 0, 0),
            kppId = "KPP-1",
            status = PlannedPlanStatus.PLANNED
        )

        val node = mapper.readTree(mapper.writeValueAsString(response))

        assertEquals("2026-05-29T01:00:00Z", node.get("startTime").asText())
        assertEquals("2026-05-29T02:00:00Z", node.get("endTime").asText())
        assertFalse(node.get("startTime").asText().contains("["), "не ожидался zoned date-time с ID зоны")
    }
}
