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

import androidx.paging.PagingSource
import com.ustadmobile.door.DoorQuery
import com.ustadmobile.door.room.RoomDatabase
import com.ustadmobile.door.util.systemTimeInMillis
import com.ustadmobile.lib.db.composites.BlockStatus
import com.ustadmobile.lib.db.composites.PersonAndPictureAndNumAttempts
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.IllegalStateException
import kotlin.Int
import kotlin.Long
import kotlin.String
import kotlin.collections.List
import kotlinx.coroutines.flow.Flow

public class StatementDao_DoorWrapper(
  private val _db: RoomDatabase,
  private val _dao: StatementDao,
) : StatementDao() {
  override suspend fun insertOrIgnoreListAsync(entityList: List<StatementEntity>) {
    val _generatedPks = mutableListOf<Long>()
    entityList.iterator().forEach  {
      it.statementLct = systemTimeInMillis()
    }
    //must set versionid and/or primary key here
    _dao.insertOrIgnoreListAsync(entityList)
  }

  override fun getOneStatement(): Flow<StatementEntity?> = _dao.getOneStatement()

  override suspend fun getResults(query: DoorQuery): List<StatementReportData> =
      _dao.getResults(query)

  override fun getListResults(query: DoorQuery): PagingSource<Int, StatementEntityAndDisplayDetails>
      = _dao.getListResults(query)

  override fun getPerson(): Person? = throw
      IllegalStateException("getPerson: synchronous db access is NOT possible on Javascript!")

  override suspend fun getStatements(statementIdHi: Long, statementIdLo: Long):
      List<StatementEntity> = _dao.getStatements(statementIdHi, statementIdLo)

  override suspend fun findById(statementIdHi: Long, statementIdLo: Long): StatementEntity? =
      _dao.findById(statementIdHi, statementIdLo)

  override suspend fun findStatusStatementsByContentEntryUid(
    contentEntryUid: Long,
    courseBlockUid: Long,
    accountPersonUid: Long,
  ): List<StatementEntity> = _dao.findStatusStatementsByContentEntryUid(contentEntryUid,
      courseBlockUid, accountPersonUid)

  override suspend fun findStatusStatementByParentContentEntryUid(parentUid: Long,
      accountPersonUid: Long): List<StatementEntity> =
      _dao.findStatusStatementByParentContentEntryUid(parentUid, accountPersonUid)

  override suspend fun findStatusStatementsForStudentByClazzUid(clazzUid: Long,
      accountPersonUid: Long): List<StatementEntity> =
      _dao.findStatusStatementsForStudentByClazzUid(clazzUid, accountPersonUid)

  override 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> = _dao.findStatusForStudentsInClazzStatements(clazzUid, roleId,
      sortOrder, searchText, filter, accountPersonUid, currentTime, studentsLimit, studentsOffset,
      completionOrProgressTrueVal)

  override suspend fun findStatusForStudentsInClazzByUidList(
    clazzUid: Long,
    studentPersonUids: List<Long>,
    completionOrProgressTrueVal: Boolean,
  ): List<StatementEntityAndRelated> = _dao.findStatusForStudentsInClazzByUidList(clazzUid,
      studentPersonUids, completionOrProgressTrueVal)

  override suspend fun findActorEntitiesForStudentInClazzByUidList(
    clazzUid: Long,
    studentPersonUids: List<Long>,
    accountPersonUid: Long,
  ): List<ActorEntity> = _dao.findActorEntitiesForStudentInClazzByUidList(clazzUid,
      studentPersonUids, accountPersonUid)

  override suspend fun findStatusForStudentsInClazz(
    clazzUid: Long,
    studentPersonUids: List<Long>,
    accountPersonUid: Long,
  ): List<BlockStatus> = _dao.findStatusForStudentsInClazz(clazzUid, studentPersonUids,
      accountPersonUid)

  override fun findStatusForStudentsInClazzAsFlow(
    clazzUid: Long,
    studentPersonUids: List<Long>,
    accountPersonUid: Long,
  ): Flow<List<BlockStatus>> = _dao.findStatusForStudentsInClazzAsFlow(clazzUid, studentPersonUids,
      accountPersonUid)

  override suspend fun findResumableRegistration(
    activityUid: Long,
    accountPersonUid: Long,
    actorUid: Long,
  ): StatementEntity? = _dao.findResumableRegistration(activityUid, accountPersonUid, actorUid)

  override suspend fun findPersonsWithAttemptsStatements(
    contentEntryUid: Long,
    accountPersonUid: Long,
    searchText: String?,
  ): List<StatementEntity> = _dao.findPersonsWithAttemptsStatements(contentEntryUid,
      accountPersonUid, searchText)

  override fun findPersonsWithAttempts(
    contentEntryUid: Long,
    accountPersonUid: Long,
    searchText: String?,
    sortOrder: Int,
  ): PagingSource<Int, PersonAndPictureAndNumAttempts> =
      _dao.findPersonsWithAttempts(contentEntryUid, accountPersonUid, searchText, sortOrder)

  override suspend fun findSessionsByPersonAndContentStatements(
    contentEntryUid: Long,
    personUid: Long,
    accountPersonUid: Long,
  ): List<StatementEntity> = _dao.findSessionsByPersonAndContentStatements(contentEntryUid,
      personUid, accountPersonUid)

  override fun findSessionsByPersonAndContent(
    contentEntryUid: Long,
    personUid: Long,
    accountPersonUid: Long,
    sortOrder: Int,
  ): PagingSource<Int, SessionTimeAndProgressInfo> =
      _dao.findSessionsByPersonAndContent(contentEntryUid, personUid, accountPersonUid, sortOrder)

  override suspend fun findActivityEntryLangMapsForStatementsBySession(registrationHi: Long,
      registrationLo: Long): List<ActivityLangMapEntry> =
      _dao.findActivityEntryLangMapsForStatementsBySession(registrationHi, registrationLo)

  override fun findStatementsBySession(
    registrationHi: Long,
    registrationLo: Long,
    accountPersonUid: Long,
    selectedPersonUid: Long,
    contentEntryUid: Long,
    searchText: String,
    sortOrder: Int,
    deSelectedVerbUids: List<Long>,
  ): PagingSource<Int, StatementEntityAndVerb> = _dao.findStatementsBySession(registrationHi,
      registrationLo, accountPersonUid, selectedPersonUid, contentEntryUid, searchText, sortOrder,
      deSelectedVerbUids)

  override fun getUniqueVerbsForSession(
    registrationHi: Long,
    registrationLo: Long,
    selectedPersonUid: Long,
    contentEntryUid: Long,
  ): Flow<List<VerbEntityAndName>> = _dao.getUniqueVerbsForSession(registrationHi, registrationLo,
      selectedPersonUid, contentEntryUid)

  override suspend fun scoreOrProgressDataExistsForContent(contentEntryUid: Long,
      accountPersonUid: Long): List<StatementEntity> =
      _dao.scoreOrProgressDataExistsForContent(contentEntryUid, accountPersonUid)

  override suspend fun findByUidWithActivityAsync(statementIdHi: Long, statementIdLo: Long):
      StatementAndActivity? = _dao.findByUidWithActivityAsync(statementIdHi, statementIdLo)
}
