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

import androidx.paging.PagingSource
import com.ustadmobile.door.DoorDatabaseRepository
import com.ustadmobile.door.DoorQuery
import com.ustadmobile.door.ext.doorNodeIdHeader
import com.ustadmobile.door.ext.setRepoUrl
import com.ustadmobile.door.http.RepoDaoFlowHelper
import com.ustadmobile.door.http.RepositoryDaoWithFlowHelper
import com.ustadmobile.door.http.replicateHttpRequestCatchAndLog
import com.ustadmobile.door.replication.onClientRepoDoorMessageHttpResponse
import com.ustadmobile.door.replication.withRepoChangeMonitorAsync
import com.ustadmobile.door.room.RoomDatabase
import com.ustadmobile.lib.db.composites.BlockStatus
import com.ustadmobile.lib.db.composites.xapi.StatementEntityAndRelated
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.ActorEntity
import com.ustadmobile.lib.db.entities.xapi.StatementEntity
import io.ktor.client.HttpClient
import io.ktor.client.request.`get`
import io.ktor.client.request.`header`
import io.ktor.client.request.parameter
import kotlin.Boolean
import kotlin.Int
import kotlin.Long
import kotlin.String
import kotlin.Suppress
import kotlin.collections.List
import kotlinx.coroutines.flow.Flow
import kotlinx.serialization.builtins.ListSerializer
import kotlinx.serialization.builtins.serializer

@Suppress("REDUNDANT_PROJECTION", "LocalVariableName", "ClassName")
public class StatementDao_Repo(
  public val _db: RoomDatabase,
  public val _repo: DoorDatabaseRepository,
  public val _dao: StatementDao,
  public val _httpClient: HttpClient,
  public val _clientId: Long,
  public val _endpoint: String,
) : StatementDao(), RepositoryDaoWithFlowHelper {
  override val repoDaoFlowHelper: RepoDaoFlowHelper = RepoDaoFlowHelper(_repo)


  override suspend fun insertOrIgnoreListAsync(entityList: List<StatementEntity>) {
    _repo.withRepoChangeMonitorAsync("StatementEntity") {
      _dao.insertOrIgnoreListAsync(entityList)
    }
  }

  override fun getOneStatement(): Flow<StatementEntity?> {
    val _result = _dao.getOneStatement()
    return _result
  }

  override suspend fun getResults(query: DoorQuery): List<StatementReportData> {
    val _result = _dao.getResults(query)
    return _result
  }

  override fun getListResults(query: DoorQuery):
      PagingSource<Int, StatementEntityAndDisplayDetails> {
    val _result = _dao.getListResults(query)
    return _result
  }

  override fun getPerson(): Person? {
    val _result = _dao.getPerson()
    return _result
  }

  override suspend fun getStatements(statementIdHi: Long, statementIdLo: Long):
      List<StatementEntity> {
    val _result = _dao.getStatements(statementIdHi, statementIdLo)
    return _result
  }

  override suspend fun findById(statementIdHi: Long, statementIdLo: Long): StatementEntity? {
    val _result = _dao.findById(statementIdHi, statementIdLo)
    return _result
  }

  override suspend fun findStatusStatementsByContentEntryUid(
    contentEntryUid: Long,
    courseBlockUid: Long,
    accountPersonUid: Long,
  ): List<StatementEntity> {
    val _result = _dao.findStatusStatementsByContentEntryUid(contentEntryUid, courseBlockUid,
        accountPersonUid)
    return _result
  }

  override suspend fun findStatusStatementByParentContentEntryUid(parentUid: Long,
      accountPersonUid: Long): List<StatementEntity> {
    val _result = _dao.findStatusStatementByParentContentEntryUid(parentUid, accountPersonUid)
    return _result
  }

  override suspend fun findStatusStatementsForStudentByClazzUid(clazzUid: Long,
      accountPersonUid: Long): List<StatementEntity> {
    val _result = _dao.findStatusStatementsForStudentByClazzUid(clazzUid, accountPersonUid)
    return _result
  }

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

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

  override suspend fun findActorEntitiesForStudentInClazzByUidList(
    clazzUid: Long,
    studentPersonUids: List<Long>,
    accountPersonUid: Long,
  ): List<ActorEntity> {
    val _result = _dao.findActorEntitiesForStudentInClazzByUidList(clazzUid, studentPersonUids,
        accountPersonUid)
    return _result
  }

  override suspend fun findStatusForStudentsInClazz(
    clazzUid: Long,
    studentPersonUids: List<Long>,
    accountPersonUid: Long,
  ): List<BlockStatus> {
    val _result = _dao.findStatusForStudentsInClazz(clazzUid, studentPersonUids, accountPersonUid)
    return _result
  }

  override fun findStatusForStudentsInClazzAsFlow(
    clazzUid: Long,
    studentPersonUids: List<Long>,
    accountPersonUid: Long,
  ): Flow<List<BlockStatus>> = repoDaoFlowHelper.asRepoFlow(
    dbFlow = _dao.findStatusForStudentsInClazzAsFlow(clazzUid, studentPersonUids, accountPersonUid),
    onMakeHttpRequest =  {
      _repo.replicateHttpRequestCatchAndLog(repoPath =
          "StatementDao/findStatusForStudentsInClazzAsFlow") {
        val _response = _httpClient.`get` {
          setRepoUrl(_repo.config, "StatementDao/findStatusForStudentsInClazzAsFlow")
          doorNodeIdHeader(_repo)
          `header`("cache-control", "no-store")
          parameter("clazzUid", _repo.config.json.encodeToString(Long.serializer(), clazzUid))
          parameter("studentPersonUids",
              _repo.config.json.encodeToString(ListSerializer(Long.serializer()),
              studentPersonUids))
          parameter("accountPersonUid", _repo.config.json.encodeToString(Long.serializer(),
              accountPersonUid))
        }

        _db.onClientRepoDoorMessageHttpResponse(_response, _repo.config.json)
      }
    },
  )

  override suspend fun findResumableRegistration(
    activityUid: Long,
    accountPersonUid: Long,
    actorUid: Long,
  ): StatementEntity? {
    val _result = _dao.findResumableRegistration(activityUid, accountPersonUid, actorUid)
    return _result
  }
}
