package com.ustadmobile.core.db.dao

import androidx.paging.PagingSource
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query
import androidx.room.RawQuery
import androidx.room.Update
import com.ustadmobile.door.DoorQuery
import com.ustadmobile.lib.db.entities.Report
import kotlin.Any
import kotlin.Boolean
import kotlin.Int
import kotlin.Long
import kotlin.String
import kotlin.collections.List
import kotlinx.coroutines.flow.Flow

@Dao
public actual abstract class ReportDao : BaseDao<Report> {
  @RawQuery(observedEntities = arrayOf())
  public actual abstract fun getResults(query: DoorQuery): List<Report>

  @Query(`value` =
      "SELECT * FROM REPORT WHERE NOT reportInactive \n        AND reportOwnerUid = :personUid\n        AND isTemplate = :isTemplate\n        AND reportTitle LIKE :searchBit\n        ORDER BY priority, CASE(:sortOrder)\n            WHEN 1 THEN Report.reportTitle\n            ELSE ''\n        END ASC,\n        CASE(:sortOrder)\n            WHEN 2 THEN Report.reportTitle\n            ELSE ''\n        END DESC\n            ")
  public actual abstract fun findAllActiveReport(
    searchBit: String,
    personUid: Long,
    sortOrder: Int,
    isTemplate: Boolean,
  ): PagingSource<Int, Report>

  @Query(`value` = "SELECT * FROM Report WHERE reportUid = :entityUid")
  public actual abstract suspend fun findByUid(entityUid: Long): Report?

  @Update(
    entity = Any::class,
    onConflict = 3,
  )
  public actual abstract suspend fun updateAsync(entity: Report)

  @Query(`value` = "SELECT * From Report WHERE  reportUid = :uid")
  public actual abstract fun findByUidLive(uid: Long): Flow<Report?>

  @Query(`value` =
      "SELECT * FROM REPORT WHERE NOT reportInactive \n        AND isTemplate = :isTemplate\n        ORDER BY priority ASC\n            ")
  public actual abstract fun findAllActiveReportLive(isTemplate: Boolean): Flow<List<Report>>

  @Query(`value` =
      "SELECT * FROM REPORT WHERE NOT reportInactive \n        AND isTemplate = :isTemplate\n        ORDER BY priority ASC\n            ")
  public actual abstract fun findAllActiveReportList(isTemplate: Boolean): List<Report>

  @Query(`value` = "SELECT reportUid FROM Report WHERE reportUid IN (:uidList)")
  public actual abstract fun findByUidList(uidList: List<Long>): List<Long>

  @Query(`value` =
      "\n        UPDATE Report \n           SET reportInactive = :toggleVisibility,\n               reportLct = :updateTime \n         WHERE reportUid IN (:selectedItem)\n    ")
  public actual abstract suspend fun toggleVisibilityReportItems(
    toggleVisibility: Boolean,
    selectedItem: List<Long>,
    updateTime: Long,
  )

  @Insert(
    onConflict = 1,
    entity = Any::class,
  )
  public actual abstract fun replaceList(entityList: List<Report>)
}
