package space.nstart.pcp.pcp_satellites_service.repository

import jakarta.transaction.Transactional
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.jpa.repository.Modifying
import org.springframework.data.jpa.repository.Query
import org.springframework.data.repository.query.Param
import space.nstart.pcp.pcp_satellites_service.entity.SatelliteModeEntity
import java.time.LocalDateTime

interface SatelliteModeRepository : JpaRepository<SatelliteModeEntity, Long> {

    fun findAllBySnapshot_IdInOrderByStartTimeAsc(
        snapshotIds: Collection<Long>
    ): List<SatelliteModeEntity>

    fun findAllBySnapshot_IdOrderByStartTimeAsc(snapshotId: Long): List<SatelliteModeEntity>

    fun findAllBySnapshot_SatelliteIdInAndSnapshot_IsActiveTrueAndEndTimeGreaterThanAndStartTimeLessThanOrderByStartTimeAsc(
        satelliteIds: Collection<Long>,
        intervalStart: LocalDateTime,
        intervalEnd: LocalDateTime
    ): List<SatelliteModeEntity>

    fun findAllBySnapshot_SatelliteIdInAndSnapshot_IsActiveTrueAndRevolutionInOrderByStartTimeAsc(
        satelliteIds: Collection<Long>,
        revolutions: Collection<Long>
    ): List<SatelliteModeEntity>

    fun findAllBySnapshot_SatelliteIdAndSnapshot_IsActiveTrueAndRevolutionInOrderByStartTimeAsc(
        satelliteId: Long,
        revolutions: Collection<Long>
    ): List<SatelliteModeEntity>

    fun findAllBySnapshot_SatelliteIdAndSnapshot_IsActiveTrueOrderByStartTimeAsc(satelliteId: Long): List<SatelliteModeEntity>

    fun findAllByCellNumOrderByStartTimeAsc(cellNum: Long): List<SatelliteModeEntity>

    fun findAllByComplexPlanRun_IdOrderByStartTimeAsc(runId: Long): List<SatelliteModeEntity>

    fun countByComplexPlanRun_Id(runId: Long): Long

    fun countBySatelliteId(satelliteId: Long): Long

    @Query(
        """
        select entity.id
        from SatelliteModeEntity entity
        where entity.satelliteId in :satelliteIds
          and entity.startTime < :intervalEnd
          and entity.endTime > :intervalStart
        """
    )
    fun findIntersectingIdsBySatelliteIdsAndInterval(
        @Param("satelliteIds") satelliteIds: Collection<Long>,
        @Param("intervalStart") intervalStart: LocalDateTime,
        @Param("intervalEnd") intervalEnd: LocalDateTime
    ): List<Long>

    @Query(
        """
        select distinct entity
        from SatelliteModeEntity entity
        join entity.cells cell
        where cell.cellNum = :cellNum
          and entity.snapshot.isActive = true
        order by entity.startTime asc
        """
    )
    fun findAllByRelatedCellNumOrderByStartTimeAsc(@Param("cellNum") cellNum: Long): List<SatelliteModeEntity>

    @Modifying
    @Transactional
    @Query(
        """
        DELETE FROM satellite_modes
        WHERE satellite_id IN (:satelliteIds)
          AND start_time < :intervalEnd
          AND end_time > :intervalStart
        """,
        nativeQuery = true
    )
    fun deleteIntersectingBySatelliteIdsAndInterval(
        @Param("satelliteIds") satelliteIds: Collection<Long>,
        @Param("intervalStart") intervalStart: LocalDateTime,
        @Param("intervalEnd") intervalEnd: LocalDateTime
    ): Int
}
