package com.ustadmobile.core.db.dao

import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query
import com.ustadmobile.lib.db.composites.OfflineItemAndState
import com.ustadmobile.lib.db.entities.OfflineItem
import kotlin.Any
import kotlin.Boolean
import kotlin.Long
import kotlinx.coroutines.flow.Flow

@Dao
public actual abstract class OfflineItemDao {
  @Insert(
    entity = Any::class,
    onConflict = 3,
  )
  public actual abstract suspend fun insertAsync(item: OfflineItem): Long

  @Query(`value` =
      "\n        SELECT OfflineItem.*,\n               TransferJob.*,\n               \n        (SELECT SUM(TransferJobItem.tjTotalSize)\n                   FROM TransferJobItem\n                  WHERE TransferJobItem.tjiTjUid =  TransferJob.tjUid) AS totalSize,\n                (SELECT SUM(TransferJobItem.tjTransferred)\n                   FROM TransferJobItem\n                  WHERE TransferJobItem.tjiTjUid =  TransferJob.tjUid) AS transferred \n    ,\n               CAST(OfflineItem.oiActive AS INTEGER) = 1 AND (SELECT EXISTS(\n                       SELECT CompletedJob.tjUid\n                         FROM TransferJob CompletedJob\n                        WHERE CompletedJob.tjTableId = 738\n                          AND CompletedJob.tjEntityUid IN  \n                              \n        (SELECT ContentEntryVersion.cevUid\n                         FROM ContentEntryVersion\n                        WHERE ContentEntryVersion.cevContentEntryUid = :contentEntryUid)\n    \n                          AND CompletedJob.tjStatus = 21\n                          AND CompletedJob.tjType = 2\n                          AND CompletedJob.tjTimeCreated >= OfflineItem.oiLct\n                        LIMIT 1      \n               )) AS readyForOffline,\n               NULL AS latestErrorStr\n          FROM OfflineItem\n               LEFT JOIN TransferJob \n                         ON TransferJob.tjUid = \n                         (SELECT TransferJob.tjUid\n                            FROM TransferJob\n                           WHERE TransferJob.tjTableId = 738\n                             AND TransferJob.tjEntityUid IN  \n                                 \n        (SELECT ContentEntryVersion.cevUid\n                         FROM ContentEntryVersion\n                        WHERE ContentEntryVersion.cevContentEntryUid = :contentEntryUid)\n    \n                             AND TransferJob.tjStatus < 21\n                        ORDER BY TransferJob.tjTimeCreated DESC     \n                           LIMIT 1)\n         WHERE OfflineItem.oiNodeId = :nodeId\n           AND OfflineItem.oiContentEntryUid = :contentEntryUid\n      ORDER BY OfflineItem.oiLct DESC\n         LIMIT 1     \n    ")
  public actual abstract fun findByContentEntryUid(contentEntryUid: Long, nodeId: Long):
      Flow<OfflineItemAndState?>

  @Query(`value` =
      "\n        UPDATE OfflineItem\n           SET oiActive = :active\n         WHERE oiUid = :oiUid   \n    ")
  public actual abstract suspend fun updateActiveByOfflineItemUid(oiUid: Long, active: Boolean)
}
