package com.ustadmobile.core.db.dao

import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query
import com.ustadmobile.lib.db.entities.Holiday
import kotlin.Boolean
import kotlin.Long
import kotlin.Unit
import kotlin.collections.List

@Dao
public actual abstract class HolidayDao : BaseDao<Holiday>, OneToManyJoinDao<Holiday> {
  @Query(`value` =
      "\n     REPLACE INTO HolidayReplicate(holidayPk, holidayDestination)\n      SELECT DISTINCT Holiday.holUid AS holidayPk,\n             :newNodeId AS holidayDestination\n        FROM Holiday\n       WHERE Holiday.holLct != COALESCE(\n             (SELECT holidayVersionId\n                FROM HolidayReplicate\n               WHERE holidayPk = Holiday.holUid\n                 AND holidayDestination = :newNodeId), 0) \n      /*psql ON CONFLICT(holidayPk, holidayDestination) DO UPDATE\n             SET holidayPending = true\n      */       \n    ")
  public actual abstract suspend fun replicateOnNewNode(newNodeId: Long): Unit

  @Query(`value` =
      "\n REPLACE INTO HolidayReplicate(holidayPk, holidayDestination)\n  SELECT DISTINCT Holiday.holUid AS holidayUid,\n         UserSession.usClientNodeId AS holidayDestination\n    FROM ChangeLog\n         JOIN Holiday\n             ON ChangeLog.chTableId = 99\n                AND ChangeLog.chEntityPk = Holiday.holUid\n         JOIN UserSession ON UserSession.usStatus = 1\n   WHERE UserSession.usClientNodeId != (\n         SELECT nodeClientId \n           FROM SyncNode\n          LIMIT 1)\n     AND Holiday.holLct != COALESCE(\n         (SELECT holidayVersionId\n            FROM HolidayReplicate\n           WHERE holidayPk = Holiday.holUid\n             AND holidayDestination = UserSession.usClientNodeId), 0)\n /*psql ON CONFLICT(holidayPk, holidayDestination) DO UPDATE\n     SET holidayPending = true\n  */               \n    ")
  public actual abstract suspend fun replicateOnChange(): Unit

  @Query(`value` = "SELECT * FROM Holiday WHERE holHolidayCalendarUid = :holidayCalendarUid")
  public actual abstract fun findByHolidayCalendaUid(holidayCalendarUid: Long): List<Holiday>

  @Query(`value` = "SELECT * FROM Holiday WHERE holHolidayCalendarUid = :holidayCalendarUid")
  public actual abstract suspend fun findByHolidayCalendaUidAsync(holidayCalendarUid: Long):
      List<Holiday>

  @Query(`value` =
      "\n        UPDATE Holiday \n           SET holActive = :active, \n               holLct = :changeTime\n         WHERE holUid = :holidayUid")
  public actual abstract fun updateActiveByUid(
    holidayUid: Long,
    active: Boolean,
    changeTime: Long,
  ): Unit

  @Insert(onConflict = 3)
  public actual abstract suspend fun updateAsync(entity: Holiday): Unit
}
