package space.nstart.pcp.slots_service.controller

import org.springframework.beans.factory.annotation.Autowired
import org.springframework.web.bind.annotation.DeleteMapping
import org.springframework.web.bind.annotation.GetMapping
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.RequestMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.server.ResponseStatusException
import space.nstart.pcp.pcp_types_lib.dto.requests.slots.BookingRequestDTO
import space.nstart.pcp.pcp_types_lib.dto.requests.slots.SlotBookingRequestDTO
import java.time.LocalDateTime
import org.slf4j.LoggerFactory
import org.springframework.http.HttpStatus
import space.nstart.pcp.slots_service.service.SlotService


@RestController
@RequestMapping("/api/slots/booking")
class BookingController {
    private val logger = LoggerFactory.getLogger(this::class.java)

    @Autowired
    private lateinit var slotService: SlotService

    @GetMapping
    fun all() = slotService.allBooked()

    @GetMapping("/search")
    fun search(
        @RequestParam(required = false) timeStart: LocalDateTime?,
        @RequestParam(required = false) timeStop: LocalDateTime?,
        @RequestParam(required = false) requestId: String?,
        @RequestParam(required = false) satelliteIds: List<Long>?
    ) = slotService.searchBookedSlots(
        timeStart = timeStart,
        timeStop = timeStop,
        requestId = requestId,
        satelliteIds = satelliteIds
    )

    @GetMapping("/{booked_slot_id}")
    fun byId(@PathVariable("booked_slot_id") id : Long) = slotService.bookedById(id)
    @GetMapping("/by-request/{request_id}")
    fun byId(@PathVariable("request_id") id : String) = slotService.bookedByReqId(id)

    @PostMapping()
    fun bookSlot(@RequestBody req : SlotBookingRequestDTO) = slotService.bookSlot(req)
    // Снятие одной брони: request-aware (см. SlotService.cancelSlot) — нужен requestId,
    // чтобы при шаренном слоте порвать только связь этой заявки, а не снести бронь у других.
    @DeleteMapping
    fun cancelSlot(@RequestParam("id") id : Long, @RequestParam requestId : String) =
        slotService.cancelSlot(requestId, id)
    // Снятие выбранных броней пачкой (фронт чанкует по 200). Список id в query (?ids=1&ids=2),
    // а не в теле — тело у DELETE через gateway ненадёжно.
    @DeleteMapping("batch")
    fun cancelBatch(@RequestParam requestId : String, @RequestParam ids : List<Long>) =
        slotService.cancelReqSlots(requestId, ids)
    @PostMapping("request")
    fun bookReq(@RequestBody req : BookingRequestDTO) =
        slotService.bookReq(req)
    @DeleteMapping("request")
    fun deleteRequestBooking(@RequestParam requestId : String) =
        slotService.cancelReq(requestId)

    /**
     * Legacy HTTP path intentionally retired.
     * Booked slots lifecycle is Kafka-first and mission-planning must publish Kafka events instead.
     */
    @Deprecated("Booked slots status changes are Kafka-first; use booked slots Kafka events instead")
    @PostMapping("process")
    fun processBookedSlots(@RequestBody bookedSlotIds: List<Long>): Nothing {
        logger.warn(
            "Rejected legacy HTTP booked slots processing request for {} ids. Kafka lifecycle is the only supported primary path.",
            bookedSlotIds.distinct().size
        )
        throw ResponseStatusException(
            HttpStatus.GONE,
            "Legacy booked slots HTTP processing is retired. Publish booked slots status changes via Kafka."
        )
    }

}
