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 PhotoUploadDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun upsert(upload: PhotoUploadEntity)

    @Query("SELECT * FROM photo_uploads WHERE clientRequestId = :clientRequestId LIMIT 1")
    suspend fun find(clientRequestId: String): PhotoUploadEntity?

    @Query(
        """
        SELECT * FROM photo_uploads
        WHERE routeId = :routeId
        AND status != 'CANCELLED'
        ORDER BY createdAtEpochMillis ASC
        """,
    )
    fun observeVisibleForRoute(routeId: String): Flow<List<PhotoUploadEntity>>

    @Query(
        """
        SELECT * FROM photo_uploads
        WHERE status != 'CONFIRMED'
        AND status != 'CANCELLED'
        ORDER BY createdAtEpochMillis ASC
        """,
    )
    fun observeQueuedUploads(): Flow<List<PhotoUploadEntity>>

    @Query(
        """
        SELECT * FROM photo_uploads
        WHERE routeId = :routeId
        AND status = 'CONFIRMED'
        """,
    )
    suspend fun confirmedForRoute(routeId: String): List<PhotoUploadEntity>

    @Query(
        """
        UPDATE photo_uploads
        SET status = :status,
            progress = :progress,
            lastError = :lastError,
            attemptCount = attemptCount + :attemptIncrement,
            updatedAtEpochMillis = :updatedAt
        WHERE clientRequestId = :clientRequestId
        """,
    )
    suspend fun updateStatus(
        clientRequestId: String,
        status: String,
        progress: Int,
        lastError: String?,
        attemptIncrement: Int,
        updatedAt: Long = System.currentTimeMillis(),
    )

    @Query(
        """
        UPDATE photo_uploads
        SET status = 'CONFIRMED',
            progress = 100,
            lastError = NULL,
            serverPhotoId = :serverPhotoId,
            updatedAtEpochMillis = :updatedAt
        WHERE clientRequestId = :clientRequestId
        """,
    )
    suspend fun markConfirmed(
        clientRequestId: String,
        serverPhotoId: String,
        updatedAt: Long = System.currentTimeMillis(),
    )

    @Query("DELETE FROM photo_uploads WHERE clientRequestId = :clientRequestId")
    suspend fun delete(clientRequestId: String)
}
