package com.base.scanqrclear.luma

import android.content.Context
import android.content.SharedPreferences
import com.base.scanqrclear.MyApplication
import org.json.JSONObject

class SpUtils private constructor(context: Context) {

    private val sharedPreferences: SharedPreferences = context.getSharedPreferences("app_preferences", Context.MODE_PRIVATE)

    // 通用的保存数据方法
    fun <T> put(key: String, value: T) {
        when (value) {
            is String -> putString(key, value)
            is Int -> putInt(key, value)
            is Long -> putLong(key, value)
            is Boolean -> putBoolean(key, value)
            is Float -> putFloat(key, value)
            else -> throw IllegalArgumentException("Unsupported type")
        }
    }

    // 通用的获取数据方法
    fun <T> get(key: String, defaultValue: T): T {
        return when (defaultValue) {
            is String -> getString(key, defaultValue)
            is Int -> getInt(key, defaultValue)
            is Long -> getLong(key, defaultValue)
            is Boolean -> getBoolean(key, defaultValue)
            is Float -> getFloat(key, defaultValue)
            else -> throw IllegalArgumentException("Unsupported type")
        } as T
    }

    // 保存字符串
    fun putString(key: String, value: String) {
        sharedPreferences.edit().putString(getKey(key), value).apply()
    }

    // 获取字符串
    fun getString(key: String, defaultValue: String = ""): String {
        return sharedPreferences.getString(getKey(key), defaultValue) ?: defaultValue
    }

    // 保存整数
    fun putInt(key: String, value: Int) {
        sharedPreferences.edit().putInt(getKey(key), value).apply()
    }

    // 获取整数
    fun getInt(key: String, defaultValue: Int = 0): Int {
        return sharedPreferences.getInt(getKey(key), defaultValue)
    }

    // 保存长整数
    fun putLong(key: String, value: Long) {
        sharedPreferences.edit().putLong(getKey(key), value).apply()
    }

    // 获取长整数
    fun getLong(key: String, defaultValue: Long = 0): Long {
        return sharedPreferences.getLong(getKey(key), defaultValue)
    }

    // 保存布尔值
    fun putBoolean(key: String, value: Boolean) {
        sharedPreferences.edit().putBoolean(getKey(key), value).apply()
    }

    // 获取布尔值
    fun getBoolean(key: String, defaultValue: Boolean = false): Boolean {
        return sharedPreferences.getBoolean(getKey(key), defaultValue)
    }

    // 保存浮点数
    fun putFloat(key: String, value: Float) {
        sharedPreferences.edit().putFloat(getKey(key), value).apply()
    }

    // 获取浮点数
    fun getFloat(key: String, defaultValue: Float = 0f): Float {
        return sharedPreferences.getFloat(getKey(key), defaultValue)
    }

    // 删除键值对
    fun remove(key: String) {
        sharedPreferences.edit().remove(getKey(key)).apply()
    }

    // 清除所有数据
    fun clear() {
        sharedPreferences.edit().clear().apply()
    }

    // 检查键是否存在
    fun contains(key: String): Boolean {
        return sharedPreferences.contains(getKey(key))
    }

    // 保存 JSON 对象
    fun saveJsonObjectToSp(json: String) {
        try {
            if (json.isEmpty()) return

            val jsonObject = JSONObject(json)
            sharedPreferences.edit().apply {
                jsonObject.keys().forEachRemaining { key ->
                    val value = jsonObject.get(key)
                    val newKey = getKey(key)
                    when (value) {
                        is String -> putString(newKey, value)
                        is Int -> putInt(newKey, value)
                        is Long -> putLong(newKey, value)
                        is Boolean -> putBoolean(newKey, value)
                        else -> putString(newKey, value.toString())
                    }
                }
                apply()
            }
        } catch (_:Exception) { }
    }

    fun <T> getValue(key: String, default: T): T {
        val newKey = getKey(key)
        val value = get(newKey, default)
        return value
    }

    private fun getKey(key: String): String = "${MyApplication.appContext.packageName}_$key"

    companion object {
        @Volatile
        private var instance: SpUtils? = null

        // 单例模式获取实例
        fun getInstance(context: Context = MyApplication.appContext): SpUtils {
            return instance ?: synchronized(this) {
                instance ?: SpUtils(context).also {
                    instance = it
                }
            }
        }
    }
}