package space.nstart.pcp.slots_service.controller

import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Controller
import org.springframework.ui.Model
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.DeleteMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.ResponseBody
import reactor.core.publisher.Mono
import space.nstart.pcp.pcp_types_lib.dto.requests.ComplexPlanProcessRequestDTO
import space.nstart.pcp.pcp_types_lib.dto.requests.RequestDTO
import space.nstart.pcp.pcp_types_lib.dto.requests.slots.BookedSlotDTO
import space.nstart.pcp.pcp_types_lib.dto.requests.slots.BookingRequestDTO
import space.nstart.pcp.pcp_types_lib.dto.requests.slots.SlotDTO
import space.nstart.pcp.pcp_types_lib.dto.requests.slots.SurveySlotDTO
import space.nstart.pcp.slots_service.service.EarthService
import space.nstart.pcp.slots_service.service.ComplexMissionService
import space.nstart.pcp.slots_service.service.SlotService
import space.nstart.pcp.slots_service.service.StationService
import java.time.LocalDateTime


@Controller
class MapController {

    @Autowired
    private lateinit var earthService: EarthService
    @Autowired
    private lateinit var complexMissionService: ComplexMissionService
    @Autowired
    private lateinit var stationService: StationService
    @Autowired
    private lateinit var slotService: SlotService


    @GetMapping("/map")
    fun showMap(model: Model): Mono<String> {
        model.addAttribute("requests", earthService.reqs().collectList().block())
        model.addAttribute("satellites", complexMissionService.satellites().collectList().block())
        model.addAttribute("stations", stationService.allStationsOrEmpty())
        return Mono.just("map")
    }

    @PostMapping("/api/requests")
    @ResponseBody
    fun addRequest(@RequestBody request: RequestDTO): RequestDTO? {
        return earthService.addRequest(request)
    }

    @PostMapping("/api/slots/booking/request")
    @ResponseBody
    fun bookRequestSlots(@RequestBody request: BookingRequestDTO): List<BookedSlotDTO> {
        return slotService.bookReq(request)
    }

    @DeleteMapping("/api/slots/booking/request")
    @ResponseBody
    fun cancelRequestBooking(@RequestParam requestId: String): Int {
        return slotService.cancelReq(requestId)
    }

    @GetMapping("/api/satellites/{satelliteId}/booked-slots")
    @ResponseBody
    fun satelliteBookedSlots(
        @PathVariable satelliteId: Long,
        @RequestParam timeStart: LocalDateTime,
        @RequestParam timeStop: LocalDateTime
    ): List<SurveySlotDTO> {
        return slotService.plan(satelliteId, timeStart, timeStop)
            .collectList()
            .block()
            ?: emptyList()
    }

    @GetMapping("/api/satellites/{satelliteId}/slots")
    @ResponseBody
    fun satelliteSlots(
        @PathVariable satelliteId: Long,
        @RequestParam timeStart: LocalDateTime,
        @RequestParam timeStop: LocalDateTime
    ): List<SlotDTO> = slotService.allSlotsByInterval(satelliteId, timeStart, timeStop)

    @PostMapping("/api/com-plan/process")
    @ResponseBody
    fun processComplexPlan(@RequestBody request: ComplexPlanProcessRequestDTO) =
        complexMissionService.processComplexPlan(request)

//    @GetMapping("/map")
//    fun showMap() : Mono<Rendering>{
//        val requests = earthService.reqs().toList()
//
//        return Mono.just(
//            Rendering
//                .view("map")
//                .modelAttribute("requests", requests)
//                .build()
//        )
//    }
}
