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

import androidx.paging.PagingSource
import com.ustadmobile.door.DoorQuery
import com.ustadmobile.lib.db.composites.BlockStatus
import com.ustadmobile.lib.db.composites.PersonAndPictureAndNumAttempts
import com.ustadmobile.lib.db.composites.StatementReportRow
import com.ustadmobile.lib.db.composites.xapi.SessionTimeAndProgressInfo
import com.ustadmobile.lib.db.composites.xapi.StatementAndActivity
import com.ustadmobile.lib.db.composites.xapi.StatementEntityAndRelated
import com.ustadmobile.lib.db.composites.xapi.StatementEntityAndVerb
import com.ustadmobile.lib.db.composites.xapi.VerbEntityAndName
import com.ustadmobile.lib.db.entities.Person
import com.ustadmobile.lib.db.entities.StatementEntityAndDisplayDetails
import com.ustadmobile.lib.db.entities.StatementReportData
import com.ustadmobile.lib.db.entities.xapi.ActivityLangMapEntry
import com.ustadmobile.lib.db.entities.xapi.ActorEntity
import com.ustadmobile.lib.db.entities.xapi.StatementEntity
import kotlin.Boolean
import kotlin.Int
import kotlin.Long
import kotlin.String
import kotlin.collections.List
import kotlinx.coroutines.flow.Flow

public actual abstract class StatementDao {
  public actual abstract suspend fun insertOrIgnoreListAsync(entityList: List<StatementEntity>)

  public actual abstract fun getOneStatement(): Flow<StatementEntity?>

  public actual abstract suspend fun runReportQuery(query: DoorQuery): List<StatementReportRow>

  public actual abstract suspend fun getResults(query: DoorQuery): List<StatementReportData>

  public actual abstract fun getListResults(query: DoorQuery):
      PagingSource<Int, StatementEntityAndDisplayDetails>

  public actual abstract fun getPerson(): Person?

  public actual abstract suspend fun getStatements(statementIdHi: Long, statementIdLo: Long):
      List<StatementEntity>

  public actual abstract suspend fun findById(statementIdHi: Long, statementIdLo: Long):
      StatementEntity?

  public actual abstract suspend fun findStatusStatementsByContentEntryUid(
    contentEntryUid: Long,
    courseBlockUid: Long,
    accountPersonUid: Long,
  ): List<StatementEntity>

  public actual abstract suspend fun findStatusStatementByParentContentEntryUid(parentUid: Long,
      accountPersonUid: Long): List<StatementEntity>

  public actual abstract suspend fun findStatusStatementsForStudentByClazzUid(clazzUid: Long,
      accountPersonUid: Long): List<StatementEntity>

  public actual abstract suspend fun findStatusForStudentsInClazzStatements(
    clazzUid: Long,
    roleId: Int,
    sortOrder: Int,
    searchText: String?,
    filter: Int,
    accountPersonUid: Long,
    currentTime: Long,
    studentsLimit: Int,
    studentsOffset: Int,
    completionOrProgressTrueVal: Boolean,
  ): List<StatementEntityAndRelated>

  public actual abstract suspend fun findStatusForStudentsInClazzByUidList(
    clazzUid: Long,
    studentPersonUids: List<Long>,
    completionOrProgressTrueVal: Boolean,
  ): List<StatementEntityAndRelated>

  public actual abstract suspend fun findActorEntitiesForStudentInClazzByUidList(
    clazzUid: Long,
    studentPersonUids: List<Long>,
    accountPersonUid: Long,
  ): List<ActorEntity>

  public actual abstract suspend fun findStatusForStudentsInClazz(
    clazzUid: Long,
    studentPersonUids: List<Long>,
    accountPersonUid: Long,
  ): List<BlockStatus>

  public actual abstract fun findStatusForStudentsInClazzAsFlow(
    clazzUid: Long,
    studentPersonUids: List<Long>,
    accountPersonUid: Long,
  ): Flow<List<BlockStatus>>

  public actual abstract suspend fun findResumableRegistration(
    activityUid: Long,
    accountPersonUid: Long,
    actorUid: Long,
  ): StatementEntity?

  public actual abstract suspend fun findPersonsWithAttemptsStatements(
    contentEntryUid: Long,
    accountPersonUid: Long,
    searchText: String?,
  ): List<StatementEntity>

  public actual abstract fun findPersonsWithAttempts(
    contentEntryUid: Long,
    accountPersonUid: Long,
    searchText: String?,
    sortOrder: Int,
  ): PagingSource<Int, PersonAndPictureAndNumAttempts>

  public actual abstract suspend fun findSessionsByPersonAndContentStatements(
    contentEntryUid: Long,
    personUid: Long,
    accountPersonUid: Long,
  ): List<StatementEntity>

  public actual abstract fun findSessionsByPersonAndContent(
    contentEntryUid: Long,
    personUid: Long,
    accountPersonUid: Long,
    sortOrder: Int,
  ): PagingSource<Int, SessionTimeAndProgressInfo>

  public actual abstract suspend
      fun findActivityEntryLangMapsForStatementsBySession(registrationHi: Long,
      registrationLo: Long): List<ActivityLangMapEntry>

  public actual abstract fun findStatementsBySession(
    registrationHi: Long,
    registrationLo: Long,
    accountPersonUid: Long,
    selectedPersonUid: Long,
    contentEntryUid: Long,
    searchText: String,
    sortOrder: Int,
    deSelectedVerbUids: List<Long>,
  ): PagingSource<Int, StatementEntityAndVerb>

  public actual abstract fun getUniqueVerbsForSession(
    registrationHi: Long,
    registrationLo: Long,
    selectedPersonUid: Long,
    contentEntryUid: Long,
  ): Flow<List<VerbEntityAndName>>

  public actual abstract suspend fun scoreOrProgressDataExistsForContent(contentEntryUid: Long,
      accountPersonUid: Long): List<StatementEntity>

  public actual abstract suspend fun findByUidWithActivityAsync(statementIdHi: Long,
      statementIdLo: Long): StatementAndActivity?
}
