package com.b8ne.RNPusherPushNotifications;

import android.util.Log;
import java.util.Map;
import org.json.JSONObject;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.WritableNativeMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.google.firebase.messaging.RemoteMessage;
import com.pusher.android.PusherAndroid;
import com.facebook.react.bridge.ReactApplicationContext;
import com.pusher.android.notifications.PushNotificationRegistration;
import com.pusher.android.notifications.fcm.FCMPushNotificationReceivedListener;
import com.pusher.android.notifications.interests.InterestSubscriptionChangeListener;
import com.pusher.android.notifications.tokens.PushNotificationRegistrationListener;

/**
 * Created by bensutter on 13/1/17.
 */

public class PusherWrapper {
    private static PushNotificationRegistration nativePusher;
    private String registeredEvent = "registered";
    private String notificationEvent = "notification";

    public PusherWrapper(String appKey) {
        Log.d("PUSHER_WRAPPER", "Creating Pusher with App Key: " + appKey);
        System.out.print("Creating Pusher with App Key: " + appKey);
        if (nativePusher == null) {
            PusherAndroid pusher = new PusherAndroid(appKey);
            nativePusher = pusher.nativePusher();
        }
    }

    public PusherWrapper(String appKey, final ReactContext context) {
      Log.d("PUSHER_WRAPPER", "Creating Pusher with App Key: " + appKey);
      System.out.print("Creating Pusher with App Key: " + appKey);
        if (nativePusher == null) {
            PusherAndroid pusher = new PusherAndroid(appKey);
            nativePusher = pusher.nativePusher();
        }

        try {
            nativePusher.registerFCM(context, new PushNotificationRegistrationListener() {
                @Override
                public void onSuccessfulRegistration() {
                    Log.d("PUSHER_WRAPPER", "Successfully registered to FCM");
                    System.out.print("Successfully registered to FCM");
                    context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(registeredEvent, null);
                }

                @Override
                public void onFailedRegistration(int statusCode, String response) {
                    Log.d("PUSHER_WRAPPER", "FCM Registration failed with code " + statusCode + " " + response);
                    System.out.print("FCM Registration failed with code " + statusCode + " " + response);
                }
            });
            nativePusher.setFCMListener(new FCMPushNotificationReceivedListener() {
                @Override
                public void onMessageReceived(RemoteMessage remoteMessage) {
                    WritableMap map = Arguments.createMap();
                    Map<String, String> messageMap = remoteMessage.getData();
                    for(Map.Entry<String, String> entry : messageMap.entrySet()) {
                      map.putString(entry.getKey(), entry.getValue());
                    }
                    Log.d("PUSHER_WRAPPER", "FCM notification received");
                    System.out.print(remoteMessage.toString());
                    context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(notificationEvent, map);
                }
            });

        } catch (Exception ex) {
            Log.d("PUSHER_WRAPPER", "Exception in PusherWrapper " + ex.getMessage());
            System.out.print("Exception in PusherWrapper " + ex.getMessage());
        }
    }

    public PushNotificationRegistration getNativePusher() {
        return this.nativePusher;
    }

    public void subscribe(final String interest, final Callback errorCallback, final Callback successCallback) {
        Log.d("PUSHER_WRAPPER", "Attempting to subscribe to " +  interest);
        System.out.print("Attempting to subscribe to " +  interest);
        nativePusher.subscribe(interest, new InterestSubscriptionChangeListener() {
            @Override
            public void onSubscriptionChangeSucceeded() {
                Log.d("PUSHER_WRAPPER", "Success! " + interest);
                System.out.print("Success! " + interest);
                successCallback.invoke();
            }

            @Override
            public void onSubscriptionChangeFailed(int statusCode, String response) {
                Log.d("PUSHER_WRAPPER", ":(: received " + statusCode + " with" + response);
                System.out.print(":(: received " + statusCode + " with" + response);
                errorCallback.invoke(statusCode, response);
            }
        });
    }

    public void unsubscribe(final String interest, final Callback errorCallback, final Callback successCallback) {
        nativePusher.unsubscribe(interest, new InterestSubscriptionChangeListener() {
            @Override
            public void onSubscriptionChangeSucceeded() {
              Log.d("PUSHER_WRAPPER", "Success! " + interest);
              System.out.print("Success! " + interest);
              successCallback.invoke();
            }

            @Override
            public void onSubscriptionChangeFailed(int statusCode, String response) {
                Log.d("PUSHER_WRAPPER", ":(: received " + statusCode + " with" + response);
                System.out.print(":(: received " + statusCode + " with" + response);
                errorCallback.invoke(statusCode, response);
            }
        });
    }
}

@@ -2965,38 +2965,47 @@
     
-Map%3CString, String%3E messageMap
+RemoteMessage.Notification notification
  = r
@@ -3024,16 +3024,25 @@
 .get
-Data
+Notification
 ();%0A
+%0A
     
@@ -3061,425 +3061,750 @@
     
-for(Map.Entry%3CString, String%3E entry : messageMap.entrySet()) %7B%0A                      map.putString(entry.getKey(), entry.getValue());%0A                    %7D%0A                    Log.d(%22PUSHER_WRAPPER%22, %22FCM notification received%22);%0A                    System.out.print(remoteMessage.toString());%0A                    context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(notificationEvent, map);
+if(notification !== null) %7B%0A                        map.putString(%22body%22, notification.getBody());%0A                        map.putString(%22title%22, notification.getTitle());%0A                        map.putString(%22tag%22, notification.getTag());%0A                        map.putString(%22click_action%22, notification.getClickAction());%0A                        map.putString(%22icon%22, notification.getIcon());%0A%0A                        context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(notificationEvent, map);%0A                        System.out.print(remoteMessage.toString());%0A                    %7D%0A                    else %7B%0A                        Log.d(%22PUSHER_WRAPPER%22, %22No notification received%22);%0A                    %7D
 %0A   

Update Android onMessageReceived to use remoteMessage.getNotification