package com.ustadmobile.core.db.dao

import androidx.room.Dao
import androidx.room.Query
import com.ustadmobile.lib.db.entities.ClazzContentJoin
import kotlin.Boolean
import kotlin.Long
import kotlin.Unit
import kotlin.collections.List

@Dao
public actual abstract class ClazzContentJoinDao : BaseDao<ClazzContentJoin> {
  @Query(`value` =
      "\n     REPLACE INTO ClazzContentJoinReplicate(ccjPk, ccjDestination)\n      SELECT DISTINCT ClazzContentJoin.ccjUid AS ccjUid,\n             :newNodeId AS ccjDestination\n        FROM UserSession\n               JOIN PersonGroupMember \n                    ON UserSession.usPersonUid = PersonGroupMember.groupMemberPersonUid\n               \n               JOIN ScopedGrant\n                    ON ScopedGrant.sgGroupUid = PersonGroupMember.groupMemberGroupUid\n                        AND (ScopedGrant.sgPermissions & \n        \n                    4398046511104 \n                    \n                       ) > 0\n               JOIN Clazz \n                    ON \n            ((ScopedGrant.sgTableId = -2\n                                AND ScopedGrant.sgEntityUid = -2)\n                            OR (ScopedGrant.sgTableId = 6\n                                AND ScopedGrant.sgEntityUid = Clazz.clazzUid)\n                            OR (ScopedGrant.sgTableId = 164\n                                AND ScopedGrant.sgEntityUid = Clazz.clazzSchoolUid))\n        \n        \n               JOIN ClazzContentJoin    \n                    ON Clazz.clazzUid = ClazzContentJoin.ccjClazzUid\n       WHERE UserSession.usClientNodeId = :newNodeId \n         AND UserSession.usStatus = 1             \n         AND ClazzContentJoin.ccjLct != COALESCE(\n             (SELECT ccjVersionId\n                FROM ClazzContentJoinReplicate\n               WHERE ccjPk = ClazzContentJoin.ccjUid\n                 AND ccjDestination = :newNodeId), 0) \n      /*psql ON CONFLICT(ccjPk, ccjDestination) DO UPDATE\n             SET ccjPending = true\n      */       \n    ")
  public actual abstract suspend fun replicateOnNewNode(newNodeId: Long): Unit

  @Query(`value` =
      "\n REPLACE INTO ClazzContentJoinReplicate(ccjPk, ccjDestination)\n  SELECT DISTINCT ClazzContentJoin.ccjUid AS ccjUid,\n         UserSession.usClientNodeId AS ccjDestination\n    FROM ChangeLog\n         JOIN ClazzContentJoin\n             ON ChangeLog.chTableId = 134\n                AND ChangeLog.chEntityPk = ClazzContentJoin.ccjUid\n         JOIN Clazz \n              ON Clazz.clazzUid = ClazzContentJoin.ccjClazzUid                \n         \n            JOIN ScopedGrant\n                 ON \n            ((ScopedGrant.sgTableId = -2\n                                AND ScopedGrant.sgEntityUid = -2)\n                            OR (ScopedGrant.sgTableId = 6\n                                AND ScopedGrant.sgEntityUid = Clazz.clazzUid)\n                            OR (ScopedGrant.sgTableId = 164\n                                AND ScopedGrant.sgEntityUid = Clazz.clazzSchoolUid))\n        \n                    AND (ScopedGrant.sgPermissions & \n        \n              4398046511104\n              \n              \n                                                       ) > 0\n             JOIN PersonGroupMember AS PrsGrpMbr\n                   ON ScopedGrant.sgGroupUid = PrsGrpMbr.groupMemberGroupUid\n                                               \n              JOIN UserSession\n                   ON UserSession.usPersonUid = PrsGrpMbr.groupMemberPersonUid\n                      AND UserSession.usStatus = 1\n        \n   WHERE UserSession.usClientNodeId != (\n         SELECT nodeClientId \n           FROM SyncNode\n          LIMIT 1)\n     AND ClazzContentJoin.ccjLct != COALESCE(\n         (SELECT ccjVersionId\n            FROM ClazzContentJoinReplicate\n           WHERE ccjPk = ClazzContentJoin.ccjUid\n             AND ccjDestination = UserSession.usClientNodeId), 0)\n /*psql ON CONFLICT(ccjPk, ccjDestination) DO UPDATE\n     SET ccjPending = true\n  */               \n    ")
  public actual abstract suspend fun replicateOnChange(): Unit

  @Query(`value` =
      "UPDATE ClazzContentJoin \n                       SET ccjActive = :toggleVisibility, \n                           ccjLct = :changedTime \n                     WHERE ccjContentEntryUid IN (:selectedItem)")
  public actual abstract suspend fun toggleVisibilityClazzContent(
    toggleVisibility: Boolean,
    selectedItem: List<Long>,
    changedTime: Long,
  ): Unit

  @Query(`value` =
      "\n        SELECT ccjContentEntryUid \n          FROM ClazzContentJoin\n         WHERE ccjClazzUid = :clazzUid\n           AND ccjActive\n    ")
  public actual abstract suspend fun listOfEntriesInClazz(clazzUid: Long): List<Long>
}
