package dev.kaizen.app.net

import android.content.Context
import android.content.SharedPreferences
import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKey
import kotlinx.serialization.json.Json
import kotlinx.serialization.encodeToString
import kotlinx.serialization.decodeFromString

/**
 * Hardware-backed encrypted persistence for the bearer token + server config.
 *
 * Uses `EncryptedSharedPreferences` (AES-256-GCM, key held in the Android KeyStore /
 * StrongBox on the S25 Ultra) so the `kzn_` token is never readable in plain text,
 * even on a rooted device. This is LATER.md §1A graduating now because a real
 * credential is held — biometrics/FLAG_SECURE binding stay deferred.
 */
class SecureStore(context: Context) {

    private val prefs: SharedPreferences = run {
        val masterKey = MasterKey.Builder(context.applicationContext)
            .setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
            .build()
        EncryptedSharedPreferences.create(
            context.applicationContext,
            "kaizen_secure",
            masterKey,
            EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
            EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM,
        )
    }

    fun load(): ServerConfig? {
        val baseUrl = prefs.getString(KEY_BASE_URL, null) ?: return null
        val token = prefs.getString(KEY_TOKEN, null) ?: return null
        val model = prefs.getString(KEY_MODEL, null) ?: DEFAULT_MODEL
        val email = prefs.getString(KEY_EMAIL, null) ?: ""
        val speed = prefs.getString(KEY_SPEED, null)
            ?.let { runCatching { ChatSpeed.valueOf(it) }.getOrNull() } ?: ChatSpeed.Normal
        return ServerConfig(baseUrl, token, model, email, speed)
    }

    fun save(config: ServerConfig) {
        prefs.edit()
            .putString(KEY_BASE_URL, config.baseUrl)
            .putString(KEY_TOKEN, config.token)
            .putString(KEY_MODEL, config.model)
            .putString(KEY_EMAIL, config.email)
            .putString(KEY_SPEED, config.speed.name)
            .apply()
    }

    /** Favorite model ids — pinned to the top of the picker. Not sensitive, but lives here to share one store. */
    fun loadFavorites(): Set<String> = prefs.getStringSet(KEY_FAVORITES, emptySet())!!.toSet()

    fun saveFavorites(ids: Set<String>) {
        prefs.edit().putStringSet(KEY_FAVORITES, ids).apply()
    }

    /** Caches the last successfully fetched model list locally for offline-first support. */
    fun loadModelsCache(): List<KaizenModel>? {
        val jsonStr = prefs.getString(KEY_MODELS_CACHE, null) ?: return null
        return try {
            Json.decodeFromString<List<KaizenModel>>(jsonStr)
        } catch (e: Exception) {
            null
        }
    }

    fun saveModelsCache(models: List<KaizenModel>) {
        try {
            val jsonStr = Json.encodeToString(models)
            prefs.edit().putString(KEY_MODELS_CACHE, jsonStr).apply()
        } catch (e: Exception) {
            // best-effort
        }
    }

    // ── Settings persistence ─────────────────────────────────────────────────

    fun loadThemeId(): String? = prefs.getString(KEY_THEME_ID, null)
    fun saveThemeId(id: String) { prefs.edit().putString(KEY_THEME_ID, id).apply() }

    fun loadAppearance(): String? = prefs.getString(KEY_APPEARANCE, null)
    fun saveAppearance(mode: String) { prefs.edit().putString(KEY_APPEARANCE, mode).apply() }

    fun loadUserName(): String? = prefs.getString(KEY_USER_NAME, null)
    fun saveUserName(name: String) { prefs.edit().putString(KEY_USER_NAME, name).apply() }

    fun loadLocale(): String? = prefs.getString(KEY_LOCALE, null)
    fun saveLocale(locale: String) { prefs.edit().putString(KEY_LOCALE, locale).apply() }

    fun loadBiometricEnabled(): Boolean = prefs.getBoolean(KEY_BIOMETRIC_ENABLED, true)
    fun saveBiometricEnabled(enabled: Boolean) { prefs.edit().putBoolean(KEY_BIOMETRIC_ENABLED, enabled).apply() }

    fun clear() {
        prefs.edit().clear().apply()
    }

    private companion object {
        const val KEY_BASE_URL = "base_url"
        const val KEY_TOKEN = "token"
        const val KEY_MODEL = "model"
        const val KEY_EMAIL = "email"
        const val KEY_SPEED = "speed"
        const val KEY_FAVORITES = "favorite_models"
        const val KEY_MODELS_CACHE = "models_cache"
        const val KEY_THEME_ID = "ui_theme"
        const val KEY_APPEARANCE = "appearance"
        const val KEY_USER_NAME = "user_name"
        const val KEY_LOCALE = "locale"
        const val KEY_BIOMETRIC_ENABLED = "biometric_enabled"
    }
}
