package com.keylightpiano.pianotimeline.data.local

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

@Dao
interface RecordingDao {

    @Query("SELECT * FROM recordings ORDER BY " +
            "substr(date, 7, 4) DESC, " +
            "substr(date, 4, 2) DESC, " +
            "substr(date, 1, 2) DESC")
    fun observeAllByDate(): Flow<List<RecordingEntity>>

    @Query("SELECT id FROM recordings")
    suspend fun getAllIds(): List<String>

    @Query("SELECT id, fileSize FROM recordings")
    suspend fun getIdAndSizes(): List<IdAndSize>

    @Query("SELECT * FROM recordings WHERE id = :id")
    suspend fun getById(id: String): RecordingEntity?

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun upsert(recordings: List<RecordingEntity>)

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun upsert(recording: RecordingEntity)

    @Query("DELETE FROM recordings WHERE id IN (:ids)")
    suspend fun deleteByIds(ids: Set<String>)

    @Query("UPDATE recordings SET cachedAudioPath = NULL, cachedMidiPath = NULL WHERE id = :id")
    suspend fun clearCachedPaths(id: String)

    @Query("UPDATE recordings SET cachedAudioPath = :path WHERE id = :id")
    suspend fun setCachedAudioPath(id: String, path: String)

    @Query("UPDATE recordings SET cachedMidiPath = :path WHERE id = :id")
    suspend fun setCachedMidiPath(id: String, path: String)

    @Query("UPDATE recordings SET cachedAudioPath = NULL, cachedMidiPath = NULL")
    suspend fun clearAllCachedPaths()

    @Query("SELECT COUNT(*) FROM recordings")
    suspend fun count(): Int

    // -- favorite / new state --

    @Query("UPDATE recordings SET isFavorite = :favorite, favoritedAt = :favoritedAt WHERE id = :id")
    suspend fun setFavorite(id: String, favorite: Boolean, favoritedAt: Long)

    @Query("UPDATE recordings SET isNew = :isNew WHERE id = :id")
    suspend fun setNew(id: String, isNew: Boolean)

    /** Mark several recordings as new in one shot (used by sync for added entries). */
    @Query("UPDATE recordings SET isNew = 1 WHERE id IN (:ids)")
    suspend fun markNew(ids: Set<String>)

    /** Clear the "new" flag for a recording (called when its play button is first pressed). */
    @Query("UPDATE recordings SET isNew = 0 WHERE id = :id")
    suspend fun clearNew(id: String)

    /** Clear the "new" flag on every recording (from the Settings screen). */
    @Query("UPDATE recordings SET isNew = 0")
    suspend fun clearAllNew()
}

data class IdAndSize(val id: String, val fileSize: Long)
