package pl.firmatpp.kierowca.data.upload

import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import kotlinx.coroutines.flow.Flow

@Dao
interface RoutePointDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun upsert(point: RoutePointEntity)

    @Query(
        """
        SELECT * FROM route_points
        WHERE routeId = :routeId
        AND status IN ('PENDING', 'SYNCING', 'FAILED_RETRYABLE')
        ORDER BY timestamp ASC
        LIMIT :limit
        """,
    )
    suspend fun pendingForRoute(routeId: String, limit: Int): List<RoutePointEntity>

    @Query(
        """
        SELECT COUNT(*) FROM route_points
        WHERE routeId = :routeId
        AND status IN ('PENDING', 'SYNCING', 'FAILED_RETRYABLE')
        """,
    )
    suspend fun pendingCount(routeId: String): Int

    @Query("SELECT * FROM route_points WHERE status != 'CONFIRMED'")
    suspend fun allUnsent(): List<RoutePointEntity>

    @Query("SELECT COUNT(*) FROM route_points WHERE status IN ('PENDING', 'SYNCING', 'FAILED_RETRYABLE')")
    fun observeUnsentCount(): Flow<Int>

    @Query("SELECT MIN(createdAtEpochMillis) FROM route_points WHERE status IN ('PENDING', 'SYNCING', 'FAILED_RETRYABLE')")
    fun observeOldestUnsentAt(): Flow<Long?>

    @Query(
        """
        UPDATE route_points
        SET status = :status,
            lastError = :lastError,
            attemptCount = attemptCount + :attemptIncrement,
            updatedAtEpochMillis = :updatedAt
        WHERE clientPointId IN (:clientPointIds)
        """,
    )
    suspend fun updateStatus(
        clientPointIds: List<String>,
        status: String,
        lastError: String?,
        attemptIncrement: Int,
        updatedAt: Long = System.currentTimeMillis(),
    )

    @Query("DELETE FROM route_points WHERE clientPointId IN (:clientPointIds)")
    suspend fun delete(clientPointIds: List<String>)

    @Query("DELETE FROM route_points")
    suspend fun deleteAll()
}
