package space.nstart.pcp.slots_service.controller

import jakarta.validation.Valid
import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.Parameter
import io.swagger.v3.oas.annotations.media.ArraySchema
import io.swagger.v3.oas.annotations.media.Content
import io.swagger.v3.oas.annotations.media.Schema
import io.swagger.v3.oas.annotations.responses.ApiResponse
import io.swagger.v3.oas.annotations.responses.ApiResponses
import org.apache.kafka.common.protocol.types.Field
import org.springframework.beans.factory.annotation.Autowired
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 space.nstart.pcp.pcp_types_lib.dto.ballistics.RevolutionSign
import space.nstart.pcp.pcp_types_lib.dto.requests.slots.SlotCoverageBatchRequestDTO
import space.nstart.pcp.pcp_types_lib.dto.requests.slots.SlotCoverageStrategy
import space.nstart.pcp.pcp_types_lib.dto.requests.slots.SlotDTO
import space.nstart.pcp.slots_service.service.SlotService
import java.time.LocalDateTime


@RestController
@RequestMapping("api/slots")
class SlotController {

    @Autowired
    private lateinit var slotService: SlotService


    @Operation(summary = "Формирование слотов замкнутых орбит")
    @PostMapping("test-init")
    fun init(@RequestParam sats : List<Long>,
             @RequestParam slotDuration: Long,
             @RequestParam dailyDuration : Long,
             @RequestParam revolutionDuration : Long,
             @RequestParam recover : Boolean?
             ) = slotService.init(sats, slotDuration, dailyDuration, revolutionDuration, recover)


    @Operation(summary = "Расчет покрытие площади")
    @GetMapping("poly-cover")
    fun cover(
        @Parameter(description = "Контур полигона", example = "POLYGON ((10 15, 12 17, 14 17, 16 15, 14 13, 12 13, 10 15))")
        @RequestParam wkt : String,
        @Parameter(description = "Время начала", example = "2026-02-05T00:00:00.000")
        @RequestParam timeStart : LocalDateTime,
        @Parameter(description = "Время конца", example = "2026-02-06T00:00:00.000")
        @RequestParam timeStop : LocalDateTime,
        @Parameter(description = "Признак ветви")
        @RequestParam("revSign") sign : RevolutionSign?,
        @Parameter(description = "Признак расчета покрытия")
        @RequestParam("cov") cov : Boolean?,
        @Parameter(description = "Список КА")
        @RequestParam("satellites") satellites : List<Long>?,
        @Parameter(description = "Угол Солнца, град")
        @RequestParam("sun") sun : Double?,
        @Parameter(description = "Вариант расчета покрытия")
        @RequestParam("coverageStrategy", required = false) coverageStrategy: SlotCoverageStrategy?,
    )
    = slotService.polySlots(wkt, timeStart, timeStop, sign, cov, null, satellites, sun, coverageStrategy)

    @PostMapping("poly-cover/batch")
    fun coverBatch(@Valid @RequestBody body: SlotCoverageBatchRequestDTO) =
        slotService.polySlotsBatch(body)


    @GetMapping("request-cover")
    @Operation(summary = "Расчет покрытие заявки")
    @ApiResponses(
        value = [
            ApiResponse(
                responseCode = "200",
                description = "Слоты покрытия заявки",
                content = [
                    Content(
                        mediaType = "application/json",
                        array = ArraySchema(schema = Schema(implementation = SlotDTO::class))
                    )
                ]
            )
        ]
    )
    fun coverReq(
        @Parameter(description = "Id")
        @RequestParam requestId : String,
        @Parameter(description = "Время начала", example = "2026-02-05T00:00:00.000")
        @RequestParam timeStart : LocalDateTime,
        @Parameter(description = "Время конца", example = "2026-02-06T00:00:00.000")
        @RequestParam timeStop : LocalDateTime,
        @Parameter(description = "Признак ветви")
        @RequestParam("revSign") sign : RevolutionSign?,
        @Parameter(description = "Признак расчета покрытия")
        @RequestParam("cov") cov : Boolean?,
        @Parameter(description = "Список КА")
        @RequestParam("satellites") satellites : List<Long>?,
        @Parameter(description = "Угол Солнца, град")
        @RequestParam("sun") sun : Double?,
        @Parameter(description = "Вариант расчета покрытия")
        @RequestParam("coverageStrategy", required = false) coverageStrategy: SlotCoverageStrategy?,
        @Parameter(description = "Вернуть и занятые бронью слоты (BUSY) — для обзора; по умолчанию только доступные/забронированные")
        @RequestParam("all", required = false) all: Boolean?,
    ) : List<SlotDTO>
            = slotService.reqCover(requestId, timeStart, timeStop, sign, cov, satellites, sun, coverageStrategy, all == true).toList()

    @GetMapping("interval")
    @Operation(summary = "Получение всех слотов на заданном интервале времени")
    fun allByInterval(
        @Parameter(description = "Идентификатор спутника")
        @RequestParam satelliteId: Long,
        @Parameter(description = "Время начала", example = "2026-02-05T00:00:00.000")
        @RequestParam timeStart: LocalDateTime,
        @Parameter(description = "Время конца", example = "2026-02-06T00:00:00.000")
        @RequestParam timeStop: LocalDateTime,
    ): List<SlotDTO> = slotService.allByInterval(satelliteId, timeStart, timeStop)

    @GetMapping("calculation-summary")
    @Operation(summary = "Получение сводки рассчитанных слотов по спутникам")
    fun calculationSummary(
        @Parameter(description = "Список идентификаторов спутников")
        @RequestParam satelliteIds: List<Long>
    ) = slotService.slotCalculationSummaries(satelliteIds)


}
