package space.nstart.pcp.tle_monitoring_service.controller

import org.slf4j.LoggerFactory
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.TLEDTO
import space.nstart.pcp.pcp_types_lib.dto.ballistics.TLEExtensionDTO
import space.nstart.pcp.tle_monitoring_service.repository.TLERepository
import space.nstart.pcp.tle_monitoring_service.service.CelesTrakService
import kotlin.system.measureTimeMillis


@RestController
@RequestMapping("v1/api/tle")
class TLEController {

    private val logger = LoggerFactory.getLogger(this::class.java)

    @Autowired
    private lateinit var tleRepository: TLERepository
    @Autowired
    private lateinit var celestrakService: CelesTrakService


    @PostMapping("/satellite/{satelliteId}")
    fun sendTLE(@PathVariable satelliteId: Long, @RequestBody tle : TLEDTO) =
        celestrakService.sendTLE(satelliteId, tle)

    @GetMapping()
    fun all(): List<TLEExtensionDTO> {
        logger.info("TLE API all records request started")
        var records = emptyList<TLEExtensionDTO>()
        val durationMs = measureTimeMillis {
            records = tleRepository.findAll().map { tle -> tle.toDto() }
        }
        logger.info(
            "TLE API all records request completed: records={}, durationMs={}",
            records.size,
            durationMs
        )
        return records
    }

    @GetMapping("/satellite/{satelliteId}")
    fun bySatellite(@PathVariable satelliteId: Long): List<TLEExtensionDTO> {
        logger.info("TLE API satellite records request started: satelliteId={}", satelliteId)
        var records = emptyList<TLEExtensionDTO>()
        val durationMs = measureTimeMillis {
            records = tleRepository.findAllBySatelliteIdOrderByTimeTleAsc(satelliteId).map { tle -> tle.toDto() }
        }
        logger.info(
            "TLE API satellite records request completed: satelliteId={}, records={}, durationMs={}",
            satelliteId,
            records.size,
            durationMs
        )
        return records
    }

    private fun space.nstart.pcp.tle_monitoring_service.entity.TLEEntity.toDto(): TLEExtensionDTO {
        val lines = tle.lines().map { it.trimEnd() }.filter { it.isNotBlank() }
        val header = when {
            lines.size >= 3 -> lines[0]
            else -> null
        }
        val first = when {
            lines.size >= 3 -> lines[1]
            lines.size >= 2 -> lines[0]
            else -> " ".repeat(69)
        }
        val second = when {
            lines.size >= 3 -> lines[2]
            lines.size >= 2 -> lines[1]
            else -> " ".repeat(69)
        }

        return TLEExtensionDTO(
            satelliteId,
            revolution,
            TLEDTO(header, first, second)
        )
    }

//    @GetMapping("/test")
//    fun update() = celestrakService.updateDB()


    @PostMapping("load-array")
    fun arra(@RequestBody data : String, @RequestParam name : String) =
        celestrakService.loadArray(data, name)


    @PostMapping ("check-cycle")
    fun checkCycle(@RequestParam id : Long) =
        celestrakService.checkCycle(id)

    @PostMapping("from-celestrack")
    fun tleFromSource(@RequestParam noradIn : Long, @RequestParam("message") sendMessage : Boolean) =
        celestrakService.getTleByNoradIdRaw(noradIn, false, sendMessage)

}
