package space.nstart.pcp.pcp_types_lib.dto.satellite.mission

import com.fasterxml.jackson.annotation.JsonProperty
import com.fasterxml.jackson.annotation.JsonSubTypes
import com.fasterxml.jackson.annotation.JsonTypeInfo
import io.swagger.v3.oas.annotations.media.Schema
import java.time.LocalDateTime

@Schema(
    description = "Базовая модель режима",
    discriminatorProperty = "type",
    oneOf = [SurveyModeResponseDTO::class, DropModeResponseDTO::class]
)
@JsonTypeInfo(
    use = JsonTypeInfo.Id.NAME,
    include = JsonTypeInfo.As.EXISTING_PROPERTY,
    property = "type",
    visible = true
)
@JsonSubTypes(
    JsonSubTypes.Type(value = SurveyModeResponseDTO::class, name = "SURVEY"),
    JsonSubTypes.Type(value = DropModeResponseDTO::class, name = "DROP")
)
sealed interface ModeResponseDTO {
    @get:Schema(description = "Идентификатор режима")
    val id: Long

    @get:Schema(description = "Идентификатор плана")
    val planId: Long

    @get:Schema(description = "Время начала режима")
    val timeStart: LocalDateTime?

    @get:Schema(description = "Номер витка")
    val revolution: Long

    @get:Schema(description = "Тип режима", allowableValues = ["SURVEY", "DROP"])
    val type: String

    @get:Schema(description = "Объём режима, Мбайт (накопление съёмки 120 Мбайт/с, сброс — канал 1200 Мбит/с)")
    @get:JsonProperty(access = JsonProperty.Access.READ_ONLY)
    val volumeMb: Double
}

@Schema(description = "Режим съемки")
data class SurveyModeResponseDTO(
    override val id: Long = 0,
    override val planId: Long = 0,
    override val timeStart: LocalDateTime? = null,
    override val revolution: Long = 0,
    override val type: String = "SURVEY",
    val status: String = "",
    val satelliteModeId: Long? = null,
    val source: String = "",
    val lat: Double = 0.0,
    val longitude: Double =0.0,
    val duration: Double = 0.0,
    val contourWkt: String? = "",
    val roll: Double = 0.0,
    @get:Schema(description = "Идентификаторы забронированных слотов")
    val bookedSlotIds: List<Long> = emptyList()
) : ModeResponseDTO {
    @get:JsonProperty(access = JsonProperty.Access.READ_ONLY)
    override val volumeMb: Double get() = ModeDataRates.surveyVolumeMb(duration)
}

@Schema(description = "Режим сброса")
data class DropModeResponseDTO(
    override val id: Long = 0,
    override val planId: Long = 0,
    override val timeStart: LocalDateTime? = null,
    override val revolution: Long = 0,
    override val type: String = "DROP",
    val station: String? = "",
    val duration: Double = 0.0,
    val surveys: List<Long> = emptyList()
) : ModeResponseDTO {
    @get:JsonProperty(access = JsonProperty.Access.READ_ONLY)
    override val volumeMb: Double get() = ModeDataRates.dropVolumeMb(duration)
}
