package de.sebse.fuplanner2.database

import android.content.Context
import androidx.navigation.NavController
import androidx.room.Entity
import androidx.room.ForeignKey
import androidx.room.ForeignKey.CASCADE
import androidx.room.Index
import androidx.room.PrimaryKey
import com.beust.klaxon.JsonObject
import de.sebse.fuplanner2.R
import de.sebse.fuplanner2.ui.notification.NotificationFragmentDirections
import de.sebse.fuplanner2.utils.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

@Entity(
    foreignKeys = [
        ForeignKey(onDelete = CASCADE, entity = Course::class, parentColumns = ["uid"], childColumns = ["courseId"])
    ],
    indices = [
        Index("courseId"),
        Index("courseId", "startDateTime", "duration", "title", "location", unique = true)
    ]
)
data class Event (
    @PrimaryKey(autoGenerate = true) var uid: Long? = null,
    val courseId: Long,
    val lastRefreshed: Long,
    val title: String,
    val duration: Long,
    val startDateTime: Long,
    val location: String?,
    val type: String
): Updatable {
    override fun getIdentifier(): String =
        hashCodeOf(type, startDateTime, duration, title, location).toString()

    override fun getHash(): Int =
        hashCodeOf(type, startDateTime, duration, title, location)

    override fun getData(): JsonObject =
        JsonObject(mapOf("title" to title, "uid" to uid))

    override fun getNotificationEntityType(): Notifications.CourseUpdateEntity =
        Notifications.CourseUpdateEntity.EVENT

    companion object : UpdatableCompanion {
        override fun notificationText(
            actCtx: Context,
            type: Notifications.CourseUpdateType,
            data: JsonObject
        ): CharSequence? = when (type) {
            Notifications.CourseUpdateType.REMOVED -> actCtx.getHtmlSpannedString(R.string.not_course_update_event_removed, data.string("title"))
            Notifications.CourseUpdateType.UPDATED -> actCtx.getHtmlSpannedString(R.string.not_course_update_event_updated, data.string("title"))
            Notifications.CourseUpdateType.ADDED -> actCtx.getHtmlSpannedString(R.string.not_course_update_event_added, data.string("title"))
        }

        override fun adapterText(
            actCtx: Context,
            type: Notifications.CourseUpdateType,
            data: JsonObject
        ): CharSequence? = when (type) {
            Notifications.CourseUpdateType.REMOVED -> actCtx.getHtmlSpannedString(R.string.adapter_course_update_event_removed, data.string("title"))
            Notifications.CourseUpdateType.UPDATED -> actCtx.getHtmlSpannedString(R.string.adapter_course_update_event_updated, data.string("title"))
            Notifications.CourseUpdateType.ADDED -> actCtx.getHtmlSpannedString(R.string.adapter_course_update_event_added, data.string("title"))
        }

        override fun adapterCallback(
            actCtx: Context,
            type: Notifications.CourseUpdateType,
            data: JsonObject,
            navController: NavController
        ): () -> Unit {
            return {
                GlobalScope.launch {
                    data.long("uid")
                        ?.let { AppDatabase.getInstance().eventDao().getEventById(it) }
                        ?.let { AppDatabase.getInstance().courseDao().getCourseById2(it.courseId) }
                        ?.let {
                            withContext(Dispatchers.Main) {
                                navController.navigate(NotificationFragmentDirections.actionNavNotificationsToCourseDetails(it.uid!!, it.title))
                            }
                        }
                }
            }
        }
    }
}
