(function() {
  'use strict';
  window.Whisper = window.Whisper || {};

  Whisper.DeliveryReceipts = new (Backbone.Collection.extend({
    forMessage: function(conversation, message) {
      var recipients;
      if (conversation.isPrivate()) {
        recipients = [conversation.id];
      } else {
        recipients = conversation.get('members') || [];
      }
      var receipts = this.filter(function(receipt) {
        return (
          receipt.get('timestamp') === message.get('sent_at') &&
          recipients.indexOf(receipt.get('source')) > -1
        );
      });
      this.remove(receipts);
      return receipts;
    },
    onReceipt: function(receipt) {
      var messages = new Whisper.MessageCollection();
      return messages
        .fetchSentAt(receipt.get('timestamp'))
        .then(function() {
          if (messages.length === 0) {
            return;
          }
          var message = messages.find(function(message) {
            return (
              !message.isIncoming() &&
              receipt.get('source') === message.get('conversationId')
            );
          });
          if (message) {
            return message;
          }

          var groups = new Whisper.GroupCollection();
          return groups.fetchGroups(receipt.get('source')).then(function() {
            var ids = groups.pluck('id');
            ids.push(receipt.get('source'));
            return messages.find(function(message) {
              return (
                !message.isIncoming() &&
                _.contains(ids, message.get('conversationId'))
              );
            });
          });
        })
        .then(
          function(message) {
            if (message) {
              var deliveries = message.get('delivered') || 0;
              var delivered_to = message.get('delivered_to') || [];
              return new Promise(
                function(resolve, reject) {
                  message
                    .save({
                      delivered_to: _.union(delivered_to, [
                        receipt.get('source'),
                      ]),
                      delivered: deliveries + 1,
                    })
                    .then(
                      function() {
                        // notify frontend listeners
                        var conversation = ConversationController.get(
                          message.get('conversationId')
                        );
                        if (conversation) {
                          conversation.trigger('delivered', message);
                        }

                        this.remove(receipt);
                        resolve();
                      }.bind(this),
                      reject
                    );
                }.bind(this)
              );
              // TODO: consider keeping a list of numbers we've
              // successfully delivered to?
            } else {
              console.log(
                'No message for delivery receipt',
                receipt.get('source'),
                receipt.get('timestamp')
              );
            }
          }.bind(this)
        )
        .catch(function(error) {
          console.log(
            'DeliveryReceipts.onReceipt error:',
            error && error.stack ? error.stack : error
          );
        });
    },
  }))();
})();
