package com.ustadmobile.core.db.dao.xapi

import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query
import com.ustadmobile.lib.db.composites.ActorUidEtagAndLastMod
import com.ustadmobile.lib.db.entities.xapi.ActorEntity
import kotlin.Any
import kotlin.Long
import kotlin.String
import kotlin.collections.List

@Dao
public actual abstract class ActorDao {
  @Insert(
    onConflict = 5,
    entity = Any::class,
  )
  public actual abstract suspend fun insertOrIgnoreListAsync(entities: List<ActorEntity>)

  @Insert(
    onConflict = 1,
    entity = Any::class,
  )
  public actual abstract suspend fun upsertListAsync(entities: List<ActorEntity>)

  @Query(`value` =
      "\n        UPDATE ActorEntity\n           SET actorName = :name,\n               actorLct = :updateTime\n         WHERE actorUid = :uid\n           AND ActorEntity.actorName != :name\n    ")
  public actual abstract suspend fun updateIfNameChanged(
    uid: Long,
    name: String?,
    updateTime: Long,
  )

  @Query(`value` =
      "\n        SELECT ActorEntity.*\n          FROM ActorEntity\n         WHERE ActorEntity.actorUid = :uid\n    ")
  public actual abstract suspend fun findByUidAsync(uid: Long): ActorEntity?

  @Query(`value` =
      "\n        SELECT ActorEntity.*\n          FROM ActorEntity\n         WHERE ActorEntity.actorUid = :actorUid\n           AND ActorEntity.actorPersonUid = :accountPersonUid  \n    ")
  public actual abstract suspend fun findByUidAndPersonUidAsync(actorUid: Long,
      accountPersonUid: Long): ActorEntity?

  @Query(`value` =
      "\n        SELECT ActorEntity.actorUid, ActorEntity.actorEtag, ActorEntity.actorLct\n          FROM ActorEntity\n         WHERE ActorEntity.actorUid IN (:uidList)\n    ")
  public actual abstract suspend fun findUidAndEtagByListAsync(uidList: List<Long>):
      List<ActorUidEtagAndLastMod>

  @Query(`value` =
      "\n        SELECT ActorEntity.*\n          FROM ActorEntity\n         WHERE ActorEntity.actorUid IN (\n               SELECT GroupMemberActorJoin.gmajMemberActorUid\n                 FROM GroupMemberActorJoin\n                WHERE GroupMemberActorJoin.gmajGroupActorUid = :groupActorUid\n                  AND GroupMemberActorJoin.gmajLastMod = (\n                      SELECT GroupActorEntity.actorLct\n                        FROM ActorEntity GroupActorEntity\n                       WHERE GroupActorEntity.actorUid = :groupActorUid)\n              ) \n    ")
  public actual abstract suspend fun findGroupMembers(groupActorUid: Long): List<ActorEntity>
}
