package com.tt.honeyDue.storage

import android.content.Context
import android.content.SharedPreferences
import android.util.Log
import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKey

/**
 * Android implementation of TokenManager using EncryptedSharedPreferences.
 *
 * Uses AndroidX Security Crypto library with AES256-GCM master key
 * to encrypt the auth token at rest. Falls back to regular SharedPreferences
 * if EncryptedSharedPreferences initialization fails (e.g., on very old devices
 * or when the Keystore is in a broken state).
 */
actual class TokenManager(private val context: Context) {
    private val prefs: SharedPreferences = createEncryptedPrefs(context)

    actual fun saveToken(token: String) {
        prefs.edit().putString(KEY_TOKEN, token).apply()
    }

    actual fun getToken(): String? {
        return prefs.getString(KEY_TOKEN, null)
    }

    actual fun clearToken() {
        prefs.edit().remove(KEY_TOKEN).apply()
    }

    companion object {
        private const val TAG = "TokenManager"
        private const val ENCRYPTED_PREFS_NAME = "honeydue_secure_prefs"
        private const val FALLBACK_PREFS_NAME = "honeydue_prefs"
        private const val KEY_TOKEN = "auth_token"

        @Volatile
        private var instance: TokenManager? = null

        fun getInstance(context: Context): TokenManager {
            return instance ?: synchronized(this) {
                instance ?: TokenManager(context.applicationContext).also { instance = it }
            }
        }

        /**
         * Creates EncryptedSharedPreferences backed by an AES256-GCM master key.
         * If initialization fails (broken Keystore, unsupported device, etc.),
         * falls back to plain SharedPreferences with a warning log.
         */
        private fun createEncryptedPrefs(context: Context): SharedPreferences {
            return try {
                val masterKey = MasterKey.Builder(context)
                    .setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
                    .build()

                EncryptedSharedPreferences.create(
                    context,
                    ENCRYPTED_PREFS_NAME,
                    masterKey,
                    EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
                    EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
                )
            } catch (e: Exception) {
                Log.w(
                    TAG,
                    "Failed to create EncryptedSharedPreferences, falling back to plain SharedPreferences. " +
                        "Auth tokens will NOT be encrypted at rest on this device.",
                    e
                )
                context.getSharedPreferences(FALLBACK_PREFS_NAME, Context.MODE_PRIVATE)
            }
        }
    }
}
