package space.nstart.pcp_tgu_service.repository

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_tgu_service.entity.SpacecraftSnapshotEntity
import java.time.LocalDateTime

/** Доступ к persisted snapshot КА из НСИ. */
interface SpacecraftSnapshotRepository : JpaRepository<SpacecraftSnapshotEntity, String> {
    /** Возвращает только активные КА для рабочих фоновых процессов. */
    fun findAllByActiveTrue(): List<SpacecraftSnapshotEntity>

    /** Атомарно создаёт или обновляет snapshot КА из НСИ по spacecraftId. */
    @Modifying
    @Query(
        value = """
            INSERT INTO spacecraft_snapshot(
                spacecraft_id,
                norad_id,
                nsi_id,
                business_key,
                name,
                status,
                mission,
                valid_from,
                valid_to,
                active,
                created_at,
                updated_at
            )
            VALUES (
                :spacecraftId,
                :noradId,
                :nsiId,
                :businessKey,
                :name,
                :status,
                :mission,
                :validFrom,
                :validTo,
                TRUE,
                :now,
                :now
            )
            ON CONFLICT (spacecraft_id) DO UPDATE SET
                norad_id = EXCLUDED.norad_id,
                nsi_id = EXCLUDED.nsi_id,
                business_key = EXCLUDED.business_key,
                name = EXCLUDED.name,
                status = EXCLUDED.status,
                mission = EXCLUDED.mission,
                valid_from = EXCLUDED.valid_from,
                valid_to = EXCLUDED.valid_to,
                active = TRUE,
                updated_at = EXCLUDED.updated_at
        """,
        nativeQuery = true
    )
    fun upsertFromNsi(
        @Param("spacecraftId") spacecraftId: String,
        @Param("noradId") noradId: Long,
        @Param("nsiId") nsiId: String?,
        @Param("businessKey") businessKey: String?,
        @Param("name") name: String?,
        @Param("status") status: String?,
        @Param("mission") mission: String?,
        @Param("validFrom") validFrom: LocalDateTime?,
        @Param("validTo") validTo: LocalDateTime?,
        @Param("now") now: LocalDateTime
    ): Int

    /** Деактивирует active snapshots, которых больше нет в allowed set НСИ. */
    @Modifying
    @Query(
        """
            UPDATE SpacecraftSnapshotEntity snapshot
            SET snapshot.active = false,
                snapshot.updatedAt = :now
            WHERE snapshot.active = true
              AND snapshot.spacecraftId NOT IN :spacecraftIds
        """
    )
    fun deactivateMissing(
        @Param("spacecraftIds") spacecraftIds: Collection<String>,
        @Param("now") now: LocalDateTime
    ): Int

    /** Деактивирует все active snapshots, когда НСИ вернул пустой allowed set. */
    @Modifying
    @Query(
        """
            UPDATE SpacecraftSnapshotEntity snapshot
            SET snapshot.active = false,
                snapshot.updatedAt = :now
            WHERE snapshot.active = true
        """
    )
    fun deactivateAllActive(@Param("now") now: LocalDateTime): Int
}
