package com.iqi.responsys;

import android.content.BroadcastReceiver;
import android.os.Bundle;
import android.telecom.Call;
import android.util.Log;

import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableMapKeySetIterator;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.WritableNativeArray;
import com.facebook.react.bridge.WritableNativeMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.pushio.manager.PIOBadgeSyncListener;
import com.pushio.manager.PIOMCMessage;
import com.pushio.manager.PIOMCMessageError;
import com.pushio.manager.PIOMCMessageListener;
import com.pushio.manager.PIOMCRichContentListener;
import com.pushio.manager.PushIOManager;
import com.pushio.manager.PushIONotificationServiceType;
import com.pushio.manager.exception.PIOMCMessageException;
import com.pushio.manager.exception.PIOMCRichContentException;
import com.pushio.manager.exception.ValidationException;
import com.pushio.manager.preferences.PushIOPreference;
import com.pushio.manager.tasks.PushIOEngagementListener;
import com.pushio.manager.tasks.PushIOListener;
import com.pushio.manager.tasks.PushIONotificationServiceDiscoveryListener;

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

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.annotation.RegEx;

public class ResponsysModule extends ReactContextBaseJavaModule implements PIOMCMessageListener, PushIOListener,
        PushIOEngagementListener, PIOMCRichContentListener, PushIONotificationServiceDiscoveryListener{

    private final ReactApplicationContext reactContext;
    private static String TAG = "Responsys";
    private static Boolean isOn = false, isRegister = false;
    private static final String DURATION_SHORT_KEY = "SHORT";
    private static final String DURATION_LONG_KEY = "LONG";
    PushIOManager pushIOManager;
    private static boolean isLocation = true;
    private static String deviceId = "", userId = "";
    private List<Messages> allPreferences;
    private List<PIOMCMessage> piomcMessageList;
    private List<PushIOPreference> pushIOPreferences;
    Preferences preferences;
    PushIONotificationServiceType pushIONotificationServiceType;
    private BroadcastReceiver mBroadcastReceiver;

    public ResponsysModule(ReactApplicationContext reactContext) {
        super(reactContext);
        this.reactContext = reactContext;
    }

    @Override
    public String getName() {
        return TAG;
    }

    @ReactMethod
    public void sampleMethod(String stringArgument, int numberArgument, Callback callback) {
        // TODO: Implement some actually useful functionality
        callback.invoke("Received numberArgument: " + numberArgument + " stringArgument: " + stringArgument);
    }

    private PushIOManager getPushIOManager() {
        return PushIOManager.getInstance(getReactApplicationContext());
    }

    @ReactMethod
    public void trackEvent(String event) {
        getPushIOManager().trackEvent(event);
    }

    @ReactMethod
    public void initializeApp(){
        pushIOManager = PushIOManager.getInstance(getReactApplicationContext());
        pushIOManager.setInAppFetchEnabled(true);
        pushIOManager.isMessageCenterEnabled();
        pushIOManager.setMessageCenterEnabled(true);
        pushIOManager.registerPushIONotificationServiceDiscoveryListener(new PushIONotificationServiceDiscoveryListener() {
            @Override
            public void onNotificationServiceAvailable(String s) {
                Log.i(TAG, "onNotificationServiceAvailable Dalam : "+s);
            }

            @Override
            public void onNotificationServicesUnavailable(Bundle bundle) {
                Log.i(TAG, "onNotificationServicesUnavailable Dalam : "+bundle.toString());
            }
        });
        pushIOManager.registerPushIOListener(new PushIOListener() {
            @Override
            public void onPushIOSuccess() {
                Log.i(TAG, "onPushIOSuccess: ");
            }

            @Override
            public void onPushIOError(String s) {
                Log.e(TAG, "onPushIOError: "+s );
            }
        });
        pushIONotificationServiceType = new PushIONotificationServiceType();
        Log.i(TAG, "initializeApp: "+pushIONotificationServiceType.toString());
        pushIOManager.setNotificationsStacked(true);
        pushIOPreferences = pushIOManager.getPreferences();
        allPreferences = new ArrayList<>();
        piomcMessageList = new ArrayList<>();
        try {
            pushIOManager.fetchMessagesForMessageCenter(null, this);
//            pushIOManager.fetchMessagesForMessageCenter(null, new PIOMCMessageListener() {
//                @Override
//                public void onSuccess(String s, List<PIOMCMessage> list) {
//                    Log.i(TAG, "onSuccess dalem: "+s+", "+list.size()+", "+list);
//                }
//
//                @Override
//                public void onFailure(String s, PIOMCMessageError piomcMessageError) {
//                    Log.e(TAG, "onFailure: "+s+", "+piomcMessageError.getErrorMessage() );
//                }
//            });
        }catch (PIOMCMessageException e){
            Log.e(TAG, "onCreate: PIOMCMessageException --> "+e.getMessage() );
        }
        try
        {
            pushIOManager.declarePreference("NEWS", "News", PushIOPreference.Type.BOOLEAN);  // (key, label, preferenceType)
            pushIOManager.declarePreference("FAVORITE_TEAM", "Favorite Team", PushIOPreference.Type.STRING);
            pushIOManager.declarePreference("PRICE_LIMIT", "Price Limit", PushIOPreference.Type.NUMBER);
        }
        catch(ValidationException ex)
        {
            // Handle exception
        }
    }

    @ReactMethod
    public void declarePreference(String key, String isian, String type){
        try
        {
            if(type.equalsIgnoreCase("boolean"))
                pushIOManager.declarePreference(key, isian, PushIOPreference.Type.BOOLEAN);  // (key, label, preferenceType)
            if(type.equalsIgnoreCase("string"))
                pushIOManager.declarePreference(key, isian, PushIOPreference.Type.STRING);
            if(type.equalsIgnoreCase("number"))
                pushIOManager.declarePreference(key, isian, PushIOPreference.Type.NUMBER);
        }
        catch(ValidationException ex)
        {
            // Handle exception
        }
    }

    @ReactMethod
    public void setEngagement(String engagement){
        if(engagement.equalsIgnoreCase("in-app purchase"))
            pushIOManager.trackEngagement(PushIOManager.PUSHIO_ENGAGEMENT_METRIC_INAPP_PURCHASE);
        if(engagement.equalsIgnoreCase("premium content"))
            pushIOManager.trackEngagement(PushIOManager.PUSHIO_ENGAGEMENT_METRIC_PREMIUM_CONTENT);
        if(engagement.equalsIgnoreCase("social media"))
            pushIOManager.trackEngagement(PushIOManager.PUSHIO_ENGAGEMENT_METRIC_SOCIAL);
        if(engagement.equalsIgnoreCase("other"))
            pushIOManager.trackEngagement(PushIOManager.PUSHIO_ENGAGEMENT_METRIC_OTHER);
    }

    @ReactMethod
    public void getPreference(Callback successCallback){
        List<PushIOPreference> allPreferences = pushIOManager.getPreferences();
        WritableArray array = new WritableNativeArray();
        for(int i=0; i<allPreferences.size(); i++){
            preferences = new Preferences();
            preferences.setHasil((String) pushIOPreferences.get(i).getValue());
            preferences.setKey(pushIOPreferences.get(i).getKey());
            preferences.setLabel(pushIOPreferences.get(i).getLabel());
            preferences.setTipe(pushIOPreferences.get(i).getType().toString());

        }
        Log.i(TAG, "getPreference: "+pushIOPreferences.get(0));
        successCallback.invoke(null, "test");
    }

    @ReactMethod
    public void getPreference(String kunci, Callback successCallback){
        Log.i(TAG, "getPreference: "+pushIOManager.getPreference(kunci));
        successCallback.invoke(null, pushIOManager.getPreference(kunci));
    }

    @ReactMethod
    public void getPreferences(Callback callback){
        Log.i(TAG, "getPreference: ");
        Gson g = new GsonBuilder().serializeNulls().create();
        WritableArray array = new WritableNativeArray();
        List<PushIOPreference> allPreferences = pushIOManager.getPreferences();
        for (PushIOPreference co : allPreferences) {
            try {
                JSONObject jo = new JSONObject(g.toJson(co));
                WritableMap wm = null;
                wm = convertJsonToMap(jo);
                array.pushMap(wm);
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        Log.i(TAG, "getPreference: "+array);
        callback.invoke(null, array);
    }

    @ReactMethod
    public void setPreference(String Item, String isi, String type){
        try {
            if(type.equalsIgnoreCase("boolean")) {
                Boolean xx;
                if(isi.equalsIgnoreCase("true"))
                    xx = true;
                else
                    xx = false;
                pushIOManager.setPreference(Item, xx);
            }
            if(type.equalsIgnoreCase("string")) {
                pushIOManager.setPreference(Item, isi);
            }
            if(type.equalsIgnoreCase("number")) {
                Float aDouble = Float.parseFloat(isi);
                pushIOManager.setPreference(Item, aDouble);
            }
//            PushIOPreference newsPreference = pushIOManager.getPreference(Item);
//            Log.i(TAG, "onClick: newsPreference --> "+newsPreference.getKey()+", "+newsPreference.getLabel()+"" +
//                    ", "+newsPreference.getType()+", "+newsPreference.getValue());
        }catch (ValidationException e){
            Log.e(TAG, "setPreference error : "+e.getMessage() );
        }
    }

    @ReactMethod
    public void getStatus(Callback successCallback) {
        successCallback.invoke(null, isRegister);
    }

    private WritableMap convertJsonToMap(JSONObject jsonObject) throws JSONException {
        WritableMap map = new WritableNativeMap();

        Iterator<String> iterator = jsonObject.keys();
        while (iterator.hasNext()) {
            String key = iterator.next();
            Object value = jsonObject.get(key);
            Log.i(TAG, "convertJsonToMap: "+key+" --> "+value);
            if (value instanceof JSONObject) {
                map.putMap(key, convertJsonToMap((JSONObject) value));
            } else if (value instanceof JSONArray) {
                map.putArray(key, convertJsonToArray((JSONArray) value));
                if(("option_values").equals(key)) {
                    map.putArray("options", convertJsonToArray((JSONArray) value));
                }
            } else if (value instanceof Boolean) {
                map.putBoolean(key, (Boolean) value);
            } else if (value instanceof Integer) {
                map.putInt(key, (Integer) value);
            } else if (value instanceof Double) {
                map.putDouble(key, (Double) value);
            } else if (value instanceof String)  {
                map.putString(key, (String) value);
            } else {
                map.putString(key, value.toString());
            }
        }
        return map;
    }

    private WritableArray convertJsonToArray(JSONArray jsonArray) throws JSONException {
        WritableArray array = new WritableNativeArray();

        for (int i = 0; i < jsonArray.length(); i++) {
            Object value = jsonArray.get(i);
            if (value instanceof JSONObject) {
                array.pushMap(convertJsonToMap((JSONObject) value));
            } else if (value instanceof JSONArray) {
                array.pushArray(convertJsonToArray((JSONArray) value));
            } else if (value instanceof Boolean) {
                array.pushBoolean((Boolean) value);
            } else if (value instanceof Integer) {
                array.pushInt((Integer) value);
            } else if (value instanceof Double) {
                array.pushDouble((Double) value);
            } else if (value instanceof String)  {
                array.pushString((String) value);
            } else {
                array.pushString(value.toString());
            }
        }
        return array;
    }

    private JSONObject convertMapToJson(ReadableMap readableMap) throws JSONException {
        JSONObject object = new JSONObject();
        ReadableMapKeySetIterator iterator = readableMap.keySetIterator();
        while (iterator.hasNextKey()) {
            String key = iterator.nextKey();
            switch (readableMap.getType(key)) {
                case Null:
                    object.put(key, JSONObject.NULL);
                    break;
                case Boolean:
                    object.put(key, readableMap.getBoolean(key));
                    break;
                case Number:
                    object.put(key, readableMap.getDouble(key));
                    break;
                case String:
                    object.put(key, readableMap.getString(key));
                    break;
                case Map:
                    object.put(key, convertMapToJson(readableMap.getMap(key)));
                    break;
                case Array:
                    object.put(key, convertArrayToJson(readableMap.getArray(key)));
                    break;
            }
        }
        return object;
    }

    private JSONArray convertArrayToJson(ReadableArray readableArray) throws JSONException {

        JSONArray array = new JSONArray();

        for (int i = 0; i < readableArray.size(); i++) {
            switch (readableArray.getType(i)) {
                case Null:
                    break;
                case Boolean:
                    array.put(readableArray.getBoolean(i));
                    break;
                case Number:
                    array.put(readableArray.getDouble(i));
                    break;
                case String:
                    array.put(readableArray.getString(i));
                    break;
                case Map:
                    array.put(convertMapToJson(readableArray.getMap(i)));
                    break;
                case Array:
                    array.put(convertArrayToJson(readableArray.getArray(i)));
                    break;
            }
        }
        return array;
    }

    @ReactMethod
    public void setMessageCenterEnabled(boolean xx){
        try{
            pushIOManager.setMessageCenterEnabled(xx);
        }catch (Exception e){
            Log.e(TAG, "setMessageCenterEnabled: "+e.getMessage() );
        }
    }

    @ReactMethod
    public void setChannel(String isian){
        try{
            if(isian.equalsIgnoreCase("i")) {
                pushIOManager.registerPushIONotificationServiceDiscoveryListener(new PushIONotificationServiceDiscoveryListener() {
                    @Override
                    public void onNotificationServiceAvailable(String s) {
                        Log.i(TAG, "onNotificationServiceAvailable: "+s);
                    }

                    @Override
                    public void onNotificationServicesUnavailable(Bundle bundle) {
                        Log.e(TAG, "onNotificationServicesUnavailable: "+bundle.toString() );
                    }
                });
                pushIOManager.setRIAppId(isian);
                pushIOManager.setNotificationsStacked(false);
                Log.i(TAG, "setChannel: "+pushIOManager.getNotificationStacked());
            }
            else {
//                if(!isian.equalsIgnoreCase("o"))
                pushIOManager.setNotificationsStacked(true);
                Log.i(TAG, "setChannel: "+pushIOManager.getNotificationStacked());
                pushIOManager.setRIAppId(isian);
                Log.i(TAG, "setChannel: " + pushIOManager.getRIAppId());
            }
        }catch (Exception e){
            Log.e(TAG, "setChannel: "+e.getMessage() );
        }
    }

    @ReactMethod
    public void getBadgeCount(Callback callback){
        try{
            callback.invoke(null, pushIOManager.getBadgeCount());
        }catch (Exception e){
            callback.invoke(e.getMessage(), 0);
        }
    }

    @ReactMethod
    public void resetBadgeCount(boolean b, final Callback successCallback, final Callback errorCallback){
        try{
            pushIOManager.resetBadgeCount(b, new PIOBadgeSyncListener(){

                @Override
                public void onBadgeSyncedSuccess(String s) {
                    successCallback.invoke(null, s);
                }

                @Override
                public void onBadgeSyncedFailure(String s) {
                    errorCallback.invoke(null, s);
                }
            });
        }catch (Exception e){

        }
    }

    @ReactMethod
    public void setBadgeCount(int badgeCount, boolean b){
        try{
            pushIOManager.setBadgeCount(badgeCount, b, new PIOBadgeSyncListener(){

                @Override
                public void onBadgeSyncedSuccess(String s) {

                }

                @Override
                public void onBadgeSyncedFailure(String s) {

                }
            });
        }catch (Exception e){

        }
    }

    @ReactMethod
    public void setMessageCenterBadgingEnabled(boolean messageCenterBadgingEnabled){
        try{
            pushIOManager.setMessageCenterBadgingEnabled(messageCenterBadgingEnabled);
        }catch (Exception e){

        }
    }

    @ReactMethod
    public void fetchRichContentForMessage(String messageId, final Callback successCallback){
        try {
            pushIOManager.fetchRichContentForMessage
                    (messageId, new PIOMCRichContentListener() {
                        @Override
                        public void onSuccess(String messageId, String richContentHtml) {
                            successCallback.invoke(null, richContentHtml);
                        }

                        @Override
                        public void onFailure(String messageId, PIOMCMessageError piomcMessageError) {
                            successCallback.invoke(null, piomcMessageError);
                        }
                    });
        } catch (PIOMCRichContentException e) {
            e.printStackTrace();
        }
    }

    @ReactMethod
    public void fetchMessagesForMessageCenter(String msgCenter, final Callback successCallback){
        // successCallback.invoke(null, allPreferences);
//        List<PIOMCMessage> allPreferences = pushIOManager.get
        try {
//            pushIOManager.fetchMessagesForMessageCenter(null, this);
            pushIOManager.isMessageCenterEnabled();
            pushIOManager.setMessageCenterEnabled(true);
            pushIOManager.fetchMessagesForMessageCenter(msgCenter, new PIOMCMessageListener() {
                @Override
                public void onSuccess(String s, List<PIOMCMessage> list) {
                    Log.i(TAG, "onSuccess dalem: "+s+", "+list.size()+", "+list);
                    piomcMessageList = list;
                    Gson g = new GsonBuilder().serializeNulls().create();
                    WritableArray array = new WritableNativeArray();

                    for(int i=0;i<list.size();i++){
                        Messages messages = new Messages();
                        messages.setDeeplinkUrl(list.get(i).getDeeplinkUrl());
                        messages.setExpiryTimestamp(list.get(i).getExpiryTimestamp());
                        messages.setIconUrl(list.get(i).getIconUrl());
                        messages.setId(list.get(i).getId());
                        messages.setMessage(list.get(i).getMessage());
                        messages.setMessageCenterName(list.get(i).getMessageCenterName());
                        messages.setRichMessageHtml(list.get(i).getRichMessageHtml());
                        messages.setRichMessageUrl(list.get(i).getRichMessageUrl());
                        messages.setSentTimestamp(list.get(i).getSentTimestamp());
                        messages.setSubject(list.get(i).getSubject());
                        for(Messages messages1 : allPreferences){
                            if(messages1.getId() != list.get(i).getId()){
                                allPreferences.add(messages);
                            }
                        }
                    }
                    for (PIOMCMessage co : piomcMessageList) {
                        Log.i(TAG, "onSuccess: "+co.getDeeplinkUrl());
                        Log.i(TAG, "onSuccess: "+co.getIconUrl());
                        Log.i(TAG, "onSuccess: "+co.getId());
                        Log.i(TAG, "onSuccess: "+co.getMessage());
                        Log.i(TAG, "onSuccess: "+co.getMessageCenterName());
                        Log.i(TAG, "onSuccess: "+co.getRichMessageUrl());
                        Log.i(TAG, "onSuccess: "+co.getSubject());
                        Log.i(TAG, "onSuccess: "+co.getRichMessageHtml());
                        Log.i(TAG, "onSuccess: "+co.getExpiryTimestamp());
                        Log.i(TAG, "onSuccess: "+co.getSentTimestamp());
                        try {
                            JSONObject jo = new JSONObject(g.toJson(co));
                            WritableMap wm = null;
                            wm = convertJsonToMap(jo);
                            array.pushMap(wm);
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                    Log.i(TAG, "getPesan: "+array);
                    successCallback.invoke(null, array);
                }

                @Override
                public void onFailure(String s, PIOMCMessageError piomcMessageError) {
                    Log.e(TAG, "onFailure: "+s+", "+piomcMessageError.getErrorMessage() );
                    successCallback.invoke(null, piomcMessageError.getErrorMessage());
                }
            });
        }catch (PIOMCMessageException e){
            Log.e(TAG, "onCreate: PIOMCMessageException --> "+e.getMessage() );
        }
    }

    @ReactMethod
    public void getDeviceId(Callback successCallback) {
        deviceId = pushIOManager.getDeviceId();
        successCallback.invoke(null, deviceId);
    }

    @ReactMethod
    public void getRegisteredCategories(Callback callback){
        try{
            Gson g = new GsonBuilder().serializeNulls().create();
            WritableArray array = new WritableNativeArray();
            List<String> strings = pushIOManager.getRegisteredCategories();
            for (String co : strings) {
                try {
                    JSONObject jo = new JSONObject(g.toJson(co));
                    WritableMap wm = null;
                    wm = convertJsonToMap(jo);
                    array.pushMap(wm);
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
            Log.i(TAG, "getPreference: "+array);
            callback.invoke(null, array);
        }catch (Exception e){

        }
    }

    @ReactMethod
    public void getUserId(Callback successCallback) {
        successCallback.invoke(null, userId);
    }

    @ReactMethod
    public void setLogLevel(String logLevel){
        if(logLevel.equalsIgnoreCase("info"))
            pushIOManager.setLogLevel(Log.INFO);
        if(logLevel.equalsIgnoreCase("verbose"))
            pushIOManager.setLogLevel(Log.VERBOSE);
        if(logLevel.equalsIgnoreCase("debug"))
            pushIOManager.setLogLevel(Log.DEBUG);
        if(logLevel.equalsIgnoreCase("error"))
            pushIOManager.setLogLevel(Log.ERROR);
        if(logLevel.equalsIgnoreCase("warn"))
            pushIOManager.setLogLevel(Log.WARN);
        if(logLevel.equalsIgnoreCase("assert"))
            pushIOManager.setLogLevel(Log.ASSERT);
    }


    @ReactMethod
    public void registerApp(){
        pushIOManager = PushIOManager.getInstance(getReactApplicationContext());
        pushIOManager.setInAppFetchEnabled(true);
        pushIOManager.isMessageCenterEnabled();
        pushIOManager.setMessageCenterEnabled(true);
        pushIOManager.registerPushIONotificationServiceDiscoveryListener(new PushIONotificationServiceDiscoveryListener() {
            @Override
            public void onNotificationServiceAvailable(String s) {
                Log.i(TAG, "onNotificationServiceAvailable Dalam : "+s);
            }

            @Override
            public void onNotificationServicesUnavailable(Bundle bundle) {
                Log.i(TAG, "onNotificationServicesUnavailable Dalam : "+bundle.toString());
            }
        });
        pushIOManager.registerPushIOListener(new PushIOListener() {
            @Override
            public void onPushIOSuccess() {
                Log.i(TAG, "onPushIOSuccess: ");
            }

            @Override
            public void onPushIOError(String s) {
                Log.e(TAG, "onPushIOError: "+s );
            }
        });
        pushIONotificationServiceType = new PushIONotificationServiceType();
        Log.i(TAG, "initializeApp: "+pushIONotificationServiceType.toString());
        pushIOManager.setNotificationsStacked(true);
        pushIOPreferences = pushIOManager.getPreferences();
        allPreferences = new ArrayList<>();
        piomcMessageList = new ArrayList<>();
        try {
            pushIOManager.fetchMessagesForMessageCenter(null, this);
//            pushIOManager.fetchMessagesForMessageCenter(null, new PIOMCMessageListener() {
//                @Override
//                public void onSuccess(String s, List<PIOMCMessage> list) {
//                    Log.i(TAG, "onSuccess dalem: "+s+", "+list.size()+", "+list);
//                }
//
//                @Override
//                public void onFailure(String s, PIOMCMessageError piomcMessageError) {
//                    Log.e(TAG, "onFailure: "+s+", "+piomcMessageError.getErrorMessage() );
//                }
//            });
        }catch (PIOMCMessageException e){
            Log.e(TAG, "onCreate: PIOMCMessageException --> "+e.getMessage() );
        }
        try
        {
            pushIOManager.declarePreference("NEWS", "News", PushIOPreference.Type.BOOLEAN);  // (key, label, preferenceType)
            pushIOManager.declarePreference("FAVORITE_TEAM", "Favorite Team", PushIOPreference.Type.STRING);
            pushIOManager.declarePreference("PRICE_LIMIT", "Price Limit", PushIOPreference.Type.NUMBER);
        }
        catch(ValidationException ex)
        {
            // Handle exception
        }
        pushIOManager.registerApp(isLocation);
        deviceId = pushIOManager.getDeviceId();
    }

    @ReactMethod
    public void registerUserId(String userId){
        pushIOManager.registerUserId(userId);
        isRegister = true;
    }

    @ReactMethod
    public void getRegisteredUserId(Callback successCallback) {
        userId = pushIOManager.getRegisteredUserId();
        successCallback.invoke(null, userId);
    }

    @ReactMethod
    public void unregisterUserId(){
        pushIOManager.unregisterUserId();
        isRegister = false;
    }

    @Override
    public void onSuccess(String s, List<PIOMCMessage> list) {
        Log.i(TAG, "onSuccess: "+s +"-->"+ list);
        piomcMessageList = list;
        emitDeviceEvent("messageListener", ""+list);
    }

    @Override
    public void onSuccess(String s, String s1) {
        Log.i(TAG, "onSuccess: "+s +"-->"+ s1);
    }

    @Override
    public void onFailure(String s, PIOMCMessageError piomcMessageError) {
        Log.e(TAG, "onFailure: "+ s +" --> "+ piomcMessageError );
    }

    private void emitDeviceEvent(String eventName, String message) {
      Log.i("GET", "GET " + message);
      // A method for emitting from the native side to JS
      // https://facebook.github.io/react-native/docs/native-modules-android.html#sending-events-to-javascript
      reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(eventName, message);
    }

    @Override
    public void onPushIOSuccess() {
        Log.i(TAG, "onPushIOSuccess: ");
    }

    @Override
    public void onPushIOError(String s) {
        Log.e(TAG, "onPushIOError: "+s );
    }

    @Override
    public void onEngagementSuccess() {

    }

    @Override
    public void onEngagementError(String s) {

    }

    @Override
    public void onNotificationServiceAvailable(String s) {
        Log.i(TAG, "onNotificationServiceAvailable: "+s);
    }

    @Override
    public void onNotificationServicesUnavailable(Bundle bundle) {
        Log.i(TAG, "onNotificationServicesUnavailable: "+bundle.toString());
    }
}
