package de.sebse.fuplanner2.whiteboard

import android.content.Context
import com.android.volley.VolleyError
import com.beust.klaxon.JsonObject
import com.beust.klaxon.Parser
import de.sebse.fuplanner2.database.AppDatabase
import de.sebse.fuplanner2.database.Course
import de.sebse.fuplanner2.database.Event
import de.sebse.fuplanner2.database.User
import de.sebse.fuplanner2.network.Requester
import de.sebse.fuplanner2.utils.UpdateResult
import de.sebse.fuplanner2.utils.console
import de.sebse.fuplanner2.utils.pmap
import de.sebse.fuplanner2.utils.updateResultOf
import de.sebse.fuplanner2.worker.FetchResourceErrorType
import de.sebse.fuplanner2.worker.FetchResourceException


suspend fun Whiteboard.getEvents(ctx: Context, database: AppDatabase, user: User, course: Course): UpdateResult<Event> {
    if (!isAvailable(user)) return UpdateResult()
    if (course.moduleType != MODULE_TYPE) return UpdateResult()
    val courseId = course.uid ?: return UpdateResult()

    val requester = Requester(ctx)
    val stored = database.eventDao().getAll2(courseId)

    try {
        val data = requester.get(
            FETCH_EVENT_LIST.format(course.internalId),
            getCookies(user)
        )
        val json = Parser.default().parse(StringBuilder(data.body)) as JsonObject
        val new = json.array<JsonObject>("calendar_collection")?.pmap { obj ->
            val type: String = obj.string("type") ?: "Event"
            val title: String = obj.string("title") ?: "Event"
            val duration: Long = obj.long("duration") ?: return@pmap null
            val firstTime: Long = obj.obj("firstTime")?.long("time") ?: return@pmap null
            val location: String? = obj.string("location")
            Event(null, courseId, System.currentTimeMillis(), title, duration, firstTime, location, type)
        }?.filterNotNull() ?: listOf()
        val result = updateResultOf(stored, new)
        database.eventDao().run {
            delete(result.removed)
            upsert(result.values)
        }
        return result
    } catch (e: VolleyError) {
        val statusCode = e.networkResponse.statusCode
        if (statusCode == 401)
            throw FetchResourceException(FetchResourceErrorType.ERR_AUTHORIZATION, statusCode)
        throw FetchResourceException(FetchResourceErrorType.ERR_NETWORK_ERROR, statusCode)
    }
}