package com.tenlionsoft.baselib.utils;

import android.content.Context;
import android.content.SharedPreferences;
import android.net.Uri;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.pddstudio.preferences.encrypted.EncryptedPreferences;
import com.tenlionsoft.baselib.constant.ConstantsV2;

import java.lang.reflect.Type;
import java.util.LinkedList;


/**
 * 加密本地缓存
 */
public class EncryptedSPTool {

    /**
     * SP中写入String类型value
     *
     * @param key   键
     * @param value 值
     */
    public static void putString(Context context, String key, String value) {
        EncryptedPreferences.EncryptedEditor editor = EncryptedPreferencesUtils.getInstance().edit();
        editor.putString(key, value);
        editor.apply();
    }

    /**
     * SP中写入String类型value
     *
     * @param key   键
     * @param value 值
     */
    public static void putString(String key, String value) {
        EncryptedPreferences.EncryptedEditor editor = EncryptedPreferencesUtils.getInstance().edit();
        editor.putString(key, value);
        editor.apply();
    }

    /**
     * SP中读取String
     *
     * @param key 键
     * @return 存在返回对应值，不存在返回默认值{@code defaultValue}
     */
    public static String getString(Context context, String key) {
        EncryptedPreferences sp = EncryptedPreferencesUtils.getInstance();
        String value;
        value = sp.getString(key, "");
        return value;
    }

    /**
     * SP中读取String
     *
     * @param key 键
     * @return 存在返回对应值，不存在返回默认值{@code defaultValue}
     */
    public static String getString(String key) {
        EncryptedPreferences sp = EncryptedPreferencesUtils.getInstance();
        String value;
        value = sp.getString(key, "");
        return value;
    }

    /**
     * SP中写入int类型value
     *
     * @param key   键
     * @param value 值
     */
    public static void putInt(String key, int value) {
        EncryptedPreferences encryptedPreferences = EncryptedPreferencesUtils.getInstance();
        EncryptedPreferences.EncryptedEditor editor = encryptedPreferences.edit();
        editor.putInt(key, value);
        editor.apply();
    }

    /**
     * SP中读取int
     *
     * @param key 键
     * @return 存在返回对应值，不存在返回默认值-1
     */
    public static int getInt(Context context, String key) {
        EncryptedPreferences sp = EncryptedPreferencesUtils.getInstance();
        int value;
        value = sp.getInt(key, -1);
        return value;
    }

    /**
     * SP中读取int
     *
     * @param key 键
     * @return 存在返回对应值，不存在返回默认值0
     */
    public static int getInt(String key, int defaultValue) {
        EncryptedPreferences sp = EncryptedPreferencesUtils.getInstance();
        int value;
        value = sp.getInt(key, defaultValue);
        return value;
    }

    /**
     * SP中写入long类型value
     *
     * @param key   键
     * @param value 值
     */
    public static void putLong(Context context, String key, long value) {
        EncryptedPreferences encryptedPreferences = EncryptedPreferencesUtils.getInstance();
        EncryptedPreferences.EncryptedEditor editor = encryptedPreferences.edit();
        editor.putLong(key, value);
        editor.apply();
    }

    /**
     * SP中读取long
     *
     * @param key 键
     * @return 存在返回对应值，不存在返回默认值-1
     */
    public static long getLong(Context context, String key) {
        EncryptedPreferences sp = EncryptedPreferencesUtils.getInstance();
        long value;
        value = sp.getLong(key, -1L);
        return value;
    }

    /**
     * SP中写入float类型value
     *
     * @param key   键
     * @param value 值
     */
    public static void putFloat(Context context, String key, float value) {
        EncryptedPreferences encryptedPreferences = EncryptedPreferencesUtils.getInstance();
        EncryptedPreferences.EncryptedEditor editor = encryptedPreferences.edit();
        editor.putFloat(key, value);
        editor.apply();
    }

    /**
     * SP中读取float
     *
     * @param key 键
     * @return 存在返回对应值，不存在返回默认值-1
     */
    public static float getFloat(Context context, String key) {
        EncryptedPreferences sp = EncryptedPreferencesUtils.getInstance();
        float value;
        value = sp.getFloat(key, -1F);
        return value;
    }

    /**
     * SP中写入boolean类型value
     *
     * @param key   键
     * @param value 值
     */
    public static void putBoolean(String key, boolean value) {
        EncryptedPreferences encryptedPreferences = EncryptedPreferencesUtils.getInstance();
        EncryptedPreferences.EncryptedEditor editor = encryptedPreferences.edit();
        editor.putBoolean(key, value);
        editor.apply();
    }


    /**
     * SP中读取boolean
     *
     * @param key 键
     * @return 存在返回对应值，不存在返回默认值{@code defaultValue}
     */
    public static boolean getBoolean(String key) {
        EncryptedPreferences sp = EncryptedPreferencesUtils.getInstance();
        boolean value;
        value = sp.getBoolean(key, false);
        return value;
    }

    /**
     * SP中读取boolean
     *
     * @param key 键
     * @return 存在返回对应值，不存在返回默认值{@code defaultValue}
     */
    public static boolean getBoolean(String key, boolean b) {
        EncryptedPreferences sp = EncryptedPreferencesUtils.getInstance();
        boolean value;
        value = sp.getBoolean(key, b);
        return value;
    }

    /**
     * SP中移除该key
     *
     * @param key 键
     */
    public static void remove(String key) {
        EncryptedPreferences sp = EncryptedPreferencesUtils.getInstance();
        sp.edit().remove(key).apply();
    }


    /**
     * 清除指定的信息
     *
     * @param context 上下文
     * @param name    键名
     * @param key     若为null 则删除name下所有的键值
     */
    public static void clearPreference(Context context, String name, String key) {
        EncryptedPreferences encryptedPreferences = EncryptedPreferencesUtils.getInstance();
        EncryptedPreferences.EncryptedEditor editor = encryptedPreferences.edit();
        if (key != null) {
            editor.remove(key);
        } else {
            editor.clear();
        }
        editor.apply();
    }

    /**
     * 用于保存集合
     *
     * @param context 上下文
     * @param key     key
     * @param list    集合数据
     * @return 保存结果
     */
    public static <T> boolean putListData(Context context, String key, LinkedList<T> list) {
        boolean result;
        SharedPreferences sp = context.getSharedPreferences(ConstantsV2.PREFS_ACCOUNT,
            Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        JsonArray array = new JsonArray();
        if (list.size() <= 0) {
            editor.putString(key, array.toString());
            editor.apply();
            return false;
        }
        String type = list.get(0).getClass().getSimpleName();
        try {
            switch (type) {
                case "Boolean":
                    for (int i = 0; i < list.size(); i++) {
                        array.add((Boolean) list.get(i));
                    }
                    break;
                case "Long":
                    for (int i = 0; i < list.size(); i++) {
                        array.add((Long) list.get(i));
                    }
                    break;
                case "Float":
                    for (int i = 0; i < list.size(); i++) {
                        array.add((Float) list.get(i));
                    }
                    break;
                case "String":
                    for (int i = 0; i < list.size(); i++) {
                        array.add((String) list.get(i));
                    }
                    break;
                case "Integer":
                    for (int i = 0; i < list.size(); i++) {
                        array.add((Integer) list.get(i));
                    }
                    break;
                default:
                    Gson gson = new GsonBuilder()
                        .registerTypeAdapter(Uri.class, new UriSerializer())
                        .create();
                    for (int i = 0; i < list.size(); i++) {
                        JsonElement obj = gson.toJsonTree(list.get(i));
                        array.add(obj);
                    }
                    break;
            }
            editor.putString(key, array.toString());
            result = true;
        } catch (Exception e) {
            result = false;
            e.printStackTrace();
        }
        editor.apply();
        return result;
    }

    /**
     * 获取保存的List
     *
     * @param context 上下文
     * @param key     key
     * @return 对应的Lis集合
     */
    public static <T> LinkedList<T> getListData(Context context, String key, Class<T> cls) {
        LinkedList<T> list = new LinkedList<>();
        SharedPreferences sp = context.getSharedPreferences(ConstantsV2.PREFS_ACCOUNT,
            Context.MODE_PRIVATE);
        String json = sp.getString(key, "");
        if (!json.equals("") && json.length() > 0) {
            Gson gson = new GsonBuilder()
                .registerTypeAdapter(Uri.class, new UriSerializer())
                .create();
            JsonArray array = new JsonParser().parse(json).getAsJsonArray();
            for (JsonElement elem : array) {
                list.add(gson.fromJson(elem, cls));
            }
        }
        return list;
    }


    public static class UriSerializer implements JsonSerializer<Uri>, JsonDeserializer<Uri> {
        @Override
        public JsonElement serialize(Uri src, Type typeOfSrc, JsonSerializationContext context) {
            return new JsonPrimitive(src.toString());
        }

        @Override
        public Uri deserialize(final JsonElement src, final Type srcType,
                               final JsonDeserializationContext context) throws JsonParseException {
            return Uri.parse(src.getAsString());
        }
    }
}
