package com.ustadmobile.core.db.dao

import androidx.paging.PagingSource
import com.ustadmobile.lib.db.composites.AssignmentSubmitterUidAndName
import com.ustadmobile.lib.db.composites.ClazzAssignmentAndBlock
import com.ustadmobile.lib.db.entities.AssignmentProgressSummary
import com.ustadmobile.lib.db.entities.AssignmentSubmitterSummary
import com.ustadmobile.lib.db.entities.ClazzAssignment
import com.ustadmobile.lib.db.entities.ClazzAssignmentCourseBlockAndSubmitterUid
import com.ustadmobile.lib.db.entities.ClazzEnrolment
import com.ustadmobile.lib.db.entities.CourseAssignmentMark
import com.ustadmobile.lib.db.entities.CourseAssignmentSubmission
import com.ustadmobile.lib.db.entities.CourseGroupMember
import com.ustadmobile.lib.db.entities.PeerReviewerAllocation
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 ClazzAssignmentDao : BaseDao<ClazzAssignment>,
    OneToManyJoinDao<ClazzAssignment> {
  public actual abstract suspend fun getAllAssignmentsByClazzUidAsync(clazzUid: Long):
      List<ClazzAssignment>

  public actual abstract suspend fun updateActiveByUid(
    cbUid: Long,
    active: Boolean,
    changeTime: Long,
  )

  public actual abstract fun getProgressSummaryForAssignment(
    assignmentUid: Long,
    clazzUid: Long,
    accountPersonUid: Long,
    group: String,
  ): Flow<AssignmentProgressSummary?>

  public actual abstract fun getAssignmentSubmitterSummaryListForAssignment(
    assignmentUid: Long,
    clazzUid: Long,
    accountPersonUid: Long,
    group: String,
    searchText: String,
    sortOption: Int,
  ): PagingSource<Int, AssignmentSubmitterSummary>

  public actual abstract suspend fun getCourseGroupMembersByAssignmentUid(assignmentUid: Long):
      List<CourseGroupMember>

  public actual abstract suspend fun getAssignmentSubmissionsByAssignmentUid(
    assignmentUid: Long,
    clazzUid: Long,
    accountPersonUid: Long,
    group: String,
  ): List<CourseAssignmentSubmission>

  public actual abstract suspend fun getAssignmentMarksByAssignmentUid(
    assignmentUid: Long,
    clazzUid: Long,
    accountPersonUid: Long,
    group: String,
  ): List<CourseAssignmentMark>

  public actual abstract suspend fun getPeerReviewerAllocationsByAssignmentUid(
    assignmentUid: Long,
    clazzUid: Long,
    accountPersonUid: Long,
  ): List<PeerReviewerAllocation>

  public actual abstract suspend fun getPeerReviewAllocationsForPerson(assignmentUid: Long,
      accountPersonUid: Long): List<PeerReviewerAllocation>

  public actual abstract suspend fun getSubmitterUidsByClazzOrGroupSetUid(
    clazzUid: Long,
    groupSetUid: Long,
    time: Long,
  ): List<Long>

  public actual abstract suspend fun getSubmitterUidsAndNameByClazzOrGroupSetUid(
    clazzUid: Long,
    groupSetUid: Long,
    date: Long,
    groupStr: String,
  ): List<AssignmentSubmitterUidAndName>

  public actual abstract suspend fun getSubmitterCountFromAssignment(
    groupUid: Long,
    clazzUid: Long,
    group: String,
  ): Int

  public actual abstract suspend fun getSubmitterUid(
    assignmentUid: Long,
    clazzUid: Long,
    accountPersonUid: Long,
  ): Long

  public actual abstract suspend fun updateAsync(clazzAssignment: ClazzAssignment)

  public actual abstract suspend fun findByUidAsync(uid: Long): ClazzAssignment?

  public actual abstract fun findByUidAndClazzUidAsFlow(uid: Long, clazzUid: Long):
      Flow<ClazzAssignment?>

  public actual abstract suspend fun findByUidAndClazzUidAsync(assignmentUid: Long, clazzUid: Long):
      ClazzAssignment?

  public actual abstract suspend fun getGroupUidFromAssignment(uid: Long): Long

  public actual abstract suspend fun getMarkingTypeFromAssignment(uid: Long): Int

  public actual abstract suspend fun findByUidWithBlockAsync(uid: Long): ClazzAssignmentAndBlock?

  public actual abstract fun findClazzAssignment(): ClazzAssignment?

  public actual abstract fun findByUidLive(uid: Long): Flow<ClazzAssignment?>

  public actual abstract suspend fun upsertListAsync(entities: List<ClazzAssignment>)

  public actual abstract suspend fun updateActiveByList(
    uidList: List<Long>,
    active: Boolean,
    changeTime: Long,
  )

  public actual abstract fun findAssignmentCourseBlockAndSubmitterUidAsFlow(
    assignmentUid: Long,
    clazzUid: Long,
    accountPersonUid: Long,
  ): Flow<ClazzAssignmentCourseBlockAndSubmitterUid?>

  public actual abstract suspend fun findEnrolmentsByPersonUidAndAssignmentUid(assignmentUid: Long,
      accountPersonUid: Long): List<ClazzEnrolment>

  public actual abstract suspend
      fun findCourseGroupMembersByPersonUidAndAssignmentUid(assignmentUid: Long,
      accountPersonUid: Long): List<CourseGroupMember>

  public actual abstract suspend
      fun findPeerReviewerAllocationsByPersonUidAndAssignmentUid(assignmentUid: Long,
      accountPersonUid: Long): List<PeerReviewerAllocation>

  public actual abstract suspend fun getLatestSubmissionTimeAllowed(assignmentUid: Long): Long
}
