// Copyright (c) 2025 Gleb Zaharov. License: GPLv3 (see LICENSE).

package ru.sweetbread.unn.api

import android.util.Log
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.withContext
import ru.sweetbread.unn.db.cacheSchedule
import ru.sweetbread.unn.db.loadSchedule
import ru.sweetbread.unn.ui.layout.LoginData
import java.time.LocalDate


lateinit var PHPSESSID: String
lateinit var CSRF: String
lateinit var ME: User


/**
 * Authorize user by [login] and [password]
 *
 * Also defines local vars [PHPSESSID] and [ME]
 */
suspend fun auth(
    login: String = LoginData.login,
    password: String = LoginData.password,
    forced: Boolean = false
): Boolean {
    if (!forced) {
        if (::PHPSESSID.isInitialized and ::ME.isInitialized)
            return true
    }
    val id = getToken(login, password)
    if (id != null) {
        PHPSESSID = id
        getMyself(login)
        getCSRF()
        return true
    }
    return false
}

/**
 * Save info about current [User] in memory
 */
private suspend fun getMyself(login: String) = coroutineScope {
    val idDeferred = async { getId(login) }
    val userDeferred = async { getUser() }

    val id = idDeferred.await()
    val user = userDeferred.await()

    ME = User(
        unnId = id,
        userId = user.userId,
        type = Type.student,
        email = user.email,
        nameRu = user.nameRu,
        nameEn = user.nameEn,
        isMale = user.isMale,
        birthday = user.birthday,
        avatar = user.avatar
    )
}

suspend fun getScheduleDay(
    type: Type = ME.type,
    id: Int = ME.unnId!!,
    date: LocalDate
): ArrayList<ScheduleUnit> {

    if ((type == ME.type) and (id == ME.unnId!!)) {
        val schedule = withContext(Dispatchers.IO) { loadSchedule(date) }
        Log.d("Schedule", schedule.joinToString())
        if (schedule.isNotEmpty())
            return schedule
    }

    return getSchedule(type, id, date, date)
}

suspend fun getSchedule(
    type: Type = ME.type,
    id: Int = ME.unnId!!,
    start: LocalDate,
    finish: LocalDate
): ArrayList<ScheduleUnit> {
    val schedule = downloadSchedule(type, id, start, finish)

    if ((type == ME.type) and (id == ME.unnId!!))
        cacheSchedule(schedule)

    return schedule
}
