package com.atridad.ascently.data.database.dao

import androidx.room.*
import com.atridad.ascently.data.model.Attempt
import com.atridad.ascently.data.model.AttemptResult
import kotlinx.coroutines.flow.Flow

@Dao
interface AttemptDao {

    @Query("SELECT * FROM attempts ORDER BY timestamp DESC")
    fun getAllAttempts(): Flow<List<Attempt>>

    @Query("SELECT * FROM attempts WHERE id = :id")
    suspend fun getAttemptById(id: String): Attempt?

    @Query("SELECT * FROM attempts WHERE sessionId = :sessionId ORDER BY timestamp ASC")
    fun getAttemptsBySession(sessionId: String): Flow<List<Attempt>>

    @Query("SELECT * FROM attempts WHERE problemId = :problemId ORDER BY timestamp DESC")
    fun getAttemptsByProblem(problemId: String): Flow<List<Attempt>>

    @Query("SELECT * FROM attempts WHERE sessionId = :sessionId AND problemId = :problemId ORDER BY timestamp ASC")
    fun getAttemptsBySessionAndProblem(sessionId: String, problemId: String): Flow<List<Attempt>>

    @Query("SELECT * FROM attempts WHERE result = :result ORDER BY timestamp DESC")
    fun getAttemptsByResult(result: AttemptResult): Flow<List<Attempt>>

    @Query("SELECT * FROM attempts WHERE timestamp BETWEEN :startDate AND :endDate ORDER BY timestamp DESC")
    fun getAttemptsInDateRange(startDate: String, endDate: String): Flow<List<Attempt>>

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertAttempt(attempt: Attempt)

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertAttempts(attempts: List<Attempt>)

    @Update
    suspend fun updateAttempt(attempt: Attempt)

    @Delete
    suspend fun deleteAttempt(attempt: Attempt)

    @Query("DELETE FROM attempts WHERE id = :id")
    suspend fun deleteAttemptById(id: String)

    @Query("DELETE FROM attempts WHERE sessionId = :sessionId")
    suspend fun deleteAttemptsBySession(sessionId: String)

    @Query("DELETE FROM attempts WHERE problemId = :problemId")
    suspend fun deleteAttemptsByProblem(problemId: String)

    @Query("SELECT COUNT(*) FROM attempts")
    suspend fun getAttemptsCount(): Int

    @Query("DELETE FROM attempts")
    suspend fun deleteAllAttempts()

    @Query("SELECT COUNT(*) FROM attempts WHERE sessionId = :sessionId")
    suspend fun getAttemptsCountBySession(sessionId: String): Int

    @Query("SELECT COUNT(*) FROM attempts WHERE problemId = :problemId")
    suspend fun getAttemptsCountByProblem(problemId: String): Int

    @Query("SELECT COUNT(*) FROM attempts WHERE result = :result")
    suspend fun getAttemptsCountByResult(result: AttemptResult): Int

    @Query("SELECT COUNT(*) FROM attempts WHERE problemId = :problemId AND result IN ('SUCCESS', 'FLASH', 'REDPOINT', 'ONSIGHT')")
    suspend fun getSuccessfulAttemptsCountByProblem(problemId: String): Int

    @Query("SELECT * FROM attempts WHERE problemId = :problemId AND result IN ('SUCCESS', 'FLASH', 'REDPOINT', 'ONSIGHT') ORDER BY timestamp ASC LIMIT 1")
    suspend fun getFirstSuccessfulAttempt(problemId: String): Attempt?

    @Query("SELECT * FROM attempts WHERE problemId = :problemId ORDER BY timestamp DESC LIMIT 1")
    suspend fun getLatestAttemptForProblem(problemId: String): Attempt?
}
