package com.ustadmobile.core.db.dao

import androidx.paging.PagingSource
import com.ustadmobile.lib.db.composites.CourseBlockAndAssignment
import com.ustadmobile.lib.db.composites.CourseBlockAndDbEntities
import com.ustadmobile.lib.db.composites.CourseBlockAndDisplayDetails
import com.ustadmobile.lib.db.composites.CourseBlockAndGradebookDisplayDetails
import com.ustadmobile.lib.db.composites.CourseBlockAndPicture
import com.ustadmobile.lib.db.composites.CourseBlockUidAndClazzUid
import com.ustadmobile.lib.db.entities.CourseBlock
import kotlin.Boolean
import kotlin.Float
import kotlin.Int
import kotlin.Long
import kotlin.String
import kotlin.collections.List
import kotlinx.coroutines.flow.Flow

public actual abstract class CourseBlockDao : BaseDao<CourseBlock>, OneToManyJoinDao<CourseBlock> {
  public actual abstract suspend fun findByUidAsync(uid: Long): CourseBlock?

  public actual abstract suspend fun existsByUid(cbUid: Long): Boolean

  public actual abstract suspend fun updateAsync(entity: CourseBlock): Int

  public actual abstract suspend fun replaceListAsync(list: List<CourseBlock>)

  public actual abstract fun findByUidAsyncAsFlow(uid: Long): Flow<CourseBlock?>

  public actual abstract fun findByUidWithPictureAsFlow(uid: Long): Flow<CourseBlockAndPicture?>

  public actual abstract suspend fun findAllCourseBlockByClazzUidAsync(clazzUid: Long,
      includeInactive: Boolean): List<CourseBlockAndDbEntities>

  public actual abstract fun findAllCourseBlockByClazzUidAsFlow(
    clazzUid: Long,
    includeInactive: Boolean,
    includeHidden: Boolean,
    hideUntilFilterTime: Long,
    accountPersonUid: Long,
  ): Flow<List<CourseBlockAndDisplayDetails>>

  public actual abstract fun findAllCourseBlockByClazzUidAsPagingSource(
    clazzUid: Long,
    collapseList: List<Long>,
    includeInactive: Boolean,
    includeHidden: Boolean,
    hideUntilFilterTime: Long,
    accountPersonUid: Long,
  ): PagingSource<Int, CourseBlockAndDisplayDetails>

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

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

  public actual abstract fun getTitleByAssignmentUid(assignmentUid: Long): Flow<String?>

  public actual abstract fun findByUidAsFlow(courseBlockUid: Long): Flow<CourseBlock?>

  public actual abstract suspend fun findCourseBlockAndClazzUidByDiscussionPostUid(postUid: Long):
      CourseBlockUidAndClazzUid?

  public actual abstract suspend fun findCourseBlockByDiscussionPostUid(postUid: Long): CourseBlock?

  public actual abstract suspend fun findClazzUidByCourseBlockUid(courseBlockUid: Long): Long

  public actual abstract fun findCourseBlockByAssignmentUid(assignmentUid: Long):
      Flow<CourseBlockAndAssignment?>

  public actual abstract suspend fun findBySourcedId(sourcedId: String, accountPersonUid: Long):
      CourseBlock?

  public actual abstract suspend fun findByClazzUid(clazzUid: Long): List<CourseBlock>

  public actual abstract fun findByClazzUidAsFlow(clazzUid: Long):
      Flow<List<CourseBlockAndGradebookDisplayDetails>>

  public actual abstract suspend fun updateFromLineItem(
    cbUid: Long,
    active: Boolean,
    dateLastModified: Long,
    title: String,
    description: String,
    assignDate: Long,
    dueDate: Long,
    resultValueMin: Float,
    resultValueMax: Float,
  )

  public actual abstract suspend fun findCourseBlockAndClazzUidByCbUid(cbUid: Long,
      accountPersonUid: Long): CourseBlockUidAndClazzUid?
}
