package eu.geyskens.pdfscan.data

import android.content.Context
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.datastore.preferences.preferencesDataStore
import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKey
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map

data class AppSettings(
    val paperlessUrl: String = "",
    val hasToken: Boolean = false,
    val defaultFilter: ScanFilter = ScanFilter.COLOR,
)

private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "settings")

/**
 * Persists app settings. Non-secret values live in DataStore; the Paperless API token
 * is kept in an AES-256 EncryptedSharedPreferences file backed by the Android Keystore,
 * so it is never stored in plaintext on the device.
 */
class SettingsRepository(private val context: Context) {

    private object Keys {
        val URL = stringPreferencesKey("paperless_url")
        val FILTER = stringPreferencesKey("default_filter")
    }

    private val securePrefs by lazy {
        val masterKey = MasterKey.Builder(context)
            .setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
            .build()
        EncryptedSharedPreferences.create(
            context,
            "secure_settings",
            masterKey,
            EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
            EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM,
        )
    }

    val settings: Flow<AppSettings> = context.dataStore.data.map { prefs ->
        AppSettings(
            paperlessUrl = prefs[Keys.URL].orEmpty(),
            hasToken = !getToken().isNullOrBlank(),
            defaultFilter = prefs[Keys.FILTER]?.let { runCatching { ScanFilter.valueOf(it) }.getOrNull() }
                ?: ScanFilter.COLOR,
        )
    }

    fun getToken(): String? = securePrefs.getString("paperless_token", null)

    fun setToken(token: String) {
        securePrefs.edit().putString("paperless_token", token).apply()
    }

    suspend fun setPaperlessUrl(url: String) {
        context.dataStore.edit { it[Keys.URL] = url }
    }

    suspend fun setDefaultFilter(filter: ScanFilter) {
        context.dataStore.edit { it[Keys.FILTER] = filter.name }
    }
}
