import { InteractionManager, Platform } from 'react-native'
import _ from 'lodash'
import Parse from 'parse/react-native'
import Store from '../data/Store'
import realm from '../data/Realm'
import PushNotification from 'react-native-push-notification';

import { BackgroundGeolocation } from './BackgroundProcess'
import { loadAllCachedGeofenceTriggers } from './Triggers'
import { showToast } from './Notifications'


let activeMap; // Cache a MapPage component for to update when geofencing triggers are crossed.

/**
 * Caches a MapPage component inside a variable for easy access
 * @param {element} component     React class element to be cached
 */
export function setActiveMap(component) {
  activeMap = component
  connectMapToGeofence()
}

/**
 * Clears and deactivates the currently cached map element
 * @param  {element} component    React class element to be cleared
 */
export function clearActiveMap(component) {
  if (activeMap == component) {
    component.active = false
    activeMap = null
  }
}

/**
 * Creates native geofence objects using the 3rd-party geolocation library.
 * Erases previous set of native geofences and adds new ones based on geofence triggers.
 */
export function setupGeofences() {
  // BackgroundGeolocation.stop()

  getUserLocationData((response) => {console.log(response)})

  loadAllCachedGeofenceTriggers({excludeCompleted: true}, (err, response) => {
    resetGeofences((err) => {
      if (err) {
        console.warn('Unable to load geofence triggers');
        console.warn(err);
        return;
      }

      const triggerGeofences = response.map((trigger) => {
        return {
          identifier: trigger.id,
          radius: trigger.radius,
          latitude: trigger.latitude,
          longitude: trigger.longitude,
          notifyOnEntry: true,
          notifyOnExit: true,
          notifyOnDwell: true,
          loiteringDelay: 30000
        }
      })
      
      console.log('Adding ' + triggerGeofences.length + ' geofences...')
      BackgroundGeolocation.addGeofences(triggerGeofences, function() {
        console.log("Successfully added geofences.");
      }, function(error) {
          console.warn("Failed to add geofences.", error);
      })

      BackgroundGeolocation.start(() => {
        console.info('Geolocation tracking started.')
      })
    })
    connectMapToGeofence()
  })
}

/**
 * Erases all active geofences in the native geofencing api.
 * @param  {Function} callback Callback function to execute afterwards.
 */
export function resetGeofences(callback) {
  BackgroundGeolocation.removeGeofences(
    function success() {
      console.log('Cleared current geofencing settings.')
      callback(null)
    },
    function error(e) {
      console.warn('Error resetting geofencing settings.')
      console.warn(e)
      callback(e)
    }
  )
}

/**
 * Returns an object containing last recorded geolocation data via an async callback
 * @param  {Function} callback   Returns object containing the current latitude, longitude, accuracy, and timestamp.
 */
export function getUserLocationData(callback) {
  BackgroundGeolocation.getLocations((locations) => {
    let current = locations[0];
    if (current && current.coords) {
      callback({
        latitude: current.coords.latitude,
        longitude: current.coords.longitude,
        accuracy: current.coords.accuracy,
        timestamp: current.timestamp,
      })
    } else {
      callback({
        latitude: 0,
        longitude: 0,
        accuracy: 0,
        timestamp: new Date()
      })
    }
  });
}

/**
 * Links the currently cached MapPage element to the geofence events, allowing for updates on the component.
 */
function connectMapToGeofence() {
  BackgroundGeolocation.on('geofence', (params) => {
    try {
      console.log('A geofence has been crossed!');
      crossGeofence(params);
      if (activeMap && activeMap.active) {
        // Send a new set of geofence trigger parameters to the cached MapPage element.
        activeMap.updateMarkers(params);
      }
    } catch(e) {
      console.error('Geofencing error.', e);
    }
  })
}

function crossGeofence(params) {
  console.log('Geofence crossed: ' + params.action + ' - ' + params.identifier);

  // Update Geofence Trigger
  try {
    const trigger = realm.objects('GeofenceTrigger').filtered(`id = "${params.identifier}"`)[0];
    if (trigger) {
      realm.write(() => {
        trigger.inRange = true;
        trigger.triggered = _.lowerCase(params.action) == 'exit' ? false : true;
      })

      // Notify on entry
      if (_.lowerCase(params.action) == 'enter') {
        const form = realm.objects('Form').filtered(`id = "${trigger.formId}"`)[0];
        const survey = realm.objects('Survey').filtered(`id = "${trigger.surveyId}"`)[0];

        if (form && survey) {
          if (Platform.OS === 'android') {
            BackgroundGeolocation.playSound(25);
          } else {
            // TODO: find a proper tone on iOS
            // http://iphonedevwiki.net/index.php/AudioServices
            // BackgroundGeolocation.playSound(1000);
          }

          showToast(form.title, 'New geofence form available.', 'globe', 8, () => {
            Store.navigator.push({
              path: 'form',
              title: survey.title,
              forms: form,
              survey: survey,
              type: 'geofence'
            });
          });
        }

      }
    } else {
      alert('Trigger not found.');
    }
  } catch (e) {
    console.warn(e)
  }
}

/**
 * Dev: logs a list of the currently active geofences in the native API.
 */
export function logActiveGeofences() {
  BackgroundGeolocation.getGeofences(function(geofences) {
    console.log('active geofences: ')
    console.log(geofences)
  });
}
@@ -1919,16 +1919,109 @@
   %7D)
+;%0A
 %0A      
-%0A
+BackgroundGeolocation.start(() =%3E %7B%0A        console.info('Geolocation tracking started.')%0A  
     
@@ -2085,24 +2085,26 @@
 fences...')%0A
+  
       Backgr
@@ -2163,32 +2163,34 @@
 ion() %7B%0A        
+ 
+ 
 console.log(%22Suc
@@ -2225,16 +2225,18 @@
 ;%0A      
+  
 %7D, funct
@@ -2250,32 +2250,34 @@
 or) %7B%0A          
+ 
+ 
 console.warn(%22Fa
@@ -2311,28 +2311,61 @@
 ror);%0A      
-%7D)%0A%0A
+  %7D);%0A        setTimeout(() =%3E %7B%0A    
       Backgr
@@ -2376,38 +2376,56 @@
 Geolocation.
-start(() 
+getGeofences((geofences)
 =%3E
- 
 %7B%0A
+    
         cons
@@ -2432,45 +2432,73 @@
 ole.
-info('Geolocation tracking started.')
+log(%22getGeofences: %22, geofences);%0A          %7D);%0A        %7D, 5000);
 %0A   
@@ -5937,16 +5937,17 @@
 ofences)%0A  %7D);%0A%7D
+%0A

add the geofences within callback of start method