package space.nstart.pcp.pcp_mission_planing_service.service


import io.camunda.client.annotation.JobWorker
import io.camunda.client.CamundaClient
import io.camunda.client.api.response.ActivatedJob
import io.camunda.client.api.worker.JobClient
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
import space.nstart.pcp.pcp_types_lib.dto.satellite.mission.MissionRequestDTO
import java.time.LocalDateTime
import java.util.UUID


@Service
class FlowService(
    private val camundaClient: CamundaClient,
    private val missionPlaningService: MissionPlaningService
) {

    private val logger : Logger = LoggerFactory.getLogger(this.javaClass)




    @JobWorker(type = "calculateSatelliteSurveyMissions", autoComplete = false)
    fun surveyPlan(client: JobClient, job: ActivatedJob) {
        try {
            val id = job.variablesAsMap.getOrDefault("satellitePlanId", 0).toString()
            logger.info("Запрос на формирование плана съемки ${id}")

            val mission = missionPlaningService.add(MissionRequestDTO(
                missionId = UUID.fromString(id),
                satelliteId = job.variablesAsMap.getOrDefault("spacecraftId", 0).toString().toLong(),
                missionStart = job.variablesAsMap["planStartTime"]
                ?.toString()
                ?.let(LocalDateTime::parse),
                missionStop = job.variablesAsMap["planEndTime"]
                    ?.toString()
                    ?.let(LocalDateTime::parse)

            ))


            missionPlaningService.loadSlots(mission.missionId)
            val cnt = missionPlaningService.modesByMission(UUID.fromString(id)).size

            client.newCompleteCommand(job.key)
                .variable("modes", cnt)
                .send()
                .exceptionally {
                        ex -> logger.warn(ex.message)
                        throw ex
                    }
        }
        catch (ex : Exception){
            logger.warn(ex.message)
        }
    }

    @JobWorker(type = "calculateSatelliteDropMissions", autoComplete = false)
    fun surveyDrop(client: JobClient, job: ActivatedJob) {
        try {
            val id = job.variablesAsMap.getOrDefault("satellitePlanId", 0).toString()
            logger.info("Запрос на формирование плана сбросов ${id}")

            missionPlaningService.loadSlots(UUID.fromString(id))
            val cnt = missionPlaningService.modesByMission(UUID.fromString(id)).size

            client.newCompleteCommand(job.key)
                .variable("modes", cnt)
                .send()
                .exceptionally {
                        ex -> logger.warn(ex.message)
                    throw ex
                }
        }
        catch (ex : Exception){
            logger.warn(ex.message)
        }
    }

    @JobWorker(type = "sendSatellitePlan", autoComplete = false)
    fun sendPlan(client: JobClient, job: ActivatedJob) {
        try {
            val id = job.variablesAsMap.getOrDefault("satellitePlanId", 0).toString()
            logger.info("Отправлен план ${id}")

            client.newCompleteCommand(job.key)
                .send()
                .exceptionally {
                        ex -> logger.warn(ex.message)
                    throw ex
                }

            Thread.sleep(5000)

            logger.info("Иммитация сообщения о получении подтверждения $id")
            camundaClient
                .newPublishMessageCommand()
                .messageName("Message_SatellitePlanAccepted")
                .correlationKey(id)
                .send()
                .join()
        }
        catch (ex : Exception){
            logger.warn(ex.message)
        }
    }


    @JobWorker(type = "updateSlotsStatus", autoComplete = false)
    fun confirmPlan(client: JobClient, job: ActivatedJob) {
        try {

            logger.info("Утверждение поана")
            val id = job.variablesAsMap.getOrDefault("satellitePlanId", 0).toString()

            val ids = missionPlaningService.confirmMission(UUID.fromString(id))
            logger.info("План утвержден ${id}")
            client.newCompleteCommand(job.key)
                .variable("slots", ids)
                .send()
                .exceptionally {
                        ex -> logger.warn(ex.message)
                    throw ex
                }
        }
        catch (ex : Exception){
            logger.warn(ex.message)
        }
    }

}
