import firebase from 'firebase';
import EventEmitter from 'events';
import { config } from '../config';

/**
 * extend EventEmitter so user of NoteRepository can react to
 * our custom events (ex: noteRepository.on('added'))
 */
class NoteRepository extends EventEmitter {
  constructor() {
    super();

    // Initialize Firebase
    firebase.initializeApp(config);

    // Firebase database reference to notes
    this.ref = firebase.database().ref('notes');
    this.attachFirebaseListeners();
  }

  // creates a note
  create({ title = '', content = '', }, onComplete) {
    this.ref.push({ title, content }, onComplete);
  }

  // updates a note
  update({ key, title = '', content = '' }, onComplete) {
    this.ref.child(key).update({ title, content }, onComplete);
  }

  // removes a note
  remove(note, onComplete) {
    const key = note.id || note.key;
    this.ref.child(key).remove(onComplete);
  }

  // Finds the index of the note inside the 'notes' array by looking for its key
  findIndex(notes, key) {
    return notes.findIndex(note => note.key === key);
  }

  // Finds the note inside the 'notes' array by searching for its key
  find(notes, key) {
    return notes.find(note => note.key === key);
  }

  // process snapshot data and add unique Firebase key to each note
  snapshotToNote(snapshot) {
    const { key } = snapshot;
    const note = { ...snapshot.val(), key };
    return note;
  }

  /**
   * The event listeners process the data passed through from
   * the Firebase DataSnapshots and then propagate the events outward
   */
  onAdded(snapshot) {
    const note = this.snapshotToNote(snapshot);
    this.emit('added', note);
  }

  onRemoved(oldSnapshot) {
    const note = this.snapshotToNote(oldSnapshot);
    this.emit('removed', note);
  }

  onChanged(snapshot) {
    const note = this.snapshotToNote(snapshot);
    this.emit('changed', note);
  }

  // attach event listeners to Firebase
  attachFirebaseListeners() {
    this.ref.on('child_added', this.onAdded, this);
    this.ref.on('child_removed', this.onRemoved, this);
    this.ref.on('child_changed', this.onChanged, this);
  }

  // detach listeners from Firebase
  detachFirebaseListeners() {
    this.ref.off('child_added', this.onAdded, this);
    this.ref.off('child_removed', this.onRemoved, this);
    this.ref.off('child_changed', this.onChanged, this);
  }
}

export default new NoteRepository();

@@ -446,20 +446,20 @@
 ().ref('
-note
+user
 s');%0A   
@@ -492,24 +492,225 @@
 ers();%0A  %7D%0A%0A
+  // get unique id for Firebase user%0A  getUID() %7B%0A    return firebase.auth().currentUser.uid;%0A  %7D%0A%0A  // get user's notes ref%0A  getNotesRef() %7B%0A    return this.ref.child(%60$%7Bthis.getUID()%7D/notes%60);%0A  %7D%0A%0A
   // creates
@@ -780,19 +780,29 @@
    this.
-ref
+getNotesRef()
 .push(%7B 
@@ -916,35 +916,45 @@
 ete) %7B%0A    this.
-ref
+getNotesRef()
 .child(key).upda
@@ -1085,27 +1085,37 @@
 y;%0A    this.
-ref
+getNotesRef()
 .child(key).
@@ -2187,32 +2187,113 @@
 ers() %7B%0A    
-this.ref
+firebase.auth().onAuthStateChanged(user =%3E %7B%0A      if (user) %7B%0A        this.getNotesRef()
 .on('child_a
@@ -2320,32 +2320,46 @@
  this);%0A    
+ 
+   
 this.
-ref
+getNotesRef()
 .on('child_r
@@ -2382,32 +2382,36 @@
 Removed, this);%0A
+    
     this.ref.on(
@@ -2403,19 +2403,29 @@
    this.
-ref
+getNotesRef()
 .on('chi
@@ -2456,24 +2456,40 @@
 ged, this);%0A
+      %7D%0A    %7D);%0A
   %7D%0A%0A  // de
@@ -2548,35 +2548,45 @@
 rs() %7B%0A    this.
-ref
+getNotesRef()
 .off('child_adde
@@ -2611,35 +2611,45 @@
 this);%0A    this.
-ref
+getNotesRef()
 .off('child_remo
@@ -2686,19 +2686,29 @@
    this.
-ref
+getNotesRef()
 .off('ch

Redefine user note references