'use strict';
var assert = require('assert');
var _ = require('lodash');
var Separator = require('./separator');
var Choice = require('./choice');

/**
 * Choices collection
 * Collection of multiple `choice` object
 * @constructor
 * @param {Array} choices  All `choice` to keep in the collection
 */

var Choices = module.exports = function (choices, answers) {
  this.choices = choices.map(function (val) {
    if (val.type === 'separator') {
      if (!(val instanceof Separator)) {
        val = new Separator(val.line);
      }
      return val;
    }
    return new Choice(val, answers);
  });

  this.realChoices = this.choices
    .filter(Separator.exclude)
    .filter(function (item) {
      return !item.disabled;
    });

  Object.defineProperty(this, 'length', {
    get: function () {
      return this.choices.length;
    },
    set: function (val) {
      this.choices.length = val;
    }
  });

  Object.defineProperty(this, 'realLength', {
    get: function () {
      return this.realChoices.length;
    },
    set: function () {
      throw new Error('Cannot set `realLength` of a Choices collection');
    }
  });
};

/**
 * Get a valid choice from the collection
 * @param  {Number} selector  The selected choice index
 * @return {Choice|Undefined} Return the matched choice or undefined
 */

Choices.prototype.getChoice = function (selector) {
  assert(_.isNumber(selector));
  return this.realChoices[selector];
};

/**
 * Get a raw element from the collection
 * @param  {Number} selector  The selected index value
 * @return {Choice|Undefined} Return the matched choice or undefined
 */

Choices.prototype.get = function (selector) {
  assert(_.isNumber(selector));
  return this.choices[selector];
};

/**
 * Match the valid choices against a where clause
 * @param  {Object} whereClause Lodash `where` clause
 * @return {Array}              Matching choices or empty array
 */

Choices.prototype.where = function (whereClause) {
  return _.filter(this.realChoices, whereClause);
};

/**
 * Pluck a particular key from the choices
 * @param  {String} propertyName Property name to select
 * @return {Array}               Selected properties
 */

Choices.prototype.pluck = function (propertyName) {
  return _.map(this.realChoices, propertyName);
};

// Expose usual Array methods
Choices.prototype.indexOf = function () {
  return this.choices.indexOf.apply(this.choices, arguments);
};
Choices.prototype.forEach = function () {
  return this.choices.forEach.apply(this.choices, arguments);
};
Choices.prototype.filter = function () {
  return this.choices.filter.apply(this.choices, arguments);
};
Choices.prototype.find = function (func) {
  return _.find(this.choices, func);
};
Choices.prototype.push = function () {
  var objs = _.map(arguments, function (val) {
    return new Choice(val);
  });
  this.choices.push.apply(this.choices, objs);
  this.realChoices = this.choices.filter(Separator.exclude);
  return this.choices;
};
