/**
 * Assemble <http://assemble.io>
 *
 * Copyright (c) 2014, Jon Schlinkert, Brian Woodward, contributors.
 * Licensed under the MIT License (MIT).
 */

var _ = require('lodash');
var inflection = require('inflection');
var utils = require('./utils');

/**
 * Export `collection`
 */

var collection = module.exports = {};

collection.update = function(col, page, context) {
  'use strict';

  if (!context[col.name]) {
    return col;
  }

  var singularName = col.inflection || inflection.singularize(col.name);
  var pageCol = context[col.name] || [];
  if (utils.toString.call(pageCol) !== '[object Array]') {
    pageCol = [pageCol];
  }

  pageCol.forEach(function(pageItem) {
    var i = _.findIndex(col.items, function(item) {
      return item[singularName] === pageItem;
    });

    if (i === -1) {
      var obj = {};
      obj[singularName] = pageItem;
      obj.pages = [page];
      col.items.push(obj);
    } else {
      col.items[i].pages.push(page);
    }
  });
  return col;
};

function compare(a, b) {

  if (a && b) {
    if (a < b) {
      return -1;
    } else if (a > b) {
      return 1;
    } else {
      return 0;
    }
  } else {
    // pages without {sortby} field will at the end of collection
    if (!a && !b) {
      return 0;
    }
    if (!a) {
      return 1;
    }
    return -1;
  }
}

collection.sort = function(col) {
  'use strict';

  var descMap = ['desc', 'descending'];
  var itemMap = ['this', ''];

  var sortby = _.contains(itemMap, (col.sortby || '')) ? '' : col.sortby;
  var sortorder = _.contains(descMap, (col.sortorder || 'ASC').toLowerCase()) ? 'DESC' : 'ASC';

  if (sortby === '') {

    // sort items by the actual item
    col.items.sort(function(a, b) {
      return compare(a[col.inflection], b[col.inflection]);
    });

    if (sortorder !== 'ASC') {
      col.items.reverse();
    }

  } else {

    // for each item sort the pages by the page.data property
    col.items.forEach(function(item) {

      item.pages.sort(function(a, b) {
        return compare(a.data[sortby], b.data[sortby]);
      });

      if (sortorder !== 'ASC') {
        item.pages.reverse();
      }

    });

    // now sort the items by the first page in each item
    col.items.sort(function(a, b) {
      if (a.pages.length > 0 && b.pages.length > 0) {
        if (a.pages[0].data[sortby] && b.pages[0].data[sortby]) {
          if (a.pages[0].data[sortby] < b.pages[0].data[sortby]) {
            return -1;
          } else if (a.pages[0].data[sortby] > b.pages[0].data[sortby]) {
            return 1;
          } else {
            return 0;
          }
        }
      } else {
        return 0;
      }
    });

    if (sortorder !== 'ASC') {
      col.items.reverse();
    }

  }

  return col;

};

/**
 * Takes in a list of collection definitions and normalizes
 * them to a be all objects with smart defaults
 * @param  {Array} collections: List of collections as either strings or objects
 * @return {Array}             Return list of collections, all as objects
 */
collection.normalize = function(collections) {
  'use strict';

  var rtn = {};
  collections.forEach(function(item) {

    if (typeof item === 'string') {
      if (rtn[item]) {
        item = rtn[item];
      } else {
        item = {
          name: item,
          inflection: inflection.singularize(item),
          sortorder: 'ASC',
          sortby: '',
          items: []
        };
      }
    } else {
      item.items = [];
    }

    if (item.name === 'pages') {
      item.inflection = '_page';
      item.sortby = (item.sortby || '') === '' ? 'name' : item.sortby;
      item.items = [{
        '_page': 'all',
        pages: []
      }];
    }

    rtn[item.name] = item;

  });
  return rtn;
};

collection.filterProperties = function(opts) {
  return _.omit(opts, [
    'defaultLayout',
    'initializeEngine',
    'registerFunctions',
    'registerPartial'
  ]);
};
