package de.trainingstagebuch.app.core

import android.content.Context
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.emptyPreferences
import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.datastore.preferences.preferencesDataStore
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.map
import java.io.IOException

private val Context.dataStore by preferencesDataStore(name = "session_store")

class SessionManager(private val context: Context) {

    private object Keys {
        val TOKEN = stringPreferencesKey("token")
        val USERNAME = stringPreferencesKey("username")
        val CURRENT_CLUB = stringPreferencesKey("current_club")
    }

    val session: Flow<SessionData> = context.dataStore.data
        .catch { e ->
            if (e is IOException) emit(emptyPreferences()) else throw e
        }
        .map { prefs -> prefs.toSessionData() }

    suspend fun save(token: String?, username: String?, currentClub: String?) {
        context.dataStore.edit { prefs ->
            setOrRemove(prefs, Keys.TOKEN, token)
            setOrRemove(prefs, Keys.USERNAME, username)
            setOrRemove(prefs, Keys.CURRENT_CLUB, currentClub)
        }
    }

    suspend fun clear() {
        context.dataStore.edit { it.clear() }
    }

    suspend fun logout() {
        clear()
    }

    private fun setOrRemove(prefs: androidx.datastore.preferences.core.MutablePreferences, key: Preferences.Key<String>, value: String?) {
        if (value.isNullOrBlank()) prefs.remove(key) else prefs[key] = value
    }

    private fun Preferences.toSessionData(): SessionData = SessionData(
        token = this[Keys.TOKEN],
        username = this[Keys.USERNAME],
        currentClub = this[Keys.CURRENT_CLUB]
    )
}

data class SessionData(
    val token: String?,
    val username: String?,
    val currentClub: String?
)
