package com.ustadmobile.core.db.dao

import com.ustadmobile.door.DoorDatabaseRepository
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.withRepoChangeMonitor
import com.ustadmobile.door.replication.withRepoChangeMonitorAsync
import com.ustadmobile.door.room.RoomDatabase
import com.ustadmobile.lib.db.composites.CourseGroupMemberAndPerson
import com.ustadmobile.lib.db.composites.PersonAndPicture
import com.ustadmobile.lib.db.entities.ClazzEnrolment
import com.ustadmobile.lib.db.entities.CourseGroupMember
import com.ustadmobile.lib.db.entities.CourseGroupMemberAndName
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.Int
import kotlin.Long
import kotlin.String
import kotlin.Suppress
import kotlin.collections.List
import kotlinx.coroutines.flow.Flow
import kotlinx.serialization.builtins.serializer

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


  override suspend fun findByGroupSetUidAsync(groupSetUid: Long): List<CourseGroupMember> {
    val _result = _dao.findByGroupSetUidAsync(groupSetUid)
    return _result
  }

  override suspend fun findByPersonUid(groupSetUid: Long, studentUid: Long): CourseGroupMember? {
    val _result = _dao.findByPersonUid(groupSetUid, studentUid)
    return _result
  }

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

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

  override suspend fun findByCourseGroupSetAndClazz(
    cgsUid: Long,
    clazzUid: Long,
    time: Long,
    activeFilter: Int,
    accountPersonUid: Long,
  ): List<CourseGroupMemberAndName> {
    _repo.replicateHttpRequestCatchAndLog(repoPath =
        "CourseGroupMemberDao/findByCourseGroupSetAndClazz") {
      val _response = _httpClient.`get` {
        setRepoUrl(_repo.config, "CourseGroupMemberDao/findByCourseGroupSetAndClazz")
        doorNodeIdHeader(_repo)
        `header`("cache-control", "no-store")
        parameter("cgsUid", _repo.config.json.encodeToString(Long.serializer(), cgsUid))
        parameter("clazzUid", _repo.config.json.encodeToString(Long.serializer(), clazzUid))
        parameter("time", _repo.config.json.encodeToString(Long.serializer(), time))
        parameter("activeFilter", _repo.config.json.encodeToString(Int.serializer(), activeFilter))
        parameter("accountPersonUid", _repo.config.json.encodeToString(Long.serializer(),
            accountPersonUid))
      }

      _db.onClientRepoDoorMessageHttpResponse(_response, _repo.config.json)
    }
    val _result = _dao.findByCourseGroupSetAndClazz(cgsUid, clazzUid, time, activeFilter,
        accountPersonUid)
    return _result
  }

  override fun findByCourseGroupSetAndClazzAsFlow(
    cgsUid: Long,
    clazzUid: Long,
    time: Long,
    activeFilter: Int,
    accountPersonUid: Long,
  ): Flow<List<CourseGroupMemberAndName>> = repoDaoFlowHelper.asRepoFlow(
    dbFlow = _dao.findByCourseGroupSetAndClazzAsFlow(cgsUid, clazzUid, time, activeFilter,
        accountPersonUid),
    onMakeHttpRequest =  {
      _repo.replicateHttpRequestCatchAndLog(repoPath =
          "CourseGroupMemberDao/findByCourseGroupSetAndClazzAsFlow") {
        val _response = _httpClient.`get` {
          setRepoUrl(_repo.config, "CourseGroupMemberDao/findByCourseGroupSetAndClazzAsFlow")
          doorNodeIdHeader(_repo)
          `header`("cache-control", "no-store")
          parameter("cgsUid", _repo.config.json.encodeToString(Long.serializer(), cgsUid))
          parameter("clazzUid", _repo.config.json.encodeToString(Long.serializer(), clazzUid))
          parameter("time", _repo.config.json.encodeToString(Long.serializer(), time))
          parameter("activeFilter", _repo.config.json.encodeToString(Int.serializer(),
              activeFilter))
          parameter("accountPersonUid", _repo.config.json.encodeToString(Long.serializer(),
              accountPersonUid))
        }

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

  override suspend fun findByCourseGroupSetAndClazzAsFlowPersons(clazzUid: Long, cgsUid: Long):
      List<PersonAndPicture> {
    val _result = _dao.findByCourseGroupSetAndClazzAsFlowPersons(clazzUid, cgsUid)
    return _result
  }

  override suspend fun findByCourseGroupSetAndClazzAsFlowEnrolments(clazzUid: Long, cgsUid: Long):
      List<ClazzEnrolment> {
    val _result = _dao.findByCourseGroupSetAndClazzAsFlowEnrolments(clazzUid, cgsUid)
    return _result
  }

  override suspend fun upsertListAsync(list: List<CourseGroupMember>) {
    _repo.withRepoChangeMonitorAsync("CourseGroupMember") {
      _dao.upsertListAsync(list)
    }
  }

  override suspend fun findByCourseGroupSetAndGroupNumAsync(
    courseGroupSetUid: Long,
    groupNum: Int,
    clazzUid: Long,
    assignmentUid: Long,
    accountPersonUid: Long,
  ): List<CourseGroupMemberAndPerson> {
    _repo.replicateHttpRequestCatchAndLog(repoPath =
        "CourseGroupMemberDao/findByCourseGroupSetAndGroupNumAsync") {
      val _response = _httpClient.`get` {
        setRepoUrl(_repo.config, "CourseGroupMemberDao/findByCourseGroupSetAndGroupNumAsync")
        doorNodeIdHeader(_repo)
        `header`("cache-control", "no-store")
        parameter("courseGroupSetUid", _repo.config.json.encodeToString(Long.serializer(),
            courseGroupSetUid))
        parameter("groupNum", _repo.config.json.encodeToString(Int.serializer(), groupNum))
        parameter("clazzUid", _repo.config.json.encodeToString(Long.serializer(), clazzUid))
        parameter("assignmentUid", _repo.config.json.encodeToString(Long.serializer(),
            assignmentUid))
        parameter("accountPersonUid", _repo.config.json.encodeToString(Long.serializer(),
            accountPersonUid))
      }

      _db.onClientRepoDoorMessageHttpResponse(_response, _repo.config.json)
    }
    val _result = _dao.findByCourseGroupSetAndGroupNumAsync(courseGroupSetUid, groupNum, clazzUid,
        assignmentUid, accountPersonUid)
    return _result
  }

  public override fun insert(entity: CourseGroupMember): Long {
    val _result = _repo.withRepoChangeMonitor("CourseGroupMember") {
      _dao.insert(entity)
    }
    return _result
  }

  public override suspend fun insertAsync(entity: CourseGroupMember): Long {
    val _result = _repo.withRepoChangeMonitorAsync("CourseGroupMember") {
      _dao.insertAsync(entity)
    }
    return _result
  }

  public override fun insertList(entityList: List<CourseGroupMember>) {
    _repo.withRepoChangeMonitor("CourseGroupMember") {
      _dao.insertList(entityList)
    }
  }

  public override fun update(entity: CourseGroupMember) {
    _repo.withRepoChangeMonitor("CourseGroupMember") {
      _dao.update(entity)
    }
  }
}
