package plugin.library;

import android.util.Log;

import com.naef.jnlua.LuaState;
import com.naef.jnlua.JavaFunction;

public class SELuaLoader implements JavaFunction {

    private final static String TAG = "SE.CoronaAndroidSDK";

    @Override
    public int invoke(LuaState L) {
        // 创建 Lua 表（返回给 require 的模块表）
        L.newTable();

        // 注册函数
        registerFunction(L, "preinit", (lua) -> {
            try {
                String appKey = lua.checkString(1);
                SEPluginProxy.preInitSdk(appKey);
            } catch (Exception e) {
                Log.e(TAG, "Error in preinit", e);


            }
            return 0;
        });


        registerFunction(L, "initSdk", (lua) -> {
            try {
                String config = lua.checkString(1);
                String properties = lua.checkString(2);


                SEPluginProxy.initialize(config, properties);
            } catch (Exception e) {
                Log.e(TAG, "Error in initSdk", e);

            }
            return 0;
        });

        registerFunction(L, "setInitCompletedCallback", (lua) -> {
            try {
                if (lua.isFunction(1)) {
                    lua.pushValue(1);
                    lua.setGlobal("onInitCompletedCallback");
                }
            } catch (Exception e) {
                Log.e(TAG, "Error in setInitCompletedCallback", e);
            }

            return 0;
        });
        registerFunction(L, "setAttributionCallback", (lua) -> {
            try {
                if (lua.isFunction(1)) {
                    lua.pushValue(1);
                    lua.setGlobal("onAttributionCallback");
                }
            } catch (Exception e) {
                Log.e(TAG, "Error in setAttributionCallback", e);
            }

            return 0;
        });
        registerFunction(L, "setDeepLinkCallback", (lua) -> {
            try {
                if (lua.isFunction(1)) {
                    lua.pushValue(1);
                    lua.setGlobal("onDeepLinkCallback");
                }
            } catch (Exception e) {
                Log.e(TAG, "Error in setDeepLinkCallback", e);
            }

            return 0;
        });
        registerFunction(L, "setDeferredDeepLinkCallback", (lua) -> {
        try { if (lua.isFunction(1)) {
                             lua.pushValue(1);
                             lua.setGlobal("onDeferredDeepLinkCallback");
                         } }
        catch (Exception e) {
            Log.e(TAG, "Error in setDeferredDeepLinkCallback", e);
        }
           
            return 0;
        });
        registerFunction(L, "requestTrackingAuthorization", (lua) -> {

            Log.d(TAG, "requestTrackingAuthorization not support android");

            return 0;

        });

        registerFunction(L, "setVisitorId", (lua) -> {
            try {
                String visitorID = lua.checkString(1);
                SEPluginProxy.setVisitorID(visitorID);
            } catch (Exception e) {
            Log.e(TAG, "Error in setVisitorId", e)
            }
            return 0;
        });
        registerFunction(L, "getVisitorId", (lua) -> {
            try {
                String visitorID = SEPluginProxy.getVisitorID();
                L.pushString(visitorID);
            } catch (Exception e) {
            Log.e(TAG, "Error in getVisitorId", e)
                L.pushString("");
            }
            return 1;

        });
        registerFunction(L, "getDistinctId", (lua) -> {
            try {
                String distinctId = SEPluginProxy.getDistinctId();
                Log.e("getDistinctId", distinctId);
                L.pushString(distinctId);
            } catch (Exception e) {
            Log.e(TAG, "Error in getDistinctId", e)
                L.pushString("");
            }
            return 1;
        });
        registerFunction(L, "getAccountId", (lua) -> {
            try {
                String accountId = SEPluginProxy.getAccountId();
                L.pushString(accountId);
            } catch (Exception e) {
            Log.e(TAG, "Error in getAccountId", e)
                L.pushString("");
            }
            return 1;
        });


        registerFunction(L, "login", (lua) -> {
            try {
                String accountId = lua.checkString(1);
                SEPluginProxy.login(accountId);

            } catch (Exception e) {
            Log.e(TAG, "Error in getDistinctId", e)
            }
            return 0;
        });
        registerFunction(L, "logout", (lua) -> {
            try {
                SEPluginProxy.logout();
            } catch (Exception e) {
            Log.e(TAG, "Error in logout", e)
            }
            return 0;
        });
        registerFunction(L, "userInit", (lua) -> {
            try {
                String json = lua.checkString(1);
                SEPluginProxy.userInit(json);
            } catch (Exception e) {
            Log.e(TAG, "Error in userInit", e);
            }
            return 0;
        });


        registerFunction(L, "userUnset", (lua) -> {
            try {
                String keysJson;

                if (lua.isTable(1)) {
                    // 将 Lua 表转换成 JSON 数组字符串
                    org.json.JSONArray jsonArray = new org.json.JSONArray();
                    lua.pushNil();
                    while (lua.next(1)) {
                        String value = lua.toString(-1);
                        jsonArray.put(value);
                        lua.pop(1);
                    }
                    keysJson = jsonArray.toString();
                } else {
                    keysJson = lua.checkString(1);
                }

                SEPluginProxy.userUnset(keysJson);
            } catch (Exception e) {
            Log.e(TAG, "Error in userUnset", e);
            }
            return 0;
        });
        registerFunction(L, "userAppend", (lua) -> {
            try {
                String json = lua.checkString(1);
                SEPluginProxy.userAppend(json);
            } catch (Exception e) {
            Log.e(TAG, "Error in userAppend", e);
            }
            return 0;
        });
        registerFunction(L, "userAdd", (lua) -> {
            try {
                String json = lua.checkString(1);
                SEPluginProxy.userAdd(json);
            } catch (Exception e) {
            Log.e(TAG, "Error in userAdd", e);
            }
            return 0;
        });
        registerFunction(L, "userUpdate", (lua) -> {
            try {
                String json = lua.checkString(1);
                SEPluginProxy.userUpdate(json);
            } catch (Exception e) {
            Log.e(TAG, "Error in userUpdate", e);
            }
            return 0;
        });
        registerFunction(L, "userDelete", (lua) -> {
            try {
                int type = lua.checkInteger(1);
                SEPluginProxy.userDelete(type);
            } catch (Exception e) {
            Log.e(TAG, "Error in userDelete", e);
            }
            return 0;
        });
        registerFunction(L, "setPresetEvent", (lua) -> {
            try {
                int type = lua.checkInteger(1);
                String json = lua.checkString(2);
                SEPluginProxy.setPresetEvent(type, json);
            } catch (Exception e) {
            Log.e(TAG, "Error in setPresetEvent", e);
            }
            return 0;
        });
        registerFunction(L, "setSuperProperties", (lua) -> {
            try {
                String json = lua.checkString(1);
                SEPluginProxy.setSuperProperties(json);
            } catch (Exception e) {
            Log.e(TAG, "Error in setSuperProperties", e);
            }
            return 0;
        });
        registerFunction(L, "clearSuperProperties", (lua) -> {
            try {
                SEPluginProxy.clearSuperProperties();
            } catch (Exception e) {
            Log.e(TAG, "Error in clearSuperProperties", e);
            }
            return 0;
        });
        registerFunction(L, "unsetSuperProperty", (lua) -> {
            try {
                String key = lua.checkString(1);
                SEPluginProxy.unsetSuperProperty(key);
            } catch (Exception e) {
            Log.e(TAG, "Error in unsetSuperProperty", e);
            }
            return 0;
        });
        registerFunction(L, "getPresetProperties", (lua) -> {
            try {
                String json = SEPluginProxy.getPresetProperties();
                L.pushString(json);
            } catch (Exception e) {
            Log.e(TAG, "Error in getPresetProperties", e)
                L.pushString("");
            }
            return 1;
        });


        registerFunction(L, "setChannel", (lua) -> {
            try {
                String channel = lua.checkString(1);
                SEPluginProxy.setChannel(channel);
            } catch (Exception e) {
            Log.e(TAG, "Error in setChannel", e)
            }
            return 0;
        });
        registerFunction(L, "reportEventImmediately", (lua) -> {
            try {
                SEPluginProxy.reportEventImmediately();
            } catch (Exception e) {
            Log.e(TAG, "Error in reportEventImmediately", e)
            }
            return 0;
        });

        registerFunction(L, "setOaid", (lua) -> {
            try {
                String oaid = lua.checkString(1);
                SEPluginProxy.setOaid(oaid);
            } catch (Exception e) {
            Log.e(TAG, "Error in setOaid", e)
            }
            return 0;
        });

        registerFunction(L, "setGDPRArea", (lua) -> {
            try {
                boolean gdpr = lua.checkBoolean(1);
                SEPluginProxy.setGDPRArea(gdpr);
            } catch (Exception e) {
            Log.e(TAG, "Error in setGDPRArea", e)
            }
            return 0;
        });
        registerFunction(L, "setGaid", (lua) -> {
            try {
                String gaid = lua.checkString(1);
                SEPluginProxy.setGaid(gaid);
            } catch (Exception e) {
            Log.e(TAG, "Error in setGaid", e)
            }
            return 0;
        });

        registerFunction(L, "trackAdImpression", (lua) -> {
            try {
                String json = lua.checkString(1);
                SEPluginProxy.trackAdImpression(json);
            } catch (Exception e) {
            Log.e(TAG, "Error in trackAdImpression", e)
            }
            return 0;
        });

        registerFunction(L, "trackPurchase", (lua) -> {
            try {
                String json = lua.checkString(1);
                SEPluginProxy.trackPurchase(json);
            } catch (Exception e) {
            Log.e(TAG, "Error in trackPurchase", e)
            }
            return 0;
        });
        registerFunction(L, "trackAdClick", (lua) -> {
            try {
                String json = lua.checkString(1);
                SEPluginProxy.trackAdClick(json);
            } catch (Exception e) {
            Log.e(TAG, "Error in trackAdClick", e)
            }
            return 0;
        });
        registerFunction(L, "trackRegister", (lua) -> {
            try {
                String json = lua.checkString(1);
                SEPluginProxy.trackRegister(json);
            } catch (Exception e) {
            Log.e(TAG, "Error in trackRegister", e)
            }
            return 0;
        });
        registerFunction(L, "trackLogin", (lua) -> {
            try {
                String json = lua.checkString(1);
                SEPluginProxy.trackLogin(json);
            } catch (Exception e) {
            Log.e(TAG, "Error in trackLogin", e)
            }
            return 0;
        });
        registerFunction(L, "trackOrder", (lua) -> {
            try {
                String json = lua.checkString(1);
                SEPluginProxy.trackOrder(json);
            } catch (Exception e) {
            Log.e(TAG, "Error in trackOrder", e)
            }
            return 0;
        });
        registerFunction(L, "trackAttribution", (lua) -> {
            try {
                String json = lua.checkString(1);
                SEPluginProxy.trackAppAttr(json);
            } catch (Exception e) {
            Log.e(TAG, "Error in trackAttribution", e)
            }
            return 0;
        });
        registerFunction(L, "eventStart", (lua) -> {
            try {
                String name = lua.checkString(1);
                SEPluginProxy.eventStart(name);
            } catch (Exception e) {
            Log.e(TAG, "Error in eventStart", e)
            }
            return 0;
        });
        registerFunction(L, "eventFinish", (lua) -> {
            try {
                String name = lua.checkString(1);
                String json = lua.checkString(2);
                SEPluginProxy.eventFinish(name, json);
            } catch (Exception e) {
            Log.e(TAG, "Error in eventFinish", e)
            }
            return 0;
        });
        registerFunction(L, "trackAppReEngagement", (lua) -> {
            try {
                String json = lua.checkString(1);
                SEPluginProxy.trackAppReEngagement(json);
            } catch (Exception e) {
            Log.e(TAG, "Error in trackAppReEngagement", e)
            }
            return 0;
        });
        registerFunction(L, "track", (lua) -> {
            try {
                // 第一个参数：事件名
                String eventName = lua.checkString(1);

                // 第二个参数：JSON字符串
                String json = null;
                if (!lua.isNoneOrNil(2)) {
                    json = lua.checkString(2);
                }

                // 第三个参数：可选字段（可能是附加数据）
                String extra = null;
                if (!lua.isNoneOrNil(3)) {
                    extra = lua.checkString(3);
                }

                SEPluginProxy.trackEvent(eventName, json, extra);

            } catch (Exception e) {
            Log.e(TAG, "Error in track", e)
            }

            return 0;
        });

        registerFunction(L, "trackFirstEvent", (lua) -> {
            try {
                String eventName = lua.checkString(1);
                String firstCheckId = lua.checkString(2);
                String json = lua.checkString(3);
                SEPluginProxy.trackFirst(eventName, firstCheckId, json);
            } catch (Exception e) {
            Log.e(TAG, "Error in trackFirstEvent", e)

            }
            return 0;
        });

        registerFunction(L, "getAttributionData", (lua) -> {
            try {
                String attributionData = SEPluginProxy.getAttributionData();
                L.pushString(attributionData);

            } catch (Exception e) {
            Log.e(TAG, "Error in getAttributionData", e)
                L.pushString("");
            }
            return 1;

        });


        registerFunction(L, "setRemoteDefaultConfig", (lua) -> {
            try {
                String json = lua.checkString(1);
                SEPluginProxy.setRemoteDefaultConfig(json);
            } catch (Exception e) {
            Log.e(TAG, "Error in setRemoteDefaultConfig", e)
            }
            return 0;
        });
        registerFunction(L, "fastFetchRemoteConfig", (lua) -> {
            try {
                String key = lua.checkString(1);
                String value = SEPluginProxy.fastFetchRemoteConfig(key);
                L.pushString(value);
            } catch (Exception e) {
            Log.e(TAG, "Error in fastFetchRemoteConfig", e)

            }
            return 1;
        });
        registerFunction(L, "setRemoteConfigEventProperties", (lua) -> {
            try {
                String json = lua.checkString(1);
                SEPluginProxy.setRemoteConfigEventProperties(json);
            } catch (Exception e) {
            Log.e(TAG, "Error in setRemoteConfigEventProperties", e)
            
            }
            return 0;
        });
        registerFunction(L, "setRemoteConfigUserProperties", (lua) -> {
            try {
                String json = lua.checkString(1);
                SEPluginProxy.setRemoteConfigUserProperties(json);
            } catch (Exception e) {
            Log.e(TAG, "Error in setRemoteConfigUserProperties", e)
            }
            return 0;
        });


        registerFunction(L, "fastAllFetchRemoteConfig", (lua) -> {
            try {
                String result = SEPluginProxy.fastAllFetchRemoteConfig();
                lua.pushString(result);

            } catch (Exception e) {
            Log.e(TAG, "Error in fastAllFetchRemoteConfig", e)
                lua.pushString("");
            }
            return 1;
        });
        registerFunction(L, "asyncFetchRemoteConfig", (lua) -> {
            try {
                String key = lua.checkString(1);
                if (lua.isFunction(2)) {
                    lua.pushValue(2);
                    lua.setGlobal("asyncFetchRemoteConfigCallBack");
                }
                SEPluginProxy.asyncFetchRemoteConfig(key);
            } catch (Exception e) {
            Log.e(TAG, "Error in asyncFetchRemoteConfig", e)
            
            }
            return 0;
        });

        registerFunction(L, "asyncAllFetchRemoteConfig", (lua) -> {

            try {
                if (lua.isFunction(1)) {
                    lua.pushValue(1);
                    lua.setGlobal("asyncAllFetchRemoteConfigCallBack");
                }
                SEPluginProxy.asyncAllFetchRemoteConfig();

            } catch (Exception e) {
            Log.e(TAG, "Error in asyncAllFetchRemoteConfig", e)
            }
            return 0;

        });

// 返回 table
        return 1;
    }


    private void registerFunction(LuaState L, String name, JavaFunction func) {
        L.pushString(name);
        L.pushJavaFunction(func);
        L.setTable(-3);
    }
}