package plugin.library;

import android.content.Context;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;

import com.ansca.corona.CoronaActivity;
import com.ansca.corona.CoronaEnvironment;
import com.ansca.corona.CoronaRuntime;
import com.ansca.corona.CoronaRuntimeTask;
import com.naef.jnlua.LuaState;
import com.reyun.remote.config.OnRemoteConfigReceivedData;
import com.reyun.remote.config.OnRemoteConfigReceivedGenericsData;
import com.reyun.remote.config.RemoteConfigManager;
import com.reyun.solar.engine.DeepLinkCallBack;
import com.reyun.solar.engine.DeferredDeepLinkCallback;
import com.reyun.solar.engine.SeSdkSource;
import com.reyun.solar.engine.SolarEngineConfig;
import com.reyun.solar.engine.SolarEngineManager;
import com.reyun.solar.engine.config.CustomDomain;
import com.reyun.solar.engine.config.RemoteConfig;
import com.reyun.solar.engine.infos.DeeplinkInfo;
import com.reyun.solar.engine.infos.SEAdClickEventModel;
import com.reyun.solar.engine.infos.SEAdImpEventModel;
import com.reyun.solar.engine.infos.SEAppReEngagementModel;
import com.reyun.solar.engine.infos.SEAppRegisterFirstEventModel;
import com.reyun.solar.engine.infos.SEAttrEventModel;
import com.reyun.solar.engine.infos.SECustomEventModel;
import com.reyun.solar.engine.infos.SECustomFirstEventModel;
import com.reyun.solar.engine.infos.SELoginEventModel;
import com.reyun.solar.engine.infos.SEOrderEventModel;
import com.reyun.solar.engine.infos.SEPurchaseEventModel;
import com.reyun.solar.engine.infos.SERegisterEventModel;
import com.reyun.solar.engine.OnAttributionListener;
import com.reyun.solar.engine.OnInitializationCallback;
import com.reyun.solar.engine.infos.PresetEventType;
import com.reyun.solar.engine.tracker.SEUserDeleteType;
import com.reyun.solar.engine.utils.Objects;

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

import java.lang.reflect.Method;
import java.util.Iterator;

import javax.xml.validation.SchemaFactoryLoader;

public class SEPluginProxy {

    private static Context context = CoronaEnvironment.getApplicationContext();
    private final static String TAG = "SE.CoronaAndroidSDK";

    public static final String ERROR_MESSAGE_CONTEXT_IS_NULL = "context can not be null";
    public static final String ERROR_MESSAGE_APPKEY_IS_EMPTY = "appkey can not be empty";
    public static final String ERROR_MESSAGE_USERID_IS_EMPTY = "userid can not be empty";
    public static final String ERROR_MESSAGE_VISITORID_IS_NULL = "visitorid can not be empty";
    public static final String ERROR_MESSAGE_ACCOUNTID_IS_NULL = "accountid can not be empty";
    public static final String ERROR_MESSAGE_PROPERTIES_IS_EMPTY = "properties can not be empty";
    public static final String ERROR_MESSAGE_PROPERTIES_VALUE_IS_EMPTY = "properties value can not be null";
    public static final String ERROR_MESSAGE_PROPERTIES_KEY_IS_EMPTY = "properties key can not be empty";
    public static final String ERROR_MESSAGE_APP_IMP_DATA_IS_EMPTY = "app_imp data event can not be empty";
    public static final String ERROR_MESSAGE_APP_PURCHADATA_IS_EMPTY = "app_purchase event data can not be empty";
    public static final String ERROR_MESSAGE_CUSTOM_EVENT_NAME_IS_EMPTY = "custom event name can not be empty";
    public static final String ERROR_MESSAGE_CUSTOM_EVENT_DATA_IS_EMPTY = "custom event data can not be empty";
    public static final String ERROR_MESSAGE_TIMER_EVENT_NAME_IS_EMPTY = "timer event name can not be empty";
    public static final String ERROR_MESSAGE_TIMER_EVENT_DATA_IS_EMPTY = "timer event data can not be empty";
    public static final String ERROR_MESSAGE_TIMER_EVENT_CREATE_FAILED = "timer event create failed";
    public static final String ERROR_MESSAGE_KEYS_IS_EMPTY = "useunset keys must no be null";
    public static final String ERROR_MESSAGE_REGISTER_EVENT_DATA_IS_EMPTY = "app_register event data can not be empty";
    public static final String ERROR_MESSAGE_LOGIN_EVENT_DATA_IS_EMPTY = "app_login event data can not be empty";
    public static final String ERROR_MESSAGE_ORDER_EVENT_DATA_IS_EMPTY = "app_order event data can not be empty";
    public static final String ERROR_MESSAGE_CLICK_EVENT_DATA_IS_EMPTY = "app_click event data can not be empty";
    public static final String ERROR_MESSAGE_PRESET_EVENT_DATA_IS_EMPTY = "preset event data can not be empty";
    public static final String ERROR_MESSAGE_APP_ATTR_EVENT_DATA_IS_EMPTY = "app_attr event data can not be empty";
    public static final String ERROR_MESSAGE_ANALYSIS_CONFIG_FAILED = "SDK初始化失败，请检查参数格式是否正确";
    public static final String ERROR_MESSAGE_FIRST_EVENT_DATA_IS_EMPTY = "first event data can not be empty";
    public static final String ERROR_MESSAGE_EVENT_PROPERTIES_IS_EMPTY = "event properties can not be null";
    public static final String ERROR_MESSAGE_USER_PROPERTIES_IS_EMPTY = "user properties can not be null";
    public static final String ERROR_MESSAGE_DEFAULT_CONFIG_IS_EMPTY = "default config can not be null";
    public static final String ERROR_MESSAGE_PARAMKEY_IS_EMPTY = "paramkey is empty";
    public static final String ERROR_MESSAGE_CALLBACK_IS_NULL = "remote config callback can not be null";

    public static boolean isLogEnable = false;

    public static void debugLog(String msg) {
        if (isLogEnable) {
            Log.d(TAG, msg);
        }

    }

    public static void errorLog(String msg) {
        Log.e(TAG, msg);
    }


    public static void preInitSdk(String appKey) {
        debugLog("preInit ：appKey " + appKey);
        SolarEngineManager.getInstance().preInit(context, appKey);

    }

    public static void initialize(String seConfigStr, String propertiesStr) {

        String subLibVersion = "";
        String sdkType = "";

        debugLog("initialize ： " + "seConfig=: " + seConfigStr);

        try {
            JSONObject seConfigJo = new JSONObject(seConfigStr);
            JSONObject propertiesJo = new JSONObject(propertiesStr);
            String appKey = "";
            if (seConfigJo.has("appKey")) {
                appKey = seConfigJo.optString("appKey");

            }

            if (TextUtils.isEmpty(appKey)) {
                errorLog(ERROR_MESSAGE_APPKEY_IS_EMPTY);
                return;
            }
            SolarEngineConfig.Builder builder = new SolarEngineConfig.Builder();
            if (propertiesJo.has("subLibVersion")) {
                subLibVersion = propertiesJo.optString("subLibVersion");
            }
            if (propertiesJo.has("sdkType")) {
                sdkType = propertiesJo.optString("sdkType");
            }


            if (seConfigJo.has("logEnabled")) {
                isLogEnable = seConfigJo.optBoolean("logEnabled");
                if (isLogEnable) {
                    builder.logEnabled();
                }
            }
            if (seConfigJo.has("isGDPRArea")) {
                boolean isGDPRArea = seConfigJo.optBoolean("isGDPRArea");
                builder.isGDPRArea(isGDPRArea);
            }
            if (seConfigJo.has("enableDeferredDeeplink")) {
                boolean delayDeeplinkEnable = seConfigJo.optBoolean("enableDeferredDeeplink");
                builder.enableDelayDeeplink(delayDeeplinkEnable);
            }

            if (seConfigJo.has("isCoppaEnabled")) {
                boolean isCoppaEnabled = seConfigJo.optBoolean("isCoppaEnabled");
                builder.setCoppaEnabled(isCoppaEnabled);
            }

            if (seConfigJo.has("isKidsAppEnabled")) {
                boolean isKidsAppEnabled = seConfigJo.optBoolean("isKidsAppEnabled");
                builder.setKidsAppEnabled(isKidsAppEnabled);
            }

            if (seConfigJo.has("adPersonalizationEnabled")) {
                boolean adPersonalizationEnabled = seConfigJo.optBoolean("adPersonalizationEnabled");
                builder.adPersonalizationEnabled(adPersonalizationEnabled);
            }
            if (seConfigJo.has("adUserDataEnabled")) {
                boolean adUserDataEnabled = seConfigJo.optBoolean("adUserDataEnabled");
                builder.adUserDataEnabled(adUserDataEnabled);
            }
            if (seConfigJo.has("isDebugModel")) {
                boolean isDebugModel = seConfigJo.optBoolean("isDebugModel");
                builder.isDebugModel(isDebugModel);
            }

            if (seConfigJo.has("enable2GReporting")) {
                boolean isEnable2GReporting = seConfigJo.optBoolean("enable2GReporting");
                builder.enable2GReporting(isEnable2GReporting);
            }
            if (seConfigJo.has("fbAppId")) {
                String fbAppID = seConfigJo.optString("fbAppId");
                if (!TextUtils.isEmpty(fbAppID)) {
                    builder.setFbAppID(fbAppID);
                }
            }
            if (seConfigJo.has("supportMultiProcess")) {
                boolean result = seConfigJo.optBoolean("supportMultiProcess");
                builder.supportMultiProcess(result);
            }
            if (seConfigJo.has("isOAIdEnabled")) {
                boolean result = seConfigJo.optBoolean("isOAIdEnabled");
                builder.isOAIDEnabled(result);
            }
            if (seConfigJo.has("isImeiEnabled")) {
                boolean result = seConfigJo.optBoolean("isImeiEnabled");
                builder.isImeiEnabled(result);
            }
            if (seConfigJo.has("isAndroidIdEnabled")) {
                boolean result = seConfigJo.optBoolean("isAndroidIdEnabled");
                builder.isAndroidIDEnabled(result);
            }
            if (seConfigJo.has("enableIPV6Address")) {
                boolean result = seConfigJo.optBoolean("enableIPV6Address");
                builder.enableIPV6Address(result);
            }


            if (seConfigJo.has("customDomain")) {
                CustomDomain customDomain = getCustomDomain((JSONObject) seConfigJo.get("customDomain"));

                if (customDomain != null) {
                    builder.withCustomDomain(customDomain);

                }
            }
            if (seConfigJo.has("remoteConfig")) {
                RemoteConfig remoteConfig = getRemoteConfig(seConfigJo.optJSONObject("remoteConfig"));
                builder.withRemoteConfig(remoteConfig);
            }


            SolarEngineConfig config = builder.build();

            config.setOnAttributionListener(new OnAttributionListener() {
                @Override
                public void onAttributionSuccess(JSONObject jsonObject) {
                    String jsonStr = jsonObject != null ? jsonObject.toString() : "{}";
                    onAttribution(0, jsonStr);
                }

                @Override
                public void onAttributionFail(int errorCode) {
                    // 失败时返回空 json
                }
            });

            SolarEngineManager.getInstance().setDeferredDeepLinkCallback(new DeferredDeepLinkCallback() {


                @Override
                public void onReceivedSuccess(JSONObject jsonObject) {

                    onDeferredDeeplinkCompleted(0, jsonObject);
                }

                @Override
                public void onReceivedFailed(int i) {
                    JSONObject attrResult = new JSONObject();
                    try {
                        attrResult.put("code", i);
                        onDeferredDeeplinkCompleted(i, null);
                    } catch (JSONException e) {
                        Log.e(TAG, "onAttributionFail JSONException : " + e);
                    }
                }


            });

//            mockDeferredDeeplinkSuccess(0);
//            mockDeeplinkSuccess(0);
            SolarEngineManager.getInstance().setDeepLinkCallback(new DeepLinkCallBack() {
                @Override
                public void onReceived(int i, DeeplinkInfo deeplinkInfo) {

                    JSONObject data = new JSONObject();
                    Log.e("setDeepLinkCallback", deeplinkInfo.toString());
                    try {
                        if (deeplinkInfo != null) {
                            data.put("sedpLink", deeplinkInfo.sedpLink);
                            data.put("turlId", deeplinkInfo.turlId);
                            data.put("from", deeplinkInfo.from);
                            data.put("baseUrl", deeplinkInfo.baseURL);
                            data.put("url", deeplinkInfo.url);
                            data.put("customParams", deeplinkInfo.customParams);
                        }
                        onDeepLinkCompleted(i, data);
                    } catch (JSONException e) {
                        Log.e(TAG, "onReceived JSONException : " + e);
                    }


                }
            });


            SeSdkSource seSdkSource = new SeSdkSource();
            seSdkSource.setSubLibVersion(subLibVersion);
            seSdkSource.setSdkType(sdkType);
            SolarEngineManager.getInstance().setSeSdkSource(seSdkSource);


            SolarEngineManager.getInstance().initialize(context, appKey, config, new OnInitializationCallback() {
                @Override
                public void onInitializationCompleted(int code) {

                    onInitCompleted(code);

                }
            });

        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

    public static void appDeeplinkOpenURL(String uriString) {

        try {
            if (!TextUtils.isEmpty(uriString)) {
                Uri uri = Uri.parse(uriString);
                SolarEngineManager.getInstance().appDeeplinkOpenURI(uri);
            } else {
                Log.e(TAG, "appDeeplinkOpenURL failed, url is empty!");
            }
        } catch (Exception e) {
            Log.e(TAG, "Error opening deeplink: " + e.getMessage());
        }
    }

    public static void setVisitorID(String visitorId) {
        debugLog("setVisitorID visitorID = " + visitorId);
        SolarEngineManager.getInstance().setVisitorID(visitorId);
    }

    public static String getVisitorID() {
        debugLog("getVisitorID");
        return SolarEngineManager.getInstance().getVisitorID();

    }

    public static String getDistinctId() {
        debugLog("getDistinctId");
        return SolarEngineManager.getInstance().getDistinctId();
    }

    public static String getAccountId() {
        debugLog("getAccountId");

        return SolarEngineManager.getInstance().getAccountID();
    }

    public static void login(String accountId) {
        debugLog("loginWithAccountID accountId = " + accountId);
        SolarEngineManager.getInstance().login(accountId);
    }

    public static void logout() {
        debugLog("logout");
        SolarEngineManager.getInstance().logout();
    }

    private static boolean isValidJsonString(String str) {
        return str != null && !str.isEmpty() && !"null".equals(str);
    }

    public static void trackEvent(String eventName, String customJsonString, String preJsonString) {
        if (TextUtils.isEmpty(eventName)) {
            errorLog(ERROR_MESSAGE_CUSTOM_EVENT_NAME_IS_EMPTY);
            return;
        }
        debugLog("trackEvent eventName = " + eventName + "customJsonString " + customJsonString + " preJsonString = " + preJsonString);
        try {
            JSONObject customJson = null;
            if (isValidJsonString(customJsonString)) {
                customJson = new JSONObject(customJsonString);
            }
            JSONObject preJson = null;
            if (isValidJsonString(preJsonString)) {
                preJson = new JSONObject(preJsonString);
            }
            SECustomEventModel seCustomEventModel = new SECustomEventModel(eventName, preJson, customJson);
            SolarEngineManager.getInstance().track(seCustomEventModel);
        } catch (Exception e) {
            errorLog("trackEvent failed , see the details : " + e.toString());
        }
    }

    public static void trackFirst(String eventName, String firstCheckId, String json) {

        try {
            JSONObject firstEventJson = new JSONObject(json);

            JSONObject customProperties =null;



            if (eventName.equals("_appReg")) {
                SEAppRegisterFirstEventModel seAppRegisterFirstEventModel = new SEAppRegisterFirstEventModel();
                String regType = firstEventJson.optString("registerType");
                seAppRegisterFirstEventModel.setRegType(regType);
                String appRegStatus = firstEventJson.optString("registerStatus");
                seAppRegisterFirstEventModel.setStatus(appRegStatus);
                customProperties= firstEventJson.optJSONObject("customProperties");
                if (Objects.isNotEmpty(firstCheckId)) {
                    seAppRegisterFirstEventModel.setCheckId(firstCheckId);
                }
                if (Objects.isNotNull(customProperties)) {

                    seAppRegisterFirstEventModel.setCustomProperties(customProperties);
                }
                SolarEngineManager.getInstance().trackFirstEvent(seAppRegisterFirstEventModel);
            } else {
                SECustomFirstEventModel seCustomFirstEventModel = new SECustomFirstEventModel();
                seCustomFirstEventModel.setEventName(eventName);
                customProperties= firstEventJson;
                if (Objects.isNotEmpty(firstCheckId)) {
                    seCustomFirstEventModel.setCheckId(firstCheckId);
                }
                if (Objects.isNotNull(customProperties)) {
                    seCustomFirstEventModel.setCustomProperties(customProperties);
                }

                SolarEngineManager.getInstance().trackFirstEvent(seCustomFirstEventModel);
            }


        } catch (Exception e) {
            errorLog("sendFirstTrack failed , see the details : " + e.toString());
        }

    }

    public static void eventStart(String eventName) {
        debugLog("eventStart eventName = " + eventName);
        SolarEngineManager.getInstance().eventStart(eventName);
    }

    public static void eventFinish(String eventName, String customJsonString) {
        debugLog("eventFinish eventName = " + eventName + ", customJsonString = " + customJsonString);
        if (TextUtils.isEmpty(eventName)) {
            errorLog(ERROR_MESSAGE_CUSTOM_EVENT_NAME_IS_EMPTY);
            return;
        }
        try {
            JSONObject dataJson = null;
            if (isValidJsonString(customJsonString)) {
                dataJson = new JSONObject(customJsonString);
            }
            SolarEngineManager.getInstance().eventFinish(eventName, dataJson);
        } catch (Exception e) {
            errorLog("sendTimerFinishTrack failed , see the details : " + e.toString());
        }
    }

    public static void trackPurchase(String json) {
        debugLog("trackPurchase " + json);

        if (TextUtils.isEmpty(json)) {
            errorLog(ERROR_MESSAGE_APP_PURCHADATA_IS_EMPTY);
            return;
        }
        try {
            JSONObject purchaseJson = new JSONObject(json);
            String orderId = purchaseJson.optString("orderId");
            double payAmount = purchaseJson.optDouble("payAmount");
            String currencyType = purchaseJson.optString("currencyType");
            String payType = purchaseJson.optString("payType");
            String productId = purchaseJson.optString("productId");
            String productName = purchaseJson.optString("productName");
            int productNum = purchaseJson.optInt("productCount");
            int payStatus = purchaseJson.optInt("payStatus");
            String failReason = purchaseJson.optString("failReason");
            JSONObject customProperties = null;
            String customJsonString = purchaseJson.optString("customProperties");

            if (isValidJsonString(customJsonString)) {
                customProperties = new JSONObject(customJsonString);
            }
            SEPurchaseEventModel sePurchaseEventModel = new SEPurchaseEventModel(orderId, payAmount, currencyType, payType, productId, productName, productNum, payStatus, failReason, customProperties);
            SolarEngineManager.getInstance().trackPurchase(sePurchaseEventModel);
        } catch (Exception e) {
            errorLog("trackPurchase failed , see the details : " + e.toString());
        }
    }

    public static void trackAdImpression(String json) {
        debugLog("trackAdImpression " + json);

        if (TextUtils.isEmpty(json)) {
            errorLog(ERROR_MESSAGE_APP_IMP_DATA_IS_EMPTY);
            return;
        }
        try {
            JSONObject impJson = new JSONObject(json);
            debugLog(impJson.toString(4));

            String adNetworkPlatform = impJson.optString("adPlatform");
            String mediationPlatform = impJson.optString("mediationPlatform");
            int adType = impJson.optInt("adType");
            String adNetworkAppID = impJson.optString("adAppId");
            String adNetworkADID = impJson.optString("adId");
            double ecpm = impJson.optDouble("adECPM");
            String currencyType = impJson.optString("currencyType");
            boolean isRenderSuccess = impJson.optBoolean("isRendered");
            String customJsonString = impJson.optString("customProperties");
            JSONObject customProperties = null;
            if (isValidJsonString(customJsonString)) {
                customProperties = new JSONObject(customJsonString);
            }
            SEAdImpEventModel seAdImpEventModel = new SEAdImpEventModel(adNetworkPlatform, mediationPlatform, adType, adNetworkAppID, adNetworkADID, ecpm, currencyType, isRenderSuccess, customProperties);
            SolarEngineManager.getInstance().trackAdImpression(seAdImpEventModel);
        } catch (Exception e) {
            errorLog("trackAdImpression failed , see the details : " + e.toString());
        }
    }

    public static void trackAdClick(String json) {
        debugLog("trackAdClick " + json);
        if (TextUtils.isEmpty(json)) {
            errorLog(ERROR_MESSAGE_CLICK_EVENT_DATA_IS_EMPTY);
            return;
        }
        try {
            JSONObject clickJson = new JSONObject(json);

            String adPlatform = clickJson.optString("adNetworkPlatform");
            String mediationPlatform = clickJson.optString("mediationPlatform");
            String adId = clickJson.optString("adNetworkPlacementId");
            int adType = clickJson.optInt("adType");
            String customJsonString = clickJson.optString("customProperties");
            JSONObject customProperties = null;
            if (isValidJsonString(customJsonString)) {
                customProperties = new JSONObject(customJsonString);
            }
            SEAdClickEventModel seAdClickEventModel = new SEAdClickEventModel(adPlatform, mediationPlatform, adType, adId, customProperties);
            SolarEngineManager.getInstance().trackAdClick(seAdClickEventModel);
        } catch (Exception e) {
            errorLog("trackAdClick failed , see the details : " + e.toString());
        }
    }

    public static void trackAppAttr(String json) {
        debugLog("trackAppAttr " + json);
        if (TextUtils.isEmpty(json)) {
            errorLog(ERROR_MESSAGE_APP_ATTR_EVENT_DATA_IS_EMPTY);
            return;
        }
        try {
            JSONObject appAttrJson = new JSONObject(json);
            String adNetwork = appAttrJson.optString("adNetwork");
            String subChannel = appAttrJson.optString("subChannel");
            String adAccountId = appAttrJson.optString("adAccountId");
            String adAccountName = appAttrJson.optString("adAccountName");
            String adCampaignId = appAttrJson.optString("adCampaignId");
            String adCampaignName = appAttrJson.optString("adCampaignName");
            String adOfferId = appAttrJson.optString("adOfferId");
            String adOfferName = appAttrJson.optString("adOfferName");
            String adCreativeId = appAttrJson.optString("adCreativeId");
            String adCreativeName = appAttrJson.optString("adCreativeName");
            String attributionPlatform = appAttrJson.optString("attributionPlatform");
            String customJsonString = appAttrJson.optString("customProperties");
            JSONObject customProperties = null;
            if (isValidJsonString(customJsonString)) {
                customProperties = new JSONObject(customJsonString);
            }
            SEAttrEventModel seAttrEventModel = new SEAttrEventModel(adNetwork, subChannel, adAccountId, adAccountName, adCampaignId, adCampaignName, adOfferId, adOfferName, adCreativeId, adCreativeName, attributionPlatform, customProperties);
            SolarEngineManager.getInstance().trackAttr(seAttrEventModel);

        } catch (Exception e) {
            Log.e(TAG, "trackAttr failed , see the details : " + e.toString());
        }
    }

    public static void trackLogin(String loginJsonString) {
        debugLog("trackLogin " + loginJsonString);
        if (TextUtils.isEmpty(loginJsonString)) {
            errorLog(ERROR_MESSAGE_LOGIN_EVENT_DATA_IS_EMPTY);
            return;
        }
        try {
            JSONObject loginJson = new JSONObject(loginJsonString);
            String loginType = loginJson.optString("loginType");
            String status = loginJson.optString("loginStatus");
            JSONObject customProperties = null;
            String customJsonString = loginJson.optString("customProperties");
            if (isValidJsonString(customJsonString)) {
                customProperties = new JSONObject(customJsonString);
            }
            SELoginEventModel seLoginEventModel = new SELoginEventModel(loginType, status, customProperties);
            SolarEngineManager.getInstance().trackAppLogin(seLoginEventModel);
        } catch (Exception e) {
            errorLog("trackLogin failed , see the details : " + e.toString());
        }
    }

    public static void trackRegister(String registerJsonString) {
        debugLog("trackRegister " + registerJsonString);
        if (TextUtils.isEmpty(registerJsonString)) {
            errorLog(ERROR_MESSAGE_REGISTER_EVENT_DATA_IS_EMPTY);
            return;
        }
        try {
            JSONObject registerJson = new JSONObject(registerJsonString);
            String regType = registerJson.optString("registerType");
            String status = registerJson.optString("registerStatus");
            JSONObject customProperties = null;
            String customJsonString = registerJson.optString("customProperties");
            if (isValidJsonString(customJsonString)) {
                customProperties = new JSONObject(customJsonString);
            }
            SERegisterEventModel seRegisterEventModel = new SERegisterEventModel(regType, status, customProperties);
            SolarEngineManager.getInstance().trackAppRegister(seRegisterEventModel);
            //            SolarEngineManager.getInstance().trackAppRegister(regType, status, customProperties);
        } catch (Exception e) {
            errorLog("trackRegister failed , see the details : " + e.toString());
        }
    }

    public static void trackOrder(String orderJsonString) {
        debugLog("trackOrder " + orderJsonString);
        if (TextUtils.isEmpty(orderJsonString)) {
            errorLog(ERROR_MESSAGE_ORDER_EVENT_DATA_IS_EMPTY);
            return;
        }
        try {
            JSONObject orderJson = new JSONObject(orderJsonString);
            String orderId = orderJson.optString("orderId");
            double payAmount = orderJson.optDouble("payAmount");
            String currencyType = orderJson.optString("currencyType");
            String payType = orderJson.optString("payType");
            String status = orderJson.optString("status");
            JSONObject customProperties = null;
            String customJsonString = orderJson.optString("customProperties");
            if (isValidJsonString(customJsonString)) {
                customProperties = new JSONObject(customJsonString);
            }
            SEOrderEventModel seOrderEventModel = new SEOrderEventModel(orderId, payAmount, currencyType, payType, status, customProperties);
            SolarEngineManager.getInstance().trackOrder(seOrderEventModel);
            //            SolarEngineManager.getInstance().track(orderId, payAmount, currencyType, payType, status, customProperties);
        } catch (Exception e) {
            errorLog("trackOrder failed , see the details : " + e.toString());
        }
    }

    public static void trackAppReEngagement(String customData) {
        debugLog("trackAppReEngagement customData = " + customData);
        try {
            SEAppReEngagementModel seAppReEngagementModel = new SEAppReEngagementModel();
            if (!TextUtils.isEmpty(customData)) {
                try {
                    JSONObject customPropertiesJson = new JSONObject(customData);
                    seAppReEngagementModel.setCustomProperties(customPropertiesJson);
                } catch (Exception e) {
                    errorLog("trackAppReEngagement failed , see the details : " + e);
                }
            }
            SolarEngineManager.getInstance().trackAppReEngagement(seAppReEngagementModel);
        } catch (Exception e) {
            errorLog("trackAppReEngagement failed , see the details : " + e);
        }

    }


    public static void userInit(String json) {
        if (TextUtils.isEmpty(json)) {
            errorLog(ERROR_MESSAGE_PROPERTIES_IS_EMPTY);
            return;
        }
        try {
            JSONObject properties = new JSONObject(json);
            SolarEngineManager.getInstance().userInit(properties);
        } catch (Exception e) {
            errorLog("userInit failed , see the details : " + e.toString());
        }
    }


    public static void userUnset(String keysJson) {
        if (TextUtils.isEmpty(keysJson)) {
            errorLog(ERROR_MESSAGE_PROPERTIES_IS_EMPTY);
            return;
        }
        try {
            // 将 keysStr 解析为 JSON 数组
            JSONArray jsonArray = new JSONArray(keysJson);
            String[] keys = new String[jsonArray.length()];
            for (int i = 0; i < jsonArray.length(); i++) {
                keys[i] = jsonArray.getString(i);
            }
            // 调用原生 SDK 的 userUnset 方法,传入 keys 数组
            SolarEngineManager.getInstance().userUnset(keys);
        } catch (JSONException e) {
            errorLog("Failed to parse keys: " + keysJson + e.getMessage());
        }
    }

    public static void userAdd(String json) {
        if (TextUtils.isEmpty(json)) {
            errorLog(ERROR_MESSAGE_PROPERTIES_IS_EMPTY);
            return;
        }
        try {
            JSONObject properties = new JSONObject(json);
            SolarEngineManager.getInstance().userAdd(properties);
        } catch (Exception e) {
            errorLog("userAdd failed , see the details : " + e.toString());
        }
    }

    public static void userAppend(String json) {
        if (TextUtils.isEmpty(json)) {
            errorLog(ERROR_MESSAGE_PROPERTIES_IS_EMPTY);
            return;
        }
        try {
            JSONObject properties = new JSONObject(json);
            SolarEngineManager.getInstance().userAppend(properties);
        } catch (Exception e) {
            errorLog("userAppend failed , see the details : " + e.toString());
        }
    }

    public static void userUpdate(String json) {
        if (TextUtils.isEmpty(json)) {
            errorLog(ERROR_MESSAGE_PROPERTIES_IS_EMPTY);
            return;
        }
        try {
            JSONObject properties = new JSONObject(json);
            SolarEngineManager.getInstance().userUpdate(properties);
        } catch (Exception e) {
            errorLog("userUpdate failed , see the details : " + e.toString());
        }
    }

    public static void userDelete(int seUserDeleteType) {
        debugLog("userDelete seUserDeleteType = " + seUserDeleteType);
        SolarEngineManager.getInstance().userDelete(seUserDeleteType == 0 ? SEUserDeleteType.DELETE_BY_ACCOUNTID : SEUserDeleteType.DELETE_BY_VISITORID);

    }

    public static void setSuperProperties(String propertiesJsonStr) {

        debugLog("setSuperProperties json = " + propertiesJsonStr);
        if (TextUtils.isEmpty(propertiesJsonStr)) {
            errorLog(ERROR_MESSAGE_PROPERTIES_IS_EMPTY);
            return;
        }


        try {
            JSONObject propertiesJson = new JSONObject(propertiesJsonStr);
            Iterator<String> iter = propertiesJson.keys();
            while (iter.hasNext()) {
                String key = iter.next();
                Object value = propertiesJson.get(key);
                doProperties(context.getApplicationContext(), key, value);
            }
        } catch (JSONException e) {
            errorLog(e.toString());
        }
    }

    private static void doProperties(Context context, String key, Object value) {
        if (TextUtils.isEmpty(key)) {
            errorLog(ERROR_MESSAGE_PROPERTIES_KEY_IS_EMPTY);
            return;
        }
        if (null == value) {
            errorLog(ERROR_MESSAGE_PROPERTIES_VALUE_IS_EMPTY);
            return;
        }
        if (value instanceof Integer) {
            SolarEngineManager.getInstance().setSuperProperties(context, key, (Integer) value);
        }
        if (value instanceof Float) {
            SolarEngineManager.getInstance().setSuperProperties(context, key, (Float) value);
        }
        if (value instanceof Long) {
            SolarEngineManager.getInstance().setSuperProperties(context, key, (Long) value);
        }
        if (value instanceof Double) {
            SolarEngineManager.getInstance().setSuperProperties(context, key, (Double) value);
        }
        if (value instanceof Boolean) {
            SolarEngineManager.getInstance().setSuperProperties(context, key, (Boolean) value);
        }
        if (value instanceof String) {
            SolarEngineManager.getInstance().setSuperProperties(context, key, (String) value);
        }
        if (value instanceof JSONArray) {
            SolarEngineManager.getInstance().setSuperProperties(context, key, (JSONArray) value);
        }
        if (value instanceof JSONObject) {
            SolarEngineManager.getInstance().setSuperProperties(context, key, (JSONObject) value);
        }
    }

    public static void unsetSuperProperty(String key) {
        debugLog("unsetSuperProperty key = " + key);
        if (TextUtils.isEmpty(key)) {
            errorLog(ERROR_MESSAGE_PROPERTIES_KEY_IS_EMPTY);
            return;
        }

        SolarEngineManager.getInstance().unsetSuperProperty(context, key);
    }

    public static void clearSuperProperties() {
        debugLog("clearSuperProperties");

        SolarEngineManager.getInstance().clearSuperProperties(context.getApplicationContext());
    }

    public static void setPresetEvent(int eventType, String eventDataJSONString) {
        debugLog("setPresetEvent eventType = " + eventType + " eventDataJSONString = " + eventDataJSONString);
        PresetEventType type = PresetEventType.values()[eventType];

        if (eventDataJSONString == null || eventDataJSONString.equals("null") || eventDataJSONString.isEmpty()) {
            SolarEngineManager.getInstance().setPresetEventProperties(type, null);
            return;
        }

        try {
            JSONObject presetJson = new JSONObject(eventDataJSONString);
            if (null == presetJson) {
                errorLog(ERROR_MESSAGE_PRESET_EVENT_DATA_IS_EMPTY);
                return;
            }
            SolarEngineManager.getInstance().setPresetEventProperties(type, presetJson);
        } catch (JSONException e) {
            errorLog("setPresetEvent failed , see the details : " + e.toString());
        }
    }

    public static void setChannel(String channel) {
        debugLog("setChannel");
        SolarEngineManager.getInstance().setChannel(channel);
    }

    public static void reportEventImmediately() {
        debugLog("reportEventImmediately");
        SolarEngineManager.getInstance().reportEventImmediately();
    }

    public static String getPresetProperties() {
        debugLog("getPresetProperties");
        JSONObject jsonObject = SolarEngineManager.getInstance().getPresetProperties();
        return jsonObject == null ? "" : jsonObject.toString();

    }

    public static void setOaid(String oaid) {

        debugLog("setOaid oaid = " + oaid);
        if (TextUtils.isEmpty(oaid)) {
            return;
        }
        try {
            // 获取 GetOaidManager 类的实例
            Class<?> getOaidManagerClass = Class.forName("com.reyun.plugin.oaid.GetOaidManager");
            Object getOaidManagerInstance = getOaidManagerClass.getDeclaredMethod("getInstance").invoke(null);

            // 获取 setOaid 方法
            Method setOaidMethod = getOaidManagerClass.getDeclaredMethod("setOaid", String.class);

            // 调用 setOaid 方法
            setOaidMethod.invoke(getOaidManagerInstance, oaid);
            errorLog("setOaid success !");
        } catch (Exception e) {
            errorLog("setOaid failed , see the details : " + e.toString());
        }

    }

    public static void setGDPRArea(boolean isGDPR) {
        debugLog("setGDPRArea isGDPR = " + isGDPR);
        SolarEngineManager.getInstance().setGDPRArea(isGDPR);
    }

    public static void setGaid(String gaid) {
        debugLog("setGaid gaid = " + gaid);
        SolarEngineManager.getInstance().setGaid(gaid);
    }

    public static String getAttributionData() {
        JSONObject jsonObject = SolarEngineManager.getInstance().getAttribution();
        if (Objects.isNotNull(jsonObject)) {
            try {
                return jsonObject.toString();
            } catch (Exception e) {
                errorLog("getAttribution failed,ex:" + e.toString());
            }
        }
        return null;

    }

    private static RemoteConfig getRemoteConfig(JSONObject rcConfigJo) {

        RemoteConfig remoteConfig = new RemoteConfig();
//        try {
//            JSONObject rcConfigJo = new JSONObject(rcConfigStr);
        boolean enable = false;
        if (rcConfigJo.has("enable")) {
            remoteConfig.setEnable(rcConfigJo.optBoolean("enable", false));
            /// remoteConfig.setEnable(true);
        }
        if (rcConfigJo.has("mergeType")) {
            int mergeType = rcConfigJo.optInt("mergeType");
            switch (mergeType) {
                case 0:
                    remoteConfig.setMergeType(RemoteConfig.MergeType.WITH_CACHE);
                    break;
                case 1:
                    remoteConfig.setMergeType(RemoteConfig.MergeType.WITH_USER);
                    break;
            }
        }
        if (rcConfigJo.has("customIDProperties")) {
            JSONObject customIDProperties = rcConfigJo.optJSONObject("customIDProperties");
            remoteConfig.setCustomIDProperties(customIDProperties);
        }
        if (rcConfigJo.has("customIDEventProperties")) {
            JSONObject customIDEventProperties = rcConfigJo.optJSONObject("customIDEventProperties");
            remoteConfig.setCustomIDEventProperties(customIDEventProperties);
        }
        if (rcConfigJo.has("customIDUserProperties")) {
            JSONObject customIDUserProperties = rcConfigJo.optJSONObject("customIDUserProperties");
            remoteConfig.setCustomIDUserProperties(customIDUserProperties);
        }
//        } catch (Exception e) {
//            errorLog("getRemoteConfig Exception = " + e.toString());
//        }
        return remoteConfig;
    }

    private static CustomDomain getCustomDomain(JSONObject customDomainObj) {
        try {
            CustomDomain customDomain = new CustomDomain();
            if (customDomainObj != null) {
                boolean enable = false;
                if (customDomainObj.has("enable")) {
                    enable = (boolean) customDomainObj.get("enable");

                }
                if (enable)
                    customDomain.setEnable(enable);
                else
                    return null;
                if (customDomainObj.has("receiverDomain")) {
                    String receiverDomain = (String) customDomainObj.get("receiverDomain");
                    customDomain.setReceiverDomain(receiverDomain);
                }
                if (customDomainObj.has("ruleDomain")) {
                    String ruleDomain = (String) customDomainObj.get("ruleDomain");
                    customDomain.setRuleDomain(ruleDomain);
                }
                if (customDomainObj.has("tcpReceiverHost")) {
                    String tcpReceiverHost = (String) customDomainObj.get("tcpReceiverHost");
                    customDomain.setTcpReceiverHost(tcpReceiverHost);
                }
                if (customDomainObj.has("tcpRuleHost")) {
                    String tcpRuleHost = (String) customDomainObj.get("tcpRuleHost");
                    customDomain.setTcpRuleHost(tcpRuleHost);
                }
                if (customDomainObj.has("tcpGatewayHost")) {
                    String tcpGatewayHost = (String) customDomainObj.get("tcpGatewayHost");
                    customDomain.setTcpGatewayHost(tcpGatewayHost);
                }
                return customDomain;
            }
        } catch (Exception e) {
            errorLog("getCustomDomain Exception = " + e.toString());
        }
        return null;
    }

    //在线参数
    public static void setRemoteDefaultConfig(String rcConfigStr) {
        debugLog("setRemoteDefaultConfig: " + rcConfigStr);
        if (TextUtils.isEmpty(rcConfigStr)) {
            errorLog(ERROR_MESSAGE_DEFAULT_CONFIG_IS_EMPTY);
            return;
        }
        try {
            JSONArray defaultConfigJa = new JSONArray(rcConfigStr);
            System.out.println("defaultConfigJa:" + defaultConfigJa.toString());
            RemoteConfigManager.getInstance().setRemoteDefaultConfig(defaultConfigJa);
        } catch (Exception e) {


            errorLog("setRemoteDefaultConfig failed , see the details : " + e.toString());
        }
    }

    public static void setRemoteConfigEventProperties(String eventPropertiesJSONString) {
        if (TextUtils.isEmpty(eventPropertiesJSONString)) {
            debugLog(ERROR_MESSAGE_EVENT_PROPERTIES_IS_EMPTY);
            return;
        }
        debugLog("setRemoteConfigEventProperties eventPropertiesJSONString = " + eventPropertiesJSONString);
        try {
            JSONObject eventPropertiesJo = new JSONObject(eventPropertiesJSONString);
            RemoteConfigManager.getInstance().setRemoteConfigEventProperties(eventPropertiesJo);
        } catch (Exception e) {
            errorLog("setRemoteConfigEventProperties failed , see the details : " + e.toString());
        }

    }

    public static void setRemoteConfigUserProperties(String userPropertiesJSONString) {
        if (TextUtils.isEmpty(userPropertiesJSONString)) {
            debugLog(ERROR_MESSAGE_EVENT_PROPERTIES_IS_EMPTY);
            return;
        }
        debugLog("setRemoteConfigUserProperties userPropertiesJSONString = " + userPropertiesJSONString);
        try {
            JSONObject userPropertiesJo = new JSONObject(userPropertiesJSONString);
            RemoteConfigManager.getInstance().setRemoteConfigUserProperties(userPropertiesJo);
        } catch (Exception e) {
            errorLog("setRemoteConfigUserProperties failed , see the details : " + e.toString());
        }
    }


    public static String fastAllFetchRemoteConfig() {
        debugLog("fastAllFetchRemoteConfig");
        JSONObject value = RemoteConfigManager.getInstance().fastFetchRemoteConfig();
        debugLog(value.toString());
        return value == null ? "" : value.toString();
    }

    public static String fastFetchRemoteConfig(String key) {
        Object value = RemoteConfigManager.getInstance().fastFetchRemoteConfig(key);
        try {
            String result = String.valueOf(value);
            Log.e("fastFetchRemoteConfig", result);
            return result;
        } catch (Exception e) {
            return "";
        }
    }

    public static JSONObject fastFetchRemoteConfig1(String key) {

        debugLog("fastFetchRemoteConfig key = " + key);
        JSONObject out = new JSONObject();
        try {
            Object result = RemoteConfigManager.getInstance().fastFetchRemoteConfig(key);
            if (result == null) return out;
            if (result instanceof String) {
                out.put("type", 1);
                out.put("value", (String) result);
            } else if (result instanceof Integer || result instanceof Long) {
                out.put("type", 2);
                out.put("value", result);
            } else if (result instanceof Boolean) {
                out.put("type", 3);
                out.put("value", result);
            } else if (result instanceof JSONObject || result instanceof JSONArray) {
                out.put("type", 4);
                out.put("value", result);
            } else {
                out.put("type", 1);
                out.put("value", String.valueOf(result));
            }
        } catch (Throwable t) {
            Log.e(TAG, "fastFetchRemoteConfig error: " + t);
        }
        return out;
    }

    public static void asyncFetchRemoteConfig(String key) {

        if (TextUtils.isEmpty(key)) {
            errorLog(ERROR_MESSAGE_PARAMKEY_IS_EMPTY);

            return;
        }
        RemoteConfigManager.getInstance().asyncFetchRemoteConfig(key, new OnRemoteConfigReceivedData() {
            @Override
            public void onResult(Object value) {
                try {
                    String result = String.valueOf(value);
                    debugLog(result);
                    asyncFetchRemoteConfigCompleted(result);
                } catch (Exception e) {
                }
            }
        });
    }

    public static void asyncAllFetchRemoteConfig() {

        RemoteConfigManager.getInstance().asyncFetchRemoteConfig(new OnRemoteConfigReceivedGenericsData<JSONObject>() {
            @Override
            public void onResult(JSONObject jsonObject) {

                try {
                    String result = jsonObject.toString();
                    asyncAllFetchRemoteConfigCompleted(result);
                } catch (Exception e) {
                }
            }
        });
    }

    // 假设这是 Deeplink Info 对象
    static class MockDeeplinkInfo {
        public String sedpLink;
        public String turlId;
        public String from;
        public String baseURL;
        public String url;
        public JSONObject customParams;

        public MockDeeplinkInfo() {
            sedpLink = "sedplinkhome";         // 跳转参数
            turlId = "NrUNVva";                // 7位短链
            from = "links";                     // 来源
            baseURL = "https://tlink.solar-engine.com"; // 基础URL
            url = "https://tlink.solar-engine.com/receive/se?…"; // 完整 deeplink
            customParams = new JSONObject();
            try {
                customParams.put("key1", "value1");
                customParams.put("key2", "value2");
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }

    // Mock 成功回调
    public static void mockDeeplinkSuccess(int i) {
        MockDeeplinkInfo deeplinkInfo = new MockDeeplinkInfo();

        JSONObject data = new JSONObject();
        try {
            if (deeplinkInfo != null) {
                data.put("sedpLink", deeplinkInfo.sedpLink);
                data.put("turlId", deeplinkInfo.turlId);
                data.put("from", deeplinkInfo.from);
                data.put("baseUrl", deeplinkInfo.baseURL);
                data.put("url", deeplinkInfo.url);
                data.put("customParams", deeplinkInfo.customParams.toString());
            }
        } catch (JSONException e) {
            Log.e("MockDeeplink", "onReceived JSONException: " + e);
        }
        onDeepLinkCompleted(i, data);
        // 调用回调
    }


    // 假设 Deferred Deeplink Info 对象
    static class MockDeferredDeeplinkInfo {
        public String sedpLink;
        public String turlId;
        public String sedpUrlscheme;
        public String from;
        public String baseURL;
        public String url;
        public JSONObject customParams;

        public MockDeferredDeeplinkInfo() {
            sedpLink = "sedplinkhome";                 // 跳转参数
            turlId = "NrUNVva";                        // 7位短链
            sedpUrlscheme = "test1://app";             // 用户创建 deeplink 时填写
            from = "links";                             // 来源
            baseURL = "https://tlink.solar-engine.com";// 基础URL
            url = "https://tlink.solar-engine.com/receive/se?..."; // 完整 deeplink
            customParams = new JSONObject();
            try {
                customParams.put("key1", "value1");
                customParams.put("key2", "value2");
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }

    // Mock Deferred Deeplink 成功回调
    public static void mockDeferredDeeplinkSuccess(int code) {
        MockDeferredDeeplinkInfo deeplinkInfo = new MockDeferredDeeplinkInfo();

        JSONObject data = new JSONObject();
        try {
            if (deeplinkInfo != null) {
                data.put("sedpLink", deeplinkInfo.sedpLink);
                data.put("turlId", deeplinkInfo.turlId);
                data.put("sedpUrlscheme", deeplinkInfo.sedpUrlscheme);

            }
        } catch (JSONException e) {
            Log.e("MockDeferredDeeplink", "JSONException: " + e);
        }
        onDeferredDeeplinkCompleted(0, data);

        // code=0 表示成功
//        OnDeferredDeeplinkCompleted(code, data.toString());
    }

    public static void onInitCompleted(final int code) {
        // 取得当前的 CoronaActivity
        final CoronaActivity activity = CoronaEnvironment.getCoronaActivity();
        if (activity == null) {
            android.util.Log.w("SolarEngine", "CoronaActivity is null, cannot callback to Lua.");
            return;
        }

        // 在 Lua 主线程安全执行
        activity.getRuntimeTaskDispatcher().send(new CoronaRuntimeTask() {
            @Override
            public void executeUsing(CoronaRuntime runtime) {
                LuaState L = runtime.getLuaState();
                if (L == null) return;

                // 调用 Lua 中注册的回调函数
                L.getGlobal("onInitCompletedCallback");
                if (L.isFunction(-1)) {
                    L.pushInteger(code);
                    L.call(1, 0);
                } else {
                    L.pop(1);
                    Log.w("SolarEngine", "Lua callback 'onInitCompletedCallback' not found");
                }
            }
        });
    }

    public static void onAttribution(final int code, final String data) {
        // 获取当前的 CoronaActivity
        final CoronaActivity activity = CoronaEnvironment.getCoronaActivity();
        if (activity == null) {
            android.util.Log.w("SolarEngine", "CoronaActivity is null, cannot callback to Lua.");
            return;
        }
        // 在 Lua 主线程安全执行
        activity.getRuntimeTaskDispatcher().send(new CoronaRuntimeTask() {
            @Override
            public void executeUsing(CoronaRuntime runtime) {
                LuaState L = runtime.getLuaState();
                if (L == null) return;
                L.getGlobal("onAttributionCallback");
                if (L.isFunction(-1)) {
                    L.pushInteger(code);
                    L.pushString(data);
                    L.call(2, 0);
                } else {
                    L.pop(1);
                    Log.w("SolarEngine", "Lua callback 'onAttributionCallback' not found");
                }

            }
        });
    }


    public static void onDeepLinkCompleted(final int code, final JSONObject data) {
        CoronaEnvironment.getCoronaActivity().getRuntimeTaskDispatcher().send(new CoronaRuntimeTask() {
            @Override
            public void executeUsing(CoronaRuntime runtime) {
                LuaState L = runtime.getLuaState();
                if (L == null) return;

                // 获取 Lua 全局函数
                L.getGlobal("onDeepLinkCallback");

                if (L.isFunction(-1)) {
                    // 参数 1: code
                    L.pushInteger(code);

                    // 参数 2: JSONObject -> Lua table
                    if (data != null) {
                        pushJsonToLuaTable(L, data);
                    } else {
                        L.newTable();
                    }

                    // 调用 Lua 回调函数
                    L.call(2, 0);
                } else {
                    L.pop(1);
                }
            }
        });
    }

    public static void onDeferredDeeplinkCompleted(final int code, final JSONObject data) {
        CoronaEnvironment.getCoronaActivity().getRuntimeTaskDispatcher().send(new CoronaRuntimeTask() {
            @Override
            public void executeUsing(CoronaRuntime runtime) {
                LuaState L = runtime.getLuaState();
                if (L == null) return;

                // 找 Lua 全局函数
                L.getGlobal("onDeferredDeepLinkCallback");
                if (L.isFunction(-1)) {
                    // 参数1：code
                    L.pushInteger(code);

                    // 参数2：JSONObject 转 Lua table
                    if (data != null) {
                        pushJsonToLuaTable(L, data);
                    } else {
                        L.newTable(); // 空表兜底
                    }

                    // 调用 Lua 回调
                    L.call(2, 0);
                } else {
                    L.pop(1);
                }
            }
        });
    }

    private static void pushJsonToLuaTable(LuaState L, JSONObject json) {
        L.newTable();

        Iterator<String> keys = json.keys();
        while (keys.hasNext()) {
            String key = keys.next();
            Object value = json.opt(key);

            if (value instanceof JSONObject) {
                pushJsonToLuaTable(L, (JSONObject) value);
                L.setField(-2, key);
            } else {
                L.pushString(value != null ? value.toString() : "");
                L.setField(-2, key);
            }
        }
    }

    public static void asyncFetchRemoteConfigCompleted(final String data) {
        CoronaEnvironment.getCoronaActivity().getRuntimeTaskDispatcher().send(new CoronaRuntimeTask() {
            @Override
            public void executeUsing(CoronaRuntime runtime) {
                LuaState L = runtime.getLuaState();
                if (L == null) return;
                L.getGlobal("asyncFetchRemoteConfigCallBack");
                if (L.isFunction(-1)) {
                    L.pushString(data);
                    L.call(1, 0);
                } else {
                    L.pop(1);
                }
            }
        });
    }

    public static void asyncAllFetchRemoteConfigCompleted(final String data) {
        CoronaEnvironment.getCoronaActivity().getRuntimeTaskDispatcher().send(new CoronaRuntimeTask() {
            @Override
            public void executeUsing(CoronaRuntime runtime) {
                LuaState L = runtime.getLuaState();
                if (L == null) return;
                L.getGlobal("asyncAllFetchRemoteConfigCallBack");
                if (L.isFunction(-1)) {
                    L.pushString(data);
                    L.call(1, 0);
                } else {
                    L.pop(1);
                }
            }
        });


    }


}

