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

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

    @Query("SELECT * FROM dispatch_sheet_uploads WHERE status != 'CONFIRMED' AND status != 'CANCELLED'")
    suspend fun allUnsent(): List<DispatchSheetUploadEntity>

    @Query("SELECT * FROM dispatch_sheet_uploads")
    suspend fun allRecords(): List<DispatchSheetUploadEntity>

    @Query("SELECT COUNT(*) FROM dispatch_sheet_uploads WHERE status != 'CONFIRMED' AND status != 'CANCELLED'")
    fun observeUnsentCount(): Flow<Int>

    @Query(
        """
        SELECT * FROM dispatch_sheet_uploads
        WHERE workDate = :workDate
        AND status != 'CANCELLED'
        ORDER BY createdAtEpochMillis ASC
        """,
    )
    fun observeVisibleForWorkDate(workDate: String): Flow<List<DispatchSheetUploadEntity>>

    @Query(
        """
        UPDATE dispatch_sheet_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 dispatch_sheet_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 dispatch_sheet_uploads WHERE clientRequestId = :clientRequestId")
    suspend fun delete(clientRequestId: String)

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