package com.ustadmobile.core.db.dao

import androidx.lifecycle.LiveData
import androidx.paging.DataSource
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
import com.ustadmobile.lib.db.entities.LeavingReason
import com.ustadmobile.lib.db.entities.UidAndLabel
import kotlin.Int
import kotlin.Long
import kotlin.Unit
import kotlin.collections.List

@Dao
public actual abstract class LeavingReasonDao : BaseDao<LeavingReason> {
  @Query(`value` =
      "\n         REPLACE INTO LeavingReasonReplicate(lrPk, lrDestination)\n          SELECT DISTINCT LeavingReason.leavingReasonUid AS lrPk,\n                 :newNodeId AS lrDestination\n            FROM LeavingReason\n           WHERE LeavingReason.leavingReasonLct != COALESCE(\n                 (SELECT lrVersionId\n                    FROM LeavingReasonReplicate\n                   WHERE lrPk = LeavingReason.leavingReasonUid\n                     AND lrDestination = :newNodeId), 0) \n          /*psql ON CONFLICT(lrPk, lrDestination) DO UPDATE\n                 SET lrPending = true\n          */       \n     ")
  public actual abstract suspend fun replicateOnNewNode(newNodeId: Long): Unit

  @Query(`value` =
      "\n REPLACE INTO LeavingReasonReplicate(lrPk, lrDestination)\n  SELECT DISTINCT LeavingReason.leavingReasonUid AS lrUid,\n         UserSession.usClientNodeId AS lrDestination\n    FROM ChangeLog\n         JOIN LeavingReason\n              ON ChangeLog.chTableId = 410\n                 AND ChangeLog.chEntityPk = LeavingReason.leavingReasonUid\n         JOIN UserSession \n              ON UserSession.usStatus = 1\n   WHERE UserSession.usClientNodeId != (\n         SELECT nodeClientId \n           FROM SyncNode\n          LIMIT 1)\n     AND LeavingReason.leavingReasonLct != COALESCE(\n         (SELECT lrVersionId\n            FROM LeavingReasonReplicate\n           WHERE lrPk = LeavingReason.leavingReasonUid\n             AND lrDestination = UserSession.usClientNodeId), 0)\n /*psql ON CONFLICT(lrPk, lrDestination) DO UPDATE\n     SET lrPending = true\n  */               \n    ")
  public actual abstract suspend fun replicateOnChange(): Unit

  @Query(`value` = "SELECT * FROM LeavingReason")
  public actual abstract fun findAllReasons(): DataSource.Factory<Int, LeavingReason>

  @Query(`value` = "SELECT * FROM LeavingReason")
  public actual abstract fun findAllReasonsLive(): List<LeavingReason>

  @Query(`value` = "SELECT * FROM LeavingReason WHERE leavingReasonUid = :uid")
  public actual abstract suspend fun findByUidAsync(uid: Long): LeavingReason?

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

  @Query(`value` = "SELECT * FROM LeavingReason WHERE leavingReasonUid = :uid")
  public actual abstract fun findByUidLive(uid: Long): LiveData<LeavingReason?>

  @Query(`value` =
      "SELECT LeavingReason.leavingReasonUid AS uid, \n            LeavingReason.leavingReasonTitle As labelName  \n            FROM LeavingReason WHERE leavingReasonUid IN (:uidList)")
  public actual abstract suspend fun getReasonsFromUids(uidList: List<Long>): List<UidAndLabel>

  @Insert(onConflict = 1)
  public actual abstract suspend fun replaceList(entityList: List<LeavingReason>): Unit

  @Update(onConflict = 3)
  public actual abstract suspend fun updateAsync(entity: LeavingReason): Int
}
