package com.quyunshuo.androidbaseframemvvm.base.utils;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonParser;

import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSyntaxException;
import com.quyunshuo.androidbaseframemvvm.base.factory.GsonFactory;
import com.quyunshuo.androidbaseframemvvm.base.utils.commons.StringUtils;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import io.netty.util.internal.StringUtil;


public class JsonUtils {

    /**
     * 获取Gson实例
     **/
    private static Gson getInstance() {
        //gsonBuilder.registerTypeAdapter(Object.class, new NaturalDeserializer());
        Gson gson = GsonFactory.getSingletonGson();
        return gson;
    }

    /**
     * 解析集合
     *
     * @param json      数据
     * @param beanClass 泛型
     * @return 泛型集合
     */
    public static <T> List<T> getBeanList(String json, Class<T> beanClass) {
        return getBeanList(json, null, beanClass);
    }

    /**
     * 解析集合
     *
     * @param json
     * @param key       json数据key
     * @param beanClass 泛型
     * @return 泛型集合
     */
    public static <T> List<T> getBeanList(String json, String key, Class<T> beanClass) {
        JsonParser parser = new JsonParser();
        Gson gson = getInstance();
        JsonElement contentElement = null;
        List<T> elementList = new ArrayList<T>();

        if (StringUtils.isNullOrEmpty(key) || StringUtils.isNullOrEmpty(json)) {
            contentElement = parser.parse(json).getAsJsonArray();
        } else {
            JsonObject jsonObject = parser.parse(json).getAsJsonObject();
            contentElement = jsonObject.get(key);
        }
        if (StringUtils.isNullOrEmpty(String.valueOf(contentElement)))
            return elementList;
        if (contentElement.isJsonArray()) {
            JsonArray jsonArray = contentElement.getAsJsonArray();
            try {
                for (int i = 0; i < jsonArray.size(); i++) {
                    JsonElement jsonObj = jsonArray.get(i);
                    T entity = gson.fromJson(jsonObj, beanClass);
                    elementList.add(entity);
                }
            } catch (ClassCastException e) {
            } catch (JsonParseException e) {
            }
            return elementList;
        }
        return elementList;
    }

    /**
     * 解析单个bean
     *
     * @param json
     * @param clazz
     * @return 泛型
     */
    public static <T> T getBean(String json, final Class<T> clazz) {
        return getBean(json, null, clazz);
    }

    /**
     * 解析单个bean
     *
     * @param json
     * @param key   解析的json数据key
     * @param clazz
     * @return 泛型
     */
    @SuppressWarnings("unchecked")
    public static <T> T getBean(String json, String key, final Class<T> clazz) {
        JsonParser parser = new JsonParser();
        Gson gson = getInstance();
        JsonElement contentElement = null;
        try {
            @SuppressWarnings("unused")
            JSONObject object = new JSONObject(json);
        } catch (JSONException e1) {
            return null;
        }
        if (StringUtils.isNullOrEmpty(key)) {
            contentElement = parser.parse(json).getAsJsonObject();
        } else {
            JsonObject jsonObject = parser.parse(json).getAsJsonObject();
            contentElement = jsonObject.get(key);
        }
        if (StringUtils.isNullOrEmpty(String.valueOf(contentElement)))
            return null;
        if (contentElement.isJsonPrimitive()) {
            if (clazz == String.class) {
                return (T) contentElement.getAsString();
            } else if (clazz == Integer.class) {
                return (T) Integer.valueOf(contentElement.getAsString());
            } else if (clazz == Number.class) {
                return (T) contentElement.getAsNumber();
            }
        } else if (contentElement.isJsonObject()) {
            JsonObject contentObj = contentElement.getAsJsonObject();
            T content = null;
            try {
                content = gson.fromJson(contentObj, clazz);
            } catch (ClassCastException e) {
            } catch (JsonParseException e) {
                System.out.println(e.getStackTrace().toString());
            }
            return content;
        }
        return null;
    }


    public static Object getObjectByKey(String json, String key, String targetkey) {
        JsonParser parser = new JsonParser();
        JsonElement jsonElement;
        try {
            JsonObject jsonObject = parser.parse(json).getAsJsonObject();
            jsonElement = jsonObject.get(key);
            return jsonElement.getAsJsonObject().get(targetkey).toString();
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 根据key 解析相关字段
     * {
     * "user": {
     * "name": "John",
     * "addresses": [
     * {
     * "city": "New York",
     * "zip": 10001
     * },
     * {
     * "city": "London",
     * "zip": 12345
     * }
     * ]
     * }
     * }
     * .getValue(jsonString, "user.name");
     * getValue(jsonString, "user.addresses[0].city");
     * getValue(jsonString, "user.addresses[1].zip")
     *
     * @return
     */
    public static <T> T getValue(String jsonString, String keyPath, Class<T> type) {
        Object value = getValue(jsonString, keyPath);
        return type.isInstance(value) ? type.cast(value) : null;
    }

    public static <T> T getValue(String jsonString, String keyPath) {
        try {
            Gson gson = getInstance();
            JsonElement jsonElement = gson.fromJson(jsonString, JsonElement.class);
            return getValue(jsonElement, keyPath);
        } catch (JsonSyntaxException e) {
            return null;
        }
    }

    private static final Pattern ARRAY_PATTERN = Pattern.compile("(.+)\\[(\\d+)\\]");

    /**
     * 从 JsonElement 中获取指定 Key 的值
     *
     * @param jsonElement 已解析的 JsonElement
     * @param keyPath     支持嵌套和数组的路径
     */
    @SuppressWarnings("unchecked")
    public static <T> T getValue(JsonElement jsonElement, String keyPath) {
        if (jsonElement == null || keyPath == null) return null;

        String[] keys = keyPath.split("\\.");
        JsonElement currentElement = jsonElement;

        for (String key : keys) {
            if (currentElement == null || currentElement.isJsonNull()) break;

            // 处理数组语法，例如 "items[0]"
            Matcher matcher = ARRAY_PATTERN.matcher(key);
            if (matcher.matches()) {
                String arrayKey = matcher.group(1);
                int index = Integer.parseInt(matcher.group(2));

                currentElement = getElementFromArray(currentElement, arrayKey, index);
            } else {
                currentElement = getElementFromObject(currentElement, key);
            }
        }

        return currentElement != null ? (T) parseElement(currentElement) : null;
    }

    private static JsonElement getElementFromObject(JsonElement element, String key) {
        if (element.isJsonObject()) {
            return element.getAsJsonObject().get(key);
        }
        return null;
    }

    private static JsonElement getElementFromArray(JsonElement element, String arrayKey, int index) {
        JsonElement arrayElement = getElementFromObject(element, arrayKey);
        if (arrayElement != null && arrayElement.isJsonArray()) {
            JsonArray jsonArray = arrayElement.getAsJsonArray();
            if (index >= 0 && index < jsonArray.size()) {
                return jsonArray.get(index);
            }
        }
        return null;
    }

    private static Object parseElement(JsonElement element) {
        if (element.isJsonPrimitive()) {
            JsonPrimitive primitive = element.getAsJsonPrimitive();
            if (primitive.isBoolean()) return primitive.getAsBoolean();
            if (primitive.isNumber()) return primitive.getAsNumber();
            return primitive.getAsString();
        } else if (element.isJsonArray() || element.isJsonObject()) {
            return element;
        }
        return null;
    }

    /**
     * JSONObject生成Json字符串
     **/
    public static String getJSONStringByJSONObject(JSONObject jsonobject) {
        String s;
        if (jsonobject == null)
            s = "";
        else
            s = jsonobject.toString();
        return s;
    }

    /**
     * JSONObject生成Json字符串
     **/
    public static String getJSONString(Object jsonobject) {
        Gson gson = getInstance();
        return gson.toJson(jsonobject);
    }


    /**
     * 解析JSONArray Json字符串
     **/
    public static JSONArray getJSONArrayByJSONString(String str) {
        JSONArray jsonarray;
        if (str != null)
            try {
                jsonarray = new JSONArray(str);
            } catch (JSONException _ex) {
                jsonarray = null;
            }
        else
            jsonarray = null;
        return jsonarray;
    }
}
