'use strict';

var utils = require('./utils');

var mongoose = require('mongoose'),
  ObjectId = require('mongoose').Types.ObjectId;


var options = {
  includes: 'creator',
};

exports.defaultOptions = options;

var updateService = require('../services/updates.js'),
  crud = require('../controllers/crud.js'),
  update = crud('updates', options),
  Update = require('../models/update'),
  Task = require('../models/task'),
  Attachement = require('../models/attachment'),
  UpdateArchive = mongoose.model('update_archive'),
  elasticsearch = require('./elasticsearch'),
  mean = require('meanio'),
  _ = require('lodash'),
  q = require('q');

var entityIssueMap = {
  tasks: 'task',
  projects: 'project',
  discussions: 'discussion',
  offices: 'office',
  folders: 'folder',
  officeDocuments: 'Document',
  templateDocs: 'TemplateDoc'
};

Object.keys(update).forEach(function(methodName) {
  exports[methodName] = update[methodName];
});

exports.getAttachmentsForUpdate = function(req, res, next) {
  if(req.locals.error) {
    return next();
  }

  var query = {
    entity: req.locals.result._id
  };

  if(_.isArray(req.locals.result)) {
    var ids = _(req.locals.result).pluck('_id').value();
    query = {
      entity: {
        $in: ids
      }
    };
  }

  Attachement.find(query).then(function(attachments) {
    if(_.isArray(req.locals.result)) {
      _.each(req.locals.result, function(i) {
        i.attachments = _.filter(attachments, function(a) {
          return a.entity.toString() === i._id.toString();
        });
      });

      next();
    }
    else {
      req.locals.result.attachments = attachments;
      next();
    }
  });
};

exports.getByEntity = function(req, res, next) {
  if(req.locals.error) {
    return next();
  }

  var type = entityIssueMap[req.params.entity];
  if(type == 'Document') {
    type = 'officeDocument';
  }
  if(type == 'TemplateDoc') {
    type = 'templateDoc';
  }
  Update.find({
    entityType: type,
    entity: req.params.id
  })
  .populate('creator')
  .then(function(updates) {
    req.locals.result = updates;
    next();
  });
};

exports.getByUser = function(req, res, next) {
    let { start, limit, sort } = req.locals.data.pagination;
    let id = req.params.id;

    Update.find({
        creator: id
    })
    .sort(sort)
    .skip(start)
    .limit(limit)
    .populate('creator', 'name lastname profile')
    .then(function(updates) {
        res.status(200).send(updates);
    });
};

exports.created = function(req, res, next) {
  if(req.locals.error) {
    return next();
  }

  var entityName = req.locals.data.entityName;
  var entityService = updateService(entityName, {
    user: req.user
  });

  entityService.created(req.locals.result._id).then(function() {
    next();
  });
};

exports.updated = function(req, res, next) {
  if(req.locals.error || !req.locals.data.shouldCreateUpdate) {
    return next();
  }

  var entityName = req.params.entity || req.locals.data.entityName;
  var entityService = updateService(entityName, {
    user: req.user
  });

  entityService.updated(req.locals.result._id).then(function() {
    next();
  });
};

function MyTasks(req) {
  var deffered = q.defer();

  Task.find({
    assign: req.user._id
  }, function(err, tasks) {
    if(err) {
      deffered.reject(err);
    }
    else {
      deffered.resolve(tasks.map(function(t) {
        return t._id;
      }));
    }
  });
  return deffered.promise;

}

exports.getMyTasks = function(req, res, next) {
  if(req.locals.error) {
    return next();
  }
  MyTasks(req).then(function(data) {

    Update.find({
      entityType: 'task',
      entity: {
        $in: data
      }
    })
      .populate({path: 'entity', model: Task, select: 'title'})
      .populate('creator', 'name lastname')
      .exec(function(err, data) {
        if(err) {
          req.locals.error = err;
        }
        else {
          req.locals.result = data;
        }
        next();
      });
  }, function(err) {
    req.locals.error = err;
    next();
  });

};

exports.signNew = function(req, res, next) {
  var entities = {
      project: 'Project',
      task: 'Task',
      discussion: 'Discussion',
      office: 'Office',
      folder: 'Folder',
      officeDocument: 'Document',
      officeDocuments: 'Document',
      templateDoc: 'TemplateDoc'
  };

  var query = req.acl.mongoQuery(entities[req.body.data.entityType]);
  query.findOne({_id: req.body.data.entity}).exec(function(err, entity) {
    if(err) {
      req.locals.error = err;
    }
    if(!entity) {
      req.locals.error = {
        status: 404,
        message: 'Entity not found'
      };
    }
    if(entity) {
      req.locals.data.watchers = entity.watchers;
      req.locals.data.circles = entity.circles;
    }
    next();
  });
};

@@ -2147,18 +2147,16 @@
 next) %7B%0A
-  
   let %7B 
@@ -2206,18 +2206,16 @@
 nation;%0A
-  
   let id
@@ -2239,43 +2239,612 @@
 %0A%0A  
-  Update.find(%7B%0A        creator: id
+let models = %7B%0A    Task: 'task',%0A    Project: 'project',%0A    Discussion: 'discussion',%0A    Office: 'office',%0A    Folder: 'folder',%0A    Document: 'officeDocument',%0A    TemplateDoc: 'templateDoc'%0A  %7D;%0A%0A  let promises = Object.keys(models).map(model =%3E %7B%0A    return mongoose.model(model).find(%7B%0A      watchers: id%0A    %7D).select('_id')%0A  %7D);%0A%0A  Promise.all(promises).then(results =%3E %7B%0A    let query = results.map((result, i) =%3E %7B%0A      return %7B%0A        entityType: Object.values(models)%5Bi%5D,%0A        entity: %7B%0A          $in: result.map(v =%3E v._id)%0A        %7D%0A      %7D%0A    %7D);%0A%0A    Update.find(%7B%0A      $or: query
 %0A   
@@ -3021,24 +3021,29 @@
 s);%0A    %7D);%0A
+  %7D)%0A
 %7D;%0A%0Aexports.

Fix `getByUser` function - used for INBOX feature