package ballistics.flightLine

import ballistics.Ballistics
import ballistics.types.BallisticsError
import ballistics.types.EarthType
import ballistics.types.InitialConditions
import ballistics.types.IntegrationType
import ballistics.types.ModDVType
import ballistics.types.OrbitalPoint
import ballistics.types.WorkCSType
import ballistics.utils.math.Vector3D
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
import java.time.LocalDateTime
import java.time.ZoneOffset
import kotlin.math.PI

internal class FlightLineCalculatorTest {
    @Test
    fun testFL() {
        var r = Ballistics()

        r.earthType = EarthType.PZ90d02
        r.modDVType = ModDVType.FOTO
        r.integrationType = IntegrationType.ADAMS7
        r.workCoordinateSystem = WorkCSType.WCSOrbit
        r.rollMax = 30 * PI / 180

        var mnu = mutableListOf<InitialConditions>()
        var tt1 = LocalDateTime.of(2023, 6, 20, 4, 18, 40, 180000000)
        var tt2 = LocalDateTime.of(2023, 6, 19, 3, 17, 49, 251000000)

        mnu.add(
            InitialConditions(
                OrbitalPoint(
                    tt1.toEpochSecond(ZoneOffset.UTC).toDouble(), // 1687238300.0,
                    18721,
                    Vector3D(
                        -6603039.949152646,
                        -1870023.1481177735,
                        0.0,
                    ),
                    Vector3D(
                        -401.5289935173786,
                        1413.4309568106378,
                        7547.69556621523,
                    ),
                ),
                0.014542,
                125.0,
            ),
        )
        mnu.add(
            InitialConditions(
                OrbitalPoint(
                    tt2.toEpochSecond(ZoneOffset.UTC).toDouble(), // 1687238300.0,
                    18705,
                    Vector3D(
                        -5880984.961878717,
                        -3535801.795084351,
                        0.0,
                    ),
                    Vector3D(
                        -759.5481166352387,
                        1257.702405545223,
                        7548.463786464257,
                    ),
                ),
                0.014542,
                125.0,
            ),
        )

        mnu.sortBy { it.point.t }

        var t = LocalDateTime.now().toEpochSecond(ZoneOffset.UTC)
        var rez = r.calculateOrbPoints(mnu.toTypedArray(), mnu.first().point.t, mnu.first().point.t + 86400.0 * 3)
        var t2 = LocalDateTime.now().toEpochSecond(ZoneOffset.UTC)
        println("расчет точек орибты за ${t2 - t} с")

//        for (fl in r.points)
//            println("${fl.vit}  ${LocalDateTime.ofEpochSecond(fl.t.toLong(),0, ZoneOffset.UTC)} ${fl.r}")

        if (rez == BallisticsError.OK) {
            t = LocalDateTime.now().toEpochSecond(ZoneOffset.UTC)
            var rezfl = r.calculateFlightLine(mnu.first().point.t, mnu.first().point.t + 86400.0 * 3)
            t2 = LocalDateTime.now().toEpochSecond(ZoneOffset.UTC)
            println("расчет ТП и ПО за ${t2 - t} с")
            for (fl in r.flightLine) {
                println(
                    "${fl.vit}  ${LocalDateTime.ofEpochSecond(fl.t.toLong(),0, ZoneOffset.UTC)}  " +
                        " ${fl.leftOuterSwath.lat * 180.0 / PI}  ${fl.leftOuterSwath.long * 180 / PI}   " +
                        " ${fl.flightLine.lat * 180.0 / PI}  ${fl.flightLine.long * 180 / PI}   " +
                        " ${fl.rightOuterSwath.lat * 180.0 / PI}  ${fl.rightOuterSwath.long * 180 / PI}",
                )
            }
//            assertEquals(/* expected = */BallisticsError.OK, /* actual = */rezfl )
        }

        /*var opKatObj = mutableListOf<OPKatObj>()
        var b = -PI/ 2
        var l = 0.0
        while (b <= PI /2){
            while (l <= PI * 2){
                opKatObj.add(OPKatObj(1,1,1,b,l,0.0,0.0,PI/2,0.0))
                l += 0.2 * PI / 180
            }
            b += 0.2 * PI / 180
            l = 0.0
        }
        println(opKatObj.count())
        t = LocalDateTime.now().toEpochSecond(ZoneOffset.UTC)

        rez= r.calculateMPL(mnu.first().point.t, mnu.first().point.t+86400.0 * 3, opKatObj)

        t2 = LocalDateTime.now().toEpochSecond(ZoneOffset.UTC)

        println(r.mpl.count())

        println("расчет МПЛ за ${t2-t}")*/

//        println("$rez")
//        for (t in r.mpl)
//            println("${t.vit}  ${LocalDateTime.ofEpochSecond(t.traverz.toLong(),(t.traverz %1 * 1e9).toInt(), ZoneOffset.UTC)}  ${t.orientation.kren * 180.0 / PI}" +
//                    " ${t.range}  ${t.sunAngle * 180 / PI}")

        assertEquals(
            // expected =
            BallisticsError.OK,
            // actual =
            rez,
        )
    }
}
