"use strict";

var StreamUser = require('./user');

var isObject = require('lodash/isObject');

var isPlainObject = require('lodash/isPlainObject');

var StreamUserSession = function StreamUserSession() {
  this.initialize.apply(this, arguments);
};

StreamUserSession.prototype = {
  initialize: function initialize(client, userId, userAuthToken) {
    /**
     * Initialize a user session object
     * @method intialize
     * @memberof StreamUserSession.prototype
     * @param {StreamClient} client Stream client this collection is constructed from
     * @param {string} userId The ID of the user
     * @param {string} token JWT token
     * @example new StreamUserSession(client, "123", "eyJhbGciOiJIUzI1...")
     */
    this.client = client;
    this.userId = userId;
    this.token = userAuthToken;
    this.user = new StreamUser(client, userId, userAuthToken);
    this.reactions = client.reactions(userAuthToken);
    this.images = this.client.images(this.token);
    this.files = this.client.files(this.token);
  },
  feed: function feed(feedGroup, user) {
    if (user === undefined) {
      user = this.userId;
    } else if (user instanceof StreamUser) {
      user = user.id;
    }

    var feed = this.client.feed(feedGroup, user, this.token);

    var replaceStreamObjects = function replaceStreamObjects(obj) {
      var cloned = obj;

      if (Array.isArray(obj)) {
        cloned = obj.map(function (v) {
          return replaceStreamObjects(v);
        });
      } else if (isPlainObject(obj)) {
        cloned = {};

        for (var k in obj) {
          cloned[k] = replaceStreamObjects(obj[k]);
        }
      } else if (isObject(obj) && obj._streamRef !== undefined) {
        cloned = obj._streamRef();
      }

      return cloned;
    };

    feed._addActivityOriginal = feed.addActivity;

    feed.addActivity = function (activity, callback) {
      activity = replaceStreamObjects(activity);
      return feed._addActivityOriginal(activity, callback);
    };

    return feed;
  },
  personalizedFeed: function personalizedFeed() {
    var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
    var callback = arguments.length > 1 ? arguments[1] : undefined;
    return this.client.get({
      url: 'enrich/personalization/feed/',
      qs: options,
      signature: this.token
    }, callback);
  },
  followUser: function followUser(user) {
    // The user argument can be a StreamUser object or a userId
    if (user instanceof StreamUser) {
      user = user.id;
    }

    return this.feed('timeline').follow('user', user);
  },
  getUser: function getUser(userId) {
    return new StreamUser(this.client, userId, this.token);
  },
  storage: function storage(collection) {
    return this.client.storage(collection, this.token);
  },
  react: function react(kind, activityId, data) {
    return this.reactions.add(kind, activityId, data);
  },
  objectFromResponse: function objectFromResponse(response) {
    var object = this.storage(response.collection).object(response.id, response.data);
    object.full = response;
    return object;
  },
  og: function og(url) {
    return this.client.get({
      url: 'og/',
      qs: {
        url: url
      },
      signature: this.token
    });
  }
};
module.exports = StreamUserSession;