package com.ustadmobile.core.db.dao

import androidx.paging.DataSource
import androidx.room.Dao
import androidx.room.Query
import androidx.room.Update
import com.ustadmobile.lib.db.entities.ContentEntryRelatedEntryJoin
import com.ustadmobile.lib.db.entities.ContentEntryRelatedEntryJoinWithLangName
import com.ustadmobile.lib.db.entities.ContentEntryRelatedEntryJoinWithLanguage
import kotlin.Int
import kotlin.Long
import kotlin.Unit
import kotlin.collections.List

@Dao
public actual abstract class ContentEntryRelatedEntryJoinDao : BaseDao<ContentEntryRelatedEntryJoin>
    {
  @Query(`value` =
      "\n     REPLACE INTO ContentEntryRelatedEntryJoinReplicate(cerejPk, cerejDestination)\n      SELECT DISTINCT ContentEntryRelatedEntryJoin.cerejUid AS cerejPk,\n             :newNodeId AS cerejDestination\n        FROM ContentEntryRelatedEntryJoin\n       WHERE ContentEntryRelatedEntryJoin.cerejLct != COALESCE(\n             (SELECT cerejVersionId\n                FROM ContentEntryRelatedEntryJoinReplicate\n               WHERE cerejPk = ContentEntryRelatedEntryJoin.cerejUid\n                 AND cerejDestination = :newNodeId), 0) \n      /*psql ON CONFLICT(cerejPk, cerejDestination) DO UPDATE\n             SET cerejPending = true\n      */       \n    ")
  public actual abstract suspend fun replicateOnNewNode(newNodeId: Long): Unit

  @Query(`value` =
      "\n REPLACE INTO ContentEntryRelatedEntryJoinReplicate(cerejPk, cerejDestination)\n  SELECT DISTINCT ContentEntryRelatedEntryJoin.cerejUid AS cerejUid,\n         UserSession.usClientNodeId AS cerejDestination\n    FROM ChangeLog\n         JOIN ContentEntryRelatedEntryJoin\n             ON ChangeLog.chTableId = 8\n                AND ChangeLog.chEntityPk = ContentEntryRelatedEntryJoin.cerejUid\n         JOIN UserSession ON UserSession.usStatus = 1\n   WHERE UserSession.usClientNodeId != (\n         SELECT nodeClientId \n           FROM SyncNode\n          LIMIT 1)\n     AND ContentEntryRelatedEntryJoin.cerejLct != COALESCE(\n         (SELECT cerejVersionId\n            FROM ContentEntryRelatedEntryJoinReplicate\n           WHERE cerejPk = ContentEntryRelatedEntryJoin.cerejUid\n             AND cerejDestination = UserSession.usClientNodeId), 0)\n /*psql ON CONFLICT(cerejPk, cerejDestination) DO UPDATE\n     SET cerejPending = true\n  */               \n    ")
  public actual abstract suspend fun replicateOnChange(): Unit

  @Query(`value` =
      "SELECT ContentEntryRelatedEntryJoin.* FROM ContentEntryRelatedEntryJoin LEFT JOIN ContentEntry ON ContentEntryRelatedEntryJoin.cerejRelatedEntryUid = ContentEntry.contentEntryUid WHERE ContentEntry.publik")
  public actual abstract fun publicContentEntryRelatedEntryJoins():
      List<ContentEntryRelatedEntryJoin>

  @Query(`value` =
      "SELECT * FROM ContentEntryRelatedEntryJoin WHERE cerejRelatedEntryUid = :contentEntryUid LIMIT 1")
  public actual abstract fun findPrimaryByTranslation(contentEntryUid: Long):
      ContentEntryRelatedEntryJoin?

  @Query(`value` =
      "SELECT ContentEntryRelatedEntryJoin.cerejContentEntryUid, ContentEntryRelatedEntryJoin.cerejRelatedEntryUid, CASE ContentEntryRelatedEntryJoin.cerejRelatedEntryUid WHEN :contentEntryUid THEN (SELECT name FROM Language WHERE langUid = (SELECT primaryLanguageUid FROM ContentEntry WHERE contentEntryUid = ContentEntryRelatedEntryJoin.cerejContentEntryUid)) ELSE Language.name END languageName FROM ContentEntryRelatedEntryJoin LEFT JOIN Language ON ContentEntryRelatedEntryJoin.cerejRelLanguageUid = Language.langUid WHERE (ContentEntryRelatedEntryJoin.cerejContentEntryUid = :contentEntryUid OR ContentEntryRelatedEntryJoin.cerejContentEntryUid IN (SELECT cerejContentEntryUid FROM ContentEntryRelatedEntryJoin WHERE cerejRelatedEntryUid = :contentEntryUid)) AND ContentEntryRelatedEntryJoin.relType = 1")
  public actual abstract suspend fun findAllTranslationsForContentEntryAsync(contentEntryUid: Long):
      List<ContentEntryRelatedEntryJoinWithLangName>

  @Query(`value` =
      "SELECT ContentEntryRelatedEntryJoin.*, Language.* FROM ContentEntryRelatedEntryJoin\n        LEFT JOIN Language ON ContentEntryRelatedEntryJoin.cerejRelLanguageUid = Language.langUid\n        WHERE (ContentEntryRelatedEntryJoin.cerejContentEntryUid = :contentEntryUid\n        OR ContentEntryRelatedEntryJoin.cerejContentEntryUid IN\n        (SELECT cerejContentEntryUid FROM ContentEntryRelatedEntryJoin WHERE cerejRelatedEntryUid = :contentEntryUid))\n        AND ContentEntryRelatedEntryJoin.relType = 1\n        ORDER BY Language.name")
  public actual abstract fun findAllTranslationsWithContentEntryUid(contentEntryUid: Long):
      DataSource.Factory<Int, ContentEntryRelatedEntryJoinWithLanguage>

  @Update(onConflict = 3)
  public actual abstract override fun update(entity: ContentEntryRelatedEntryJoin): Unit
}
