package io.videtur.ignis.service;

import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.os.IBinder;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.TaskStackBuilder;
import android.util.Log;

import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ServerValue;
import com.google.firebase.database.ValueEventListener;

import java.util.HashMap;
import java.util.Map;

import io.videtur.ignis.ChatActivity;
import io.videtur.ignis.MainActivity;
import io.videtur.ignis.R;

import static io.videtur.ignis.util.Constants.MESSAGES_REF;
import static io.videtur.ignis.util.Constants.USERS_REF;
import static io.videtur.ignis.util.Util.getKeyFromEmail;

public class NotificationService extends Service {

    private static final String TAG = "NotificationService";
    private static final int NOTIFICATION_ID = 1;
    private static final int LED_COLOR = 0x2196f3;

    private FirebaseAuth mAuth;
    private FirebaseAuth.AuthStateListener mAuthStateListener;
    private FirebaseDatabase mDatabase;
    private DatabaseReference mChatsRef;
    private DatabaseReference mMessagesRef;
    private DatabaseReference mUnreadMessagesRef;

    private ValueEventListener mUnreadMessagesListener;

    private Context mContext;
    private Resources mRes;
    private String mUserKey;

    private NotificationManager mNotificationManager;
    private NotificationCompat.Builder mNotifyBuilder;

    public NotificationService(Context applicationContext) {
        super();
        mContext = applicationContext;
        mRes = mContext.getResources();
    }

    public NotificationService() {
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        super.onStartCommand(intent, flags, startId);
        Log.d(TAG, "onStartCommand");

        // Set up notifications
        mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        // Set up auth listener
        mAuth = FirebaseAuth.getInstance();
        mAuthStateListener = new FirebaseAuth.AuthStateListener() {
            @Override
            public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
                if (firebaseAuth.getCurrentUser() != null) {
                    if (mUnreadMessagesRef != null) {
                        mUnreadMessagesRef.removeEventListener(mUnreadMessagesListener);
                    }

                    mUserKey = getKeyFromEmail(firebaseAuth.getCurrentUser().getEmail());
                    mDatabase = FirebaseDatabase.getInstance();
                    mMessagesRef = mDatabase.getReference(MESSAGES_REF);
                    mUnreadMessagesRef = mDatabase.getReference(USERS_REF).child(mUserKey).child("unread");

                    mUnreadMessagesListener = mUnreadMessagesRef.addValueEventListener(new ValueEventListener() {
                        @Override
                        public void onDataChange(DataSnapshot dataSnapshot) {
                            notifyMessages(dataSnapshot);
                        }

                        @Override
                        public void onCancelled(DatabaseError databaseError) {

                        }
                    });
                }
            }
        };
        mAuth.addAuthStateListener(mAuthStateListener);

        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.i(TAG, "onDestroy()");
        mAuth.removeAuthStateListener(mAuthStateListener);
        // TODO restart service if destroyed
        // Intent broadcastIntent = new Intent("BroadcastReceiver");
        // sendBroadcast(broadcastIntent);
    }

    private void notifyMessages(DataSnapshot unreadSnapshot) {
        long chatCount = unreadSnapshot.getChildrenCount();
        long totalMessageCount = 0;
        Map<String, Object> updates = new HashMap<>();

        for (DataSnapshot chatSnapshot : unreadSnapshot.getChildren()) {
            totalMessageCount += chatSnapshot.getChildrenCount();
            for (DataSnapshot messageSnapshot : chatSnapshot.getChildren()) {
                Boolean pendingDelivery = messageSnapshot.getValue(Boolean.class);
                if (pendingDelivery) {
                    updates.put("/users/" + mUserKey + "/unread/" + chatSnapshot.getKey()
                            + "/" + messageSnapshot.getKey(), Boolean.FALSE);
                    updates.put("/messages/" + chatSnapshot.getKey() + "/" + messageSnapshot.getKey()
                            + "/deliveryReceipts/" + mUserKey, ServerValue.TIMESTAMP);
                }
            }
        }

        if (totalMessageCount >= 1) {
            PendingIntent pendingIntent;
            if (chatCount == 1) {
                pendingIntent = getIntentForSingleChat(unreadSnapshot.getChildren().iterator().next().getKey());
            } else {
                pendingIntent = getIntentForMultipleChats();
            }
            mNotifyBuilder = new NotificationCompat.Builder(this)
                    .setContentIntent(pendingIntent)
                    .setContentTitle(getResources().getString(R.string.app_name))
                    .setContentText(getNotificationText(chatCount, totalMessageCount))
                    .setSmallIcon(R.mipmap.ic_launcher)
                    .setLights(LED_COLOR, 1000, 1000);
            if (updates.size() > 0) {
                mNotifyBuilder.setDefaults(NotificationCompat.DEFAULT_SOUND);
                mNotifyBuilder.setDefaults(NotificationCompat.DEFAULT_VIBRATE);
            }
            mNotificationManager.notify(NOTIFICATION_ID, mNotifyBuilder.build());
            mDatabase.getReference().updateChildren(updates);
        } else {
            mNotificationManager.cancel(NOTIFICATION_ID);
        }
    }

    private String getNotificationText(long chatCount, long messageCount) {
        return mRes.getQuantityString(R.plurals.number_of_unread_messages, (int) messageCount, messageCount)
                + mRes.getQuantityString(R.plurals.number_of_unread_chats, (int) chatCount, chatCount);
    }

    private PendingIntent getIntentForSingleChat(String chatKey) {
        Intent intent = new Intent(this, ChatActivity.class);
        intent.putExtra(ChatActivity.ARG_CHAT_KEY, chatKey);
        TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
        // Adds the back stack
        stackBuilder.addParentStack(ChatActivity.class);
        // Adds the Intent to the top of the stack
        stackBuilder.addNextIntent(intent);
        // Gets a PendingIntent containing the entire back stack
        return stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
    }

    private PendingIntent getIntentForMultipleChats() {
        Intent intent = new Intent(this, MainActivity.class);
        TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
        // Adds the back stack
        stackBuilder.addParentStack(MainActivity.class);
        // Adds the Intent to the top of the stack
        stackBuilder.addNextIntent(intent);
        // Gets a PendingIntent containing the entire back stack
        return stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

@@ -1273,16 +1273,123 @@
 rvice%22;%0A
+    private static final String RESTART_BROADCAST = %22io.videtur.ignis.service.RestartNotificationService%22;%0A
     priv
@@ -1473,16 +1473,18 @@
 LOR = 0x
+ff
 2196f3;%0A
@@ -2131,48 +2131,8 @@
 xt;%0A
-        mRes = mContext.getResources();%0A
     
@@ -2350,24 +2350,80 @@
 Command%22);%0A%0A
+        mRes = getApplicationContext().getResources();%0A%0A
         // S
@@ -4144,13 +4144,8 @@
   //
- TODO
  res
@@ -4177,19 +4177,16 @@
 %0A       
- //
  Intent 
@@ -4218,27 +4218,25 @@
 ent(
-%22BroadcastReceiver%22
+RESTART_BROADCAST
 );%0A 
@@ -4241,19 +4241,16 @@
 %0A       
- //
  sendBro

Make the NotificationService never-ending