package llc.arma.fleet.monitor.domain.service

import llc.arma.fleet.monitor.data.entity.BeaconTelemetryPacketEntity
import llc.arma.fleet.monitor.data.repository.BeaconRepository
import llc.arma.fleet.monitor.data.repository.BeaconTelemetryPacketRepository
import llc.arma.fleet.monitor.data.repository.MachineRepository
import llc.arma.fleet.monitor.presentation.model.BeaconTelemetryPayload
import org.springframework.stereotype.Service
import java.time.Instant
import java.time.OffsetDateTime
import java.time.ZoneOffset

@Service
class TelemetryService(
    private val beaconRepository: BeaconRepository,
    private val machineRepository: MachineRepository,
    private val packetRepository: BeaconTelemetryPacketRepository,
) {
    fun registerBeaconTelemetryPacket(payload: BeaconTelemetryPayload): Boolean {
        val beacon = beaconRepository.findByMacAddress(payload.mac) ?: return false
        val machine = machineRepository.findAll().firstOrNull { it.beacon?.id == beacon.id }
        val receivedAt = OffsetDateTime.ofInstant(Instant.ofEpochMilli(payload.timeMillis), ZoneOffset.UTC)

        beacon.lastSeenAt = receivedAt
        machine?.lastDataReceivedAt = receivedAt
        beaconRepository.save(beacon)
        if (machine != null) machineRepository.save(machine)

        packetRepository.save(
            BeaconTelemetryPacketEntity(
                beacon = beacon,
                machine = machine,
                mac = payload.mac,
                vibration = payload.vibration,
                duration = payload.duration,
                timeMillis = payload.timeMillis,
                receivedAt = receivedAt,
            ),
        )

        return true
    }

    fun getBeaconTelemetry(beaconId: Long?, machineId: Long?, startDate: OffsetDateTime, endDate: OffsetDateTime): List<BeaconTelemetryPacketEntity> {
        return when {
            machineId != null -> packetRepository.findByMachineIdAndReceivedAtBetween(machineId, startDate, endDate)
            beaconId != null -> packetRepository.findByBeaconIdAndReceivedAtBetween(beaconId, startDate, endDate)
            else -> packetRepository.findAll().filter { it.receivedAt in startDate..endDate }
        }
    }
}
