// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

require('es6-shim');

var hg = require('mercury');
var queryString = require('query-string');
var raf = require('raf');

var $ = require('./util/jquery');
var defineClass = require('./util/define-class');

var AddButton = require('./components/add-button');
var DestinationSearch = require('./components/destination-search');
var MapWidget = require('./components/map-widget');
var Messages = require('./components/messages');
var Message = require('./components/message');
var Suggestions = require('./components/suggestions');
var Timeline = require('./components/timeline');
var TimelineClient = require('./components/timeline-client');
var TimelineService = require('./components/timeline-server');

var CastingManager = require('./casting-manager');
var Destinations = require('./destinations');
var Identity = require('./identity');
var TravelSync = require('./travelsync');

var vanadiumWrapperDefault = require('./vanadium-wrapper');

var debug = require('./debug');
var describeDestination = require('./describe-destination');
var naming = require('./naming');
var strings = require('./strings').currentLocale;

function buildStatusErrorStringMap(statusClass, stringGroup) {
  var dict = {};
  $.each(statusClass, function(name, value) {
    dict[value] = stringGroup[name];
  });
  return dict;
}

function handleDestinationOrdinalUpdate(control, destination) {
  return control.setPlaceholder(
    describeDestination.descriptionOpenEnded(destination));
}

var CMD_REGEX = /\/(\S*)(?:\s+(.*))?/;
var SUGGESTION_PHOTO_OPTS = {
  maxHeight: 96
};

var Travel = defineClass({
  publics: {
    dump: function() {
      return this.sync.getData().then(function(data) {
        debug.log(data);
        return data;
      }, function(err) {
        console.error(err);
        throw err;
      });
    },

    status: function() {
      return this.sync.status;
    },

    error: function (err) {
      this.messages.push(Message.error(err));
    },

    info: function (info, promise) {
      this.messages.push(new Message({
        type: Message.INFO,
        text: info,
        promise: promise
      }));
    },

    getActiveTripId: function() {
      return this.sync.getActiveTripId();
    },

    invite: function(recipient) {
      var self = this;

      var owner = this.sync.getActiveTripOwner();
      if (owner) {
        this.info(strings.sendingInvite(recipient),
          this.sync.invitationManager.invite(recipient,
              this.sync.getActiveTripOwner(), this.sync.getActiveTripId())
            .then(function() {
              var me = self.sync.invitationManager.getUsername();
              self.sync.message({
                type: Message.INFO,
                text: strings.invitationSent(recipient, me)
              });
            }, function(err) {
              if (err.id === 'v.io/v23/verror.NoServers') {
                throw strings.notReachable(recipient);
              } else {
                throw err;
              }
            }));
      } else {
        this.error(strings['Trip is still initializing.']);
      }
    },

    castTimeline: function() {

    }
  },

  privates: {
    trap: function(asyncMethod) {
      var self = this;
      return function() {
        return asyncMethod.apply(this, arguments).catch(self.error);
      };
    },

    bindControlToDestination: function(control, destination) {
      var asyncs = [];

      function updateOrdinalAsync() {
        return handleDestinationOrdinalUpdate(control, destination);
      }

      var setPlace, select, deselect, updateOrdinal;

      if (destination) {
        setPlace = this.trap(control.setPlace);
        select = this.trap(control.select);
        deselect = this.trap(control.deselect);
        updateOrdinal = this.trap(updateOrdinalAsync);

        destination.onPlaceChange.add(setPlace);
        destination.onSelect.add(select);
        destination.onDeselect.add(deselect);
        destination.onOrdinalChange.add(updateOrdinal);
        asyncs.push(control.setPlace(destination.getPlace()));
        /* Since these controls are 1:1 with destinations, we don't want to stay
         * in a state where the control has invalid text but the destination is
         * still valid; that would be confusing to the user (e.g. abandoned
         * query string "restaurants" for destination 4 Privet Drive.)
         *
         * However, if the place is valid, don't bother updating the
         * destination. The destination is authoritative, and any disparity will
         * be due to update lag (especially bad for remote components), which
         * will result in oscillation. */
        control.onPlaceChange.add(function(place) {
          if (!place) {
            destination.setPlace(place);
          }
        });
      }

      asyncs.push(updateOrdinalAsync());

      if (destination && destination.isSelected()) {
        asyncs.push(control.select());
      } else {
        asyncs.push(control.deselect());
      }

      var unbind = destination? function() {
        destination.onPlaceChange.remove(setPlace);
        destination.onSelect.remove(select);
        destination.onDeselect.remove(deselect);
        destination.onOrdinalChange.remove(updateOrdinal);
        control.onPlaceChange.remove(destination.setPlace);
      } : $.noop;

      return Promise.all(asyncs).then(function() {
        return unbind;
      }, function(err) {
        unbind();
        throw err;
      });
    },

    handleDestinationAdd: function(destination) {
      var self = this;

      this.addDestinationToTimeline(this.timeline, destination)
      .then(function() {
        self.bindMiniFeedback(destination);
      }).catch(this.error);
    },

    addDestinationToTimeline: function(timeline, destination) {
      var self = this;
      return timeline.add(destination.getIndex()).then(function(control) {
        self.bindControlToDestination(control, destination);

        var asyncs = [control.setSearchBounds(self.map.getBounds())];

        control.onFocus.add(function() {
          if (!destination.isSelected()) {
            self.map.closeActiveInfoWindow();
            destination.select();
          }
        });

        control.onSearch.add(function(results) {
          /* There seems to be a bug where if you click a search suggestion (for
           * a query, not a resolved location) in autocomplete, the input box
           * under it gets clicked and focused... I haven't been able to figure
           * out why. */
          self.trap(control.focus)();

          self.handleSearchResults(results);
        });

        if (!destination.hasNext()) {
          asyncs.push(timeline.disableAdd());
          var oldLastIndex = destination.getIndex() - 1;
          if (oldLastIndex >= 0) {
            asyncs.push(timeline.get(oldLastIndex)
              .then(function(oldLast) {
                if (oldLast) {
                  self.unbindLastDestinationSearchEvents(oldLast);
                }
              }));
          }
          self.bindLastDestinationSearchEvents(control);
        }

        return Promise.all([asyncs]);
      });
    },

    handleDestinationRemove: function(destination) {
      var self = this;
      var index = destination.getIndex();
      this.timeline.remove(index).then(function(control) {
        self.unbindLastDestinationSearchEvents(control);

        if (index >= self.destinations.count()) {
          return self.timeline.get(-1).then(function(lastControl) {
            if (lastControl) {
              self.bindLastDestinationSearchEvents(lastControl);
              self.handleLastPlaceChange(lastControl.getPlace());
            }
          });
        }
        //TODO(rosswang): reselect?
      }).catch(this.error);
    },

    handleTimelineDestinationAdd: function() {
      var self = this;
      var timeline = this.timeline;
      function selectNewControl(control) {
        control.focus().catch(self.error);
        timeline.onDestinationAdd.remove(selectNewControl);
      }
      timeline.onDestinationAdd.add(selectNewControl);

      this.destinations.add().select();
    },

    handleMiniDestinationAdd: function() {
      this.miniDestinationSearch.clear();
      this.map.closeActiveInfoWindow();

      var selectedDest = this.map.getSelectedDestination();
      var index = selectedDest?
        selectedDest.getIndex() + 1 : this.destinations.count();

      var destination = this.destinations.get(index);
      if (!destination || destination.hasPlace()) {
        destination = this.destinations.add(index);
      }

      destination.select();
      this.miniDestinationSearch.focus();
      this.miniDestinationSearch.setPlaceholder(
        destination.hasNext()?
          /* Actually, the terminal case where descriptionOpenEnded would differ
           * from description is always handled by the latter branch, but
           * semantically we would want the open-ended description here. */
          strings.add(describeDestination.descriptionOpenEnded(destination)) :
          strings['Add destination']);
    },

    bindMiniFeedback: function(destination) {
      var mf = this.miniFeedback;

      destination.onSelect.add(mf.handleSelect);
      destination.onDeselect.add(mf.handleDeselect);
    },

    initMiniFeedback: function() {
      var self = this;

      var selectedDestination;

      //context: destination
      function handlePlaceChange(place) {
        self.miniDestinationSearch.setPlace(place);
        self.miniDestinationSearch.setPlaceholder(
          strings.change(describeDestination.description(this)));
      }

      //context: destination
      function handleSelect() {
        selectedDestination = this;
        handlePlaceChange.call(this, this.getPlace());
        this.onPlaceChange.add(handlePlaceChange);
      }

      //context: destination
      function handleDeselect() {
        this.onPlaceChange.remove(handlePlaceChange);
        if (selectedDestination === this) {
          selectedDestination = null;
          if (self.miniDestinationSearch.getPlace()) {
            self.miniDestinationSearch.clear();
          }
          self.miniDestinationSearch.setPlaceholder(strings['Search']);
        }
      }

      this.miniFeedback = {
        handleSelect: handleSelect,
        handleDeselect: handleDeselect,
        handlePlaceChange: handlePlaceChange
      };
    },

    showTimeline: function() {
      if (this.$timelineContainer.hasClass('collapsed')) {
        this.$toggleTimeline.removeClass('collapsed');
        this.$timelineContainer.removeClass('collapsed');
        this.$minPanel.addClass('collapsed');
        //disable the control, but wait until offscreen to avoid distraction
        this.$minPanel.one('transitionend', this.miniDestinationSearch.disable);
        this.watchMapResizes();
      }
    },

    collapseTimeline: function() {
      if (!this.$timelineContainer.hasClass('collapsed')) {
        this.$toggleTimeline.addClass('collapsed');
        this.$timelineContainer.addClass('collapsed');
        this.$minPanel.removeClass('collapsed');
        this.miniDestinationSearch.enable();
        if (!this.miniDestinationSearch.getPlace()) {
          this.miniDestinationSearch.focus();
        }
        this.watchMapResizes();
      }
    },

    bindLastDestinationSearchEvents: function(control) {
      control.onPlaceChange.add(this.handleLastPlaceChange);
      control.onDeselect.add(this.handleLastPlaceDeselected);
    },

    unbindLastDestinationSearchEvents: function(control) {
      control.onPlaceChange.remove(this.handleLastPlaceChange);
      control.onDeselect.remove(this.handleLastPlaceDeselected);
    },

    handleLastPlaceChange: function(place) {
      if (place) {
        this.timeline.enableAdd().catch(this.error);
      } else {
        this.timeline.disableAdd().catch(this.error);
      }
    },

    handleLastPlaceDeselected: function() {
      this.trimUnusedDestinations().catch(this.error);
    },

    runCommand: function(command, rest) {
      var handler = this.commands[command];
      if (handler) {
        var args = handler.parseArgs? handler.parseArgs(rest) : [rest];
        handler.op.apply(this, args);
      } else {
        this.error('Unrecognized command ' + command);
      }
    },

    handleInvite: function(invitation) {
      var self = this;

      var sender = invitation.sender;
      var owner = invitation.owner;
      var tripId = invitation.tripId;

      var message = new Message();
      message.setType(Message.INFO);
      message.setHtml(strings.invitationReceived(sender, owner));
      message.setPromise(new Promise(function(resolve, reject) {
        message.$.find('a[name=accept]').click(function() {
          invitation.accept().then(function() {
            self.sync.watchForTrip(tripId);
            return strings.invitationAccepted(sender, owner);
          }).then(resolve, reject);
          return false;
        });
        message.$.find('a[name=decline]').click(function() {
          invitation.decline().then(function() {
            return strings.invitationDeclined(sender, owner);
          }).then(resolve, reject);
          return false;
        });

        invitation.onDismiss.add(function() {
          resolve(strings.invitationDismissed(sender, owner));
        });
      }));

      this.messages.push(message);
    },

    handleSendCast: function(targetOwner, targetDeviceName, spec) {
      switch (spec.panelName) {
      case 'timeline':
        this.sendTimelineCast(targetOwner, targetDeviceName);
        break;
      default:
        this.error(strings.notCastable(spec.panelName));
      }
    },

    handleReceiveCast: function(spec) {
      switch (spec.panelName) {
      case 'timeline':
        this.receiveTimelineCast();
        break;
      default:
        this.error(strings.notCastable(spec.panelName));
      }
    },

    sendTimelineCast: function(targetOwner, targetDeviceName) {
      var self = this;
      this.vanadiumStartup.then(function(args) {
        var endpoint = naming.rpcMount(
          targetOwner, targetDeviceName, 'timeline');
        return args.vanadiumWrapper.client(endpoint).then(function(ts) {
          var tc = new TimelineClient(args.vanadiumWrapper.context(),
            ts, self.map.maps);
          tc.onError.add(self.error);
          return self.adoptTimeline(tc);
        });
      }).catch(this.error);
    },

    receiveTimelineCast: function() {
      var self = this;
      var timeline = new Timeline(this.map.maps);
      var ts = new TimelineService(timeline, this.map.maps);

      this.vanadiumStartup.then(function(args) {
        return args.vanadiumWrapper.server(
          args.mountNames.rpcMount('timeline'), ts);
      }).then(function() {
        //TODO(rosswang): delay swap until after initialized
        self.$appRoot.replaceWith(timeline.$);
      }).catch(this.error);
    },

    adoptTimeline: function(timeline) {
      var self = this;
      timeline.onAddClick.add(this.handleTimelineDestinationAdd);
      this.map.onBoundsChange.add(this.trap(timeline.setSearchBounds));
      var async = Promise.resolve();
      this.destinations.each(function(i, destination) {
        async = async.then(function() {
          return self.addDestinationToTimeline(timeline, destination);
        });
      });
      this.timeline = timeline;
      if (timeline.$) {
        this.$timelineContainer.empty().append(timeline.$).show();
        this.$toggleTimeline.show();
      } else {
        this.$timelineContainer.hide();
        this.$toggleTimeline.hide();
      }
      this.map.invalidateSize();
      return async;
    },

    handleUserMessage: function(message, raw) {
      var match = CMD_REGEX.exec(raw);
      if (match) {
        this.runCommand(match[1], match[2]);
      } else {
        this.sync.message(message);
      }
    },

    trimUnusedDestinations: function() {
      var self = this;

      var lastIndex = this.destinations.count() - 1;
      if (lastIndex > 0) {
        return this.timeline.get(lastIndex).then(function(lastControl) {
          return Promise.all([
            lastControl.getPlace(),
            lastControl.isSelected()
          ]);
        }).then(function(conditions) {
          if (!(conditions[0] || conditions[1])) {
            //check for race condition; if we're no longer up-to-date
            //just execute the next "iteration" without actually removing
            if (lastIndex === self.destinations.count() - 1) {
              self.destinations.remove(-1);
            }
            return self.trimUnusedDestinations();
          }
        });
      } else {
        return Promise.resolve();
      }
    },

    handleSearchResults: function(results) {
      this.map.showSearchResults(results);
      if (results.length > 1) {
        this.hgState.suggestions.set({
          suggestions: results.map(function(place) {
            var details = place.getDetails();
            var photoUrl;

            if (details.photos && details.photos[0]) {
              photoUrl = details.photos[0].getUrl(SUGGESTION_PHOTO_OPTS);
            }

            return {
              placeId: place.toObject().placeId,
              placeName: place.getName(),
              photoUrl: photoUrl,
              iconUrl: details.icon,
              rating: details.rating,
              priceLevel: details['price_level']
            };
          })
        });
        this.showSuggestions();
      } else {
        this.dismissSuggestions();
      }
    },

    showSuggestions: function() {
      if (!this.$hgSuggestionsRoot) {
        this.$hgSuggestionsRoot = $('<div>')
          .addClass('suggestions-container')
          .insertBefore(this.map.$);
        this.dismissHgSuggestions = hg.app(
          this.$hgSuggestionsRoot[0], this.hgState, this.hgRenderSuggestions);
        this.map.invalidateSize();
      }
      this.$hgSuggestionsRoot.prop('scrollTop', 0);
    },

    hgRenderSuggestions: function(state) {
      return Suggestions.render(state.suggestions);
    },

    dismissSuggestions: function() {
      if (this.dismissHgSuggestions) {
        this.dismissHgSuggestions();
        delete this.dismissHgSuggestions;
        this.$hgSuggestionsRoot.remove();
        delete this.$hgSuggestionsRoot;
        this.map.invalidateSize();
      }
    },

    /**
     * The map widget isn't very sensitive to size updates, so we need to
     * continuously invalidate during animations.
     */
    watchMapResizes: function() {
      var newWidth = this.map.$.width();
      if (newWidth !== this.mapWidth) {
        this.widthStable = 0;

        this.mapWidth = newWidth;
        this.map.invalidateSize();
        raf(this.watchMapResizes);

      } else if (this.widthStable < 5) {
        raf(this.watchMapResizes);
        this.widthStable++;
      } else {
        this.mapWidth = null;
      }
    }
  },

  constants: [ 'hgState' ],

  init: function (opts) {
    var self = this;

    opts = opts || {};
    var vanadiumWrapper = opts.vanadiumWrapper || vanadiumWrapperDefault;

    this.hgState = hg.state({
      suggestions: new Suggestions()
    });

    var destinations = this.destinations = new Destinations();
    destinations.onAdd.add(this.handleDestinationAdd);
    destinations.onRemove.add(this.handleDestinationRemove);

    var map = this.map = new MapWidget(opts);
    var maps = map.maps;
    map.bindDestinations(destinations);

    var messages = this.messages = new Messages();
    var timeline = this.timeline = new Timeline(maps);

    var error = this.error;
    var vanadiumStartup = this.vanadiumStartup =
      vanadiumWrapper.init(opts.vanadium)
      .then(function(wrapper) {
        wrapper.onError.add(error);
        wrapper.onCrash.add(error);

        var identity = new Identity(wrapper.getAccountName());
        var mountNames = naming.mountNames(identity);
        messages.setUsername(identity.username);

        return {
          identity: identity,
          mountNames: mountNames,
          vanadiumWrapper: wrapper
        };
      });

    var sbName = opts.syncbase ||
      queryString.parse(location.search).syncbase || 4000;
    if ($.isNumeric(sbName)) {
      sbName = '/localhost:' + sbName;
    }

    var dependencies = {
      maps: maps,
      placesService: map.createPlacesService()
    };

    var sync = this.sync = new TravelSync(
      vanadiumStartup, dependencies, sbName);
    sync.bindDestinations(destinations);

    this.info(strings['Connecting...'], sync.startup
      .then(function() {
        /* Fit whatever's in the map via timeout to simplify the coding a
         * little. Otherwise we'd need to hook into the asynchronous place
         * vivification and routing. */
        setTimeout(map.fitAll, 2250);
        return strings['Connected to all services.'];
      }));

    var directionsServiceStatusStrings = buildStatusErrorStringMap(
      maps.DirectionsStatus, strings.DirectionsStatus);

    map.onError.add(function(err) {
      var message = directionsServiceStatusStrings[err.directionsStatus] ||
        strings['Unknown error'];

      error(message);
    });

    sync.onError.add(error);
    sync.onPossibleNearbyDevices.add(function() {
      self.info(strings.castingTooltip);
    });
    sync.onMessages.add(function(messages) {
      self.messages.push.apply(self.messages, messages);
    });

    sync.invitationManager.onInvite.add(this.handleInvite);

    messages.onMessage.add(this.handleUserMessage);

    var miniAddButton = this.miniAddButton = new AddButton();
    var miniDestinationSearch = this.miniDestinationSearch =
      new DestinationSearch(maps);

    miniAddButton.onClick.add(this.handleMiniDestinationAdd);

    miniDestinationSearch.setPlaceholder(strings['Search']).catch(error);
    miniDestinationSearch.setSearchBounds(map.getBounds()).catch(error);
    map.onBoundsChange.add(this.trap(miniDestinationSearch.setSearchBounds));

    miniDestinationSearch.onSearch.add(function(results) {
      if (results.length > 0) {
        /* If we've searched for a location via the minibox, any subsequent
         * map click is probably intended to deselect the destination rather
         * than pick by clicking. This differs from the timeline behavior since
         * when we invalidate a timeline location, we delete the destination
         * place and so must pick a new one. */
        map.disableLocationSelection();
      }
      self.handleSearchResults(results);
    });

    miniDestinationSearch.onPlaceChange.add(function(place) {
      if (!place) {
        self.map.enableLocationSelection();
      } else {
        self.map.disableLocationSelection();
      }
    });

    miniDestinationSearch.onSubmit.add(function(value) {
      if (!value) {
        var selected = self.map.getSelectedDestination();
        if (selected) {
          selected.remove();
        }

        self.map.clearSearchMarkers();
      }
    });

    var $miniPanel = this.$minPanel = $('<div>')
      .addClass('mini-search')
      .append(miniAddButton.$,
              miniDestinationSearch.$);

    /* This container lets us collapse the destination panel even though it has
     * padding, without resorting to transform: scaleX which would
     * unnecessarily distort the text (which is an effect that is nice for the
     * add button, so that gets it explicitly). */
    var $timelineContainer = this.$timelineContainer = $('<div>')
      .addClass('timeline-container collapsed');

    var $toggleTimeline = this.$toggleTimeline = $('<div>')
      .addClass('toggle-timeline no-select collapsed')
      .text(strings['Timeline'])
      .click(this.collapseTimeline);
    $toggleTimeline.hoverintent(this.showTimeline, $.noop);

    map.addControls(maps.ControlPosition.TOP_CENTER, messages.$);
    map.addControls(maps.ControlPosition.LEFT_TOP, $miniPanel);
    map.addControls(maps.ControlPosition.LEFT_CENTER, $toggleTimeline);

    var $domRoot = this.$domRoot = opts.domRoot? $(opts.domRoot) : $('body');
    var $appRoot = this.$appRoot = $('<div>');

    $domRoot.append($appRoot.append($timelineContainer, map.$));

    this.initMiniFeedback();

    var castingManager = new CastingManager(sync);
    castingManager.makeCastable($timelineContainer, {
      spec: {
        panelName: 'timeline'
      }
    });
    castingManager.onAmbiguousCast.add(function(related, unknown, other) {
      console.debug('ambiguous cast');
      console.debug(related);
      console.debug(unknown);
      console.debug(other);
    });
    castingManager.onNoNearbyDevices.add(function() {
      self.error(strings.noNearbyDevices);
    });
    castingManager.onError.add(error);

    castingManager.onSendCast.add(this.handleSendCast);
    sync.onReceiveCast.add(this.handleReceiveCast);

    this.adoptTimeline(timeline);

    destinations.add();
    miniDestinationSearch.focus().catch(error);

    $domRoot.keypress(function() {
      messages.open();
      /* Somehow emergent behavior types the key just hit without any further
       * code from us. Praise be to the code gods; pray for cross-browser. */
    });

    this.commands = {
      invite: {
        op: this.invite
      },

      status: {
        op: function() {
          this.messages.push(new Message({
            type: Message.INFO,
            html: strings.status(JSON.stringify(this.status(), null, 2))
          }));
        }
      }
    };
  }
});

module.exports = Travel;
