'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
 */

module.exports = class Choices {
  constructor(choices, answers) {
    this.choices = choices.map(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(item => !item.disabled);

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

    Object.defineProperty(this, 'realLength', {
      get() {
        return this.realChoices.length;
      },
      set() {
        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
   */

  getChoice(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
   */

  get(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
   */

  where(whereClause) {
    return _.filter(this.realChoices, whereClause);
  }

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

  pluck(propertyName) {
    return _.map(this.realChoices, propertyName);
  }

  // Expose usual Array methods
  indexOf() {
    return this.choices.indexOf.apply(this.choices, arguments);
  }

  forEach() {
    return this.choices.forEach.apply(this.choices, arguments);
  }

  filter() {
    return this.choices.filter.apply(this.choices, arguments);
  }

  find(func) {
    return _.find(this.choices, func);
  }

  push() {
    var objs = _.map(arguments, val => new Choice(val));
    this.choices.push.apply(this.choices, objs);
    this.realChoices = this.choices.filter(Separator.exclude);
    return this.choices;
  }
};
