package space.nstart.pcp.slots_service.czml

import com.fasterxml.jackson.annotation.JsonIgnoreProperties
import com.fasterxml.jackson.annotation.JsonInclude
import io.swagger.v3.oas.annotations.media.Schema
import lombok.AllArgsConstructor
import lombok.Data
import lombok.NoArgsConstructor
import space.nstart.pcp.pcp_types_lib.dto.ballistics.AscNodeDTO
import space.nstart.pcp.pcp_types_lib.utils.UtcDateTimes
import java.time.LocalDateTime
import java.time.ZoneOffset


@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(description = "Узел CZML")
@JsonInclude(JsonInclude.Include.NON_NULL)
class CZMLPath(
    var show: Boolean = true,
    val width: Int = 1,
    val resolution: Int = 120,
    val material: CZMLMaterial = CZMLMaterial(255, 0, 0, 0),
    var leadTime: Iterable<CZMLInterval> = listOf(),
    var trailTime: Iterable<CZMLInterval> = listOf()
) {

    private fun fromDateTime(t: LocalDateTime) = t.toEpochSecond(ZoneOffset.UTC) + t.nano / 1e9

    private fun utcIso(t: Double): String = UtcDateTimes.format(
        LocalDateTime.ofEpochSecond(t.toLong(), ((t % 1) * 1e9).toInt(), ZoneOffset.UTC)
    )

    constructor(
        vuz: Iterable<AscNodeDTO>, epoch: LocalDateTime, epochStop: LocalDateTime, width: Int, resolution: Int,
        material: CZMLMaterial
    ) : this(width = width, resolution = resolution, material = material) {


        var t = epoch.toEpochSecond(ZoneOffset.UTC).toDouble()
        var lt = mutableListOf<CZMLInterval>()
        var tt = mutableListOf<CZMLInterval>()

        for (v in vuz) {

            var dt = fromDateTime(v.time) - t
            if (dt > 1) {
                lt.add(
                    CZMLInterval(
                        "${utcIso(t)}/${utcIso(fromDateTime(v.time))}",
                        utcIso(t),
                        listOf(0.0, dt, dt, 0.0)
                    )
                )

                tt.add(
                    CZMLInterval(
                        "${utcIso(t)}/${utcIso(fromDateTime(v.time))}",
                        utcIso(t),
                        listOf(0.0, 0.0, dt, dt)
                    )
                )
            }
            t = fromDateTime(v.time)
        }

        var tk = epochStop.toEpochSecond(ZoneOffset.UTC).toDouble()
        var dt = tk - t
        if (dt > 1) {
            lt.add(
                CZMLInterval(
                    "${utcIso(t)}/${utcIso(tk)}",
                    utcIso(t),
                    listOf(0.0, dt, dt, 0.0)
                )
            )

            tt.add(
                CZMLInterval(
                    "${utcIso(t)}/${utcIso(tk)}",
                    utcIso(t),
                    listOf(0.0, 0.0, dt, dt)
                )
            )
        }

        leadTime = lt
        trailTime = tt
    }
}
