package space.nstart.pcp.slots_service.rest

import org.junit.jupiter.api.Test
import org.mockito.Mockito.doReturn
import org.mockito.Mockito.mock
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyNoInteractions
import org.springframework.test.util.ReflectionTestUtils
import reactor.core.publisher.Flux
import reactor.core.publisher.Mono
import space.nstart.pcp.pcp_types_lib.dto.satellite.SatelliteInfoDTO
import space.nstart.pcp.pcp_types_lib.dto.satellite.mission.SatelliteModeResponseDTO
import space.nstart.pcp.slots_service.czml.CZMLEntity
import space.nstart.pcp.slots_service.service.CZMLService
import space.nstart.pcp.slots_service.service.ComplexMissionService
import space.nstart.pcp.slots_service.service.SlotService
import java.time.LocalDateTime
import kotlin.test.assertEquals
import kotlin.test.assertTrue

class RequestRestControllerSatFldTest {

    @Test
    fun `plan endpoint forwards runId to satellite plan`() {
        val czmlService = mock(CZMLService::class.java)
        val controller = RequestRestController()
        val timeStart = LocalDateTime.of(2026, 4, 22, 10, 0)
        val timeStop = LocalDateTime.of(2026, 4, 22, 12, 0)

        doReturn(emptyList<CZMLEntity>()).`when`(czmlService)
            .showSatPlan(101L, timeStart, timeStop, 17L)
        ReflectionTestUtils.setField(controller, "czmlService", czmlService)

        val result = controller.plan(
            id = 101L,
            tn = timeStart,
            tk = timeStop,
            runId = 17L
        )

        assertTrue(result.none())
        verify(czmlService).showSatPlan(101L, timeStart, timeStop, 17L)
    }

    @Test
    fun `sat endpoint forwards time interval to satFLD`() {
        val czmlService = mock(CZMLService::class.java)
        val controller = RequestRestController()
        val timeStart = LocalDateTime.of(2026, 4, 21, 10, 0)
        val timeStop = LocalDateTime.of(2026, 4, 21, 12, 0)

        doReturn(emptyList<CZMLEntity>()).`when`(czmlService)
            .satFLD(101L, false, true, true, true, timeStart, timeStop)
        ReflectionTestUtils.setField(controller, "czmlService", czmlService)

        val result = controller.sat(
            id = 101L,
            view = false,
            orbit = true,
            sw = true,
            fl = true,
            tn = timeStart,
            tk = timeStop
        )

        assertTrue(result.none())
        verify(czmlService).satFLD(101L, false, true, true, true, timeStart, timeStop)
    }

    @Test
    fun `satellite plan czml does not depend on slots service`() {
        val service = CZMLService()
        val complexMissionService = mock(ComplexMissionService::class.java)
        val slotService = mock(SlotService::class.java)
        val timeStart = LocalDateTime.of(2026, 5, 18, 15, 20)
        val timeStop = LocalDateTime.of(2026, 6, 1, 15, 20)

        doReturn(Mono.just(SatelliteInfoDTO(noradId = 31L, name = "SAT-31")))
            .`when`(complexMissionService)
            .satellite(31L)
        doReturn(Flux.empty<SatelliteModeResponseDTO>())
            .`when`(complexMissionService)
            .plan(31L, timeStart, timeStop, null)

        ReflectionTestUtils.setField(service, "complexMissionService", complexMissionService)
        ReflectionTestUtils.setField(service, "slotService", slotService)

        val result = service.showSatPlan(31L, timeStart, timeStop).toList()

        assertEquals("document", result.first().id)
        verifyNoInteractions(slotService)
    }
}
