'use strict';

exports.__esModule = true;

var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');

var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);

var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');

var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);

var _inherits2 = require('babel-runtime/helpers/inherits');

var _inherits3 = _interopRequireDefault(_inherits2);

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _propTypes = require('prop-types');

var _propTypes2 = _interopRequireDefault(_propTypes);

var _Label = require('../Label');

var _Label2 = _interopRequireDefault(_Label);

var _InputError = require('../InputError');

var _InputError2 = _interopRequireDefault(_InputError);

var _InputHelper = require('../InputHelper');

var _InputHelper2 = _interopRequireDefault(_InputHelper);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * @category controls
 * @component input
 * @variations collab-ui-react
 */

var determineErrorType = function determineErrorType(array) {
  return array.reduce(function (agg, e) {
    return agg === 'error' ? agg : e.type || '';
  }, '');
};

var filterErrorsByType = function filterErrorsByType(array, value) {
  return array.reduce(function (agg, e) {
    return e.type === value ? agg.concat(e.error) : agg;
  }, []);
};

/** Text input with integrated label to enforce consistency in layout, error display, label placement, and required field marker. */

var Input = function (_React$Component) {
  (0, _inherits3.default)(Input, _React$Component);

  function Input() {
    var _temp, _this, _ret;

    (0, _classCallCheck3.default)(this, Input);

    for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }

    return _ret = (_temp = (_this = (0, _possibleConstructorReturn3.default)(this, _React$Component.call.apply(_React$Component, [this].concat(args))), _this), _this.state = {
      isEditing: false,
      value: _this.props.value
    }, _this.handleKeyDown = function (e) {
      var onKeyDown = _this.props.onKeyDown;


      if (onKeyDown) {
        onKeyDown(e);
      }
    }, _this.handleFocus = function (e) {
      var _this$props = _this.props,
          onFocus = _this$props.onFocus,
          disabled = _this$props.disabled;


      if (disabled) {
        e.stopPropagation();
        return;
      }

      if (onFocus) {
        onFocus(e);
      }
      _this.setState({
        isEditing: true
      });
    }, _this.handleMouseDown = function (e) {
      var _this$props2 = _this.props,
          onMouseDown = _this$props2.onMouseDown,
          disabled = _this$props2.disabled;


      if (disabled) {
        e.stopPropagation();
        return;
      }

      if (onMouseDown) {
        onMouseDown(e);
      }
      _this.setState({
        isEditing: true
      });
    }, _this.handleChange = function (e) {
      var onChange = _this.props.onChange;

      var value = e.target.value;

      _this.setState(function () {
        onChange && onChange(value);
        return { value: value };
      });
    }, _this.handleBlur = function (e) {
      var onDoneEditing = _this.props.onDoneEditing;

      var value = e.target.value;
      e.stopPropagation();
      e.preventDefault();

      if (e.keyCode === 27 || e.keyCode === 13 || e.type === 'blur') {
        _this.setState({ isEditing: false });

        if (onDoneEditing) {
          onDoneEditing(value);
        }
      }
    }, _temp), (0, _possibleConstructorReturn3.default)(_this, _ret);
  }

  Input.prototype.render = function render() {
    var _props = this.props,
        className = _props.className,
        defaultValue = _props.defaultValue,
        inputClassName = _props.inputClassName,
        inputSize = _props.inputSize,
        inputRef = _props.inputRef,
        htmlId = _props.htmlId,
        name = _props.name,
        label = _props.label,
        type = _props.type,
        errorArr = _props.errorArr,
        placeholder = _props.placeholder,
        inputHelpText = _props.inputHelpText,
        children = _props.children,
        disabled = _props.disabled,
        readOnly = _props.readOnly,
        secondaryLabel = _props.secondaryLabel,
        nestedLevel = _props.nestedLevel;
    var value = this.state.value;


    var errorType = errorArr.length > 0 && determineErrorType(errorArr) || '';
    var errors = errorType && filterErrorsByType(errorArr, errorType) || [];

    var _ref = _react2.default.createElement(_Label2.default, {
      className: 'cui-label__secondary-label',
      label: secondaryLabel,
      htmlFor: htmlId
    });

    var secondaryLabelWrapper = function secondaryLabelWrapper() {
      return _react2.default.createElement(
        'div',
        { className: 'cui-label__secondary-label-container' },
        inputElement,
        _ref
      );
    };

    var inputElement = _react2.default.createElement('input', {
      className: 'cui-input' + ('' + (inputClassName ? ' ' + inputClassName : '')) + ('' + (readOnly ? ' read-only' : '')) + ('' + (disabled ? ' disabled' : '')) + ('' + (value ? ' dirty' : '')),
      id: htmlId,
      type: type,
      name: name,
      onKeyDown: this.handleKeyDown,
      onBlur: this.handleBlur,
      onFocus: this.handleFocus,
      onMouseDown: this.handleMouseDown,
      placeholder: placeholder,
      value: value || defaultValue,
      onChange: this.handleChange,
      ref: inputRef || 'editTextfield',
      disabled: disabled,
      readOnly: readOnly,
      tabIndex: 0
    });

    return _react2.default.createElement(
      'div',
      {
        className: 'cui-input-group' + (' ' + inputSize) + ('' + (inputSize ? ' columns' : '')) + ('' + (readOnly ? ' read-only' : '')) + ('' + (disabled ? ' disabled' : '')) + ('' + (errorType ? ' ' + errorType : '')) + ('' + (nestedLevel && ' cui-input--nested-' + nestedLevel || '')) + ('' + (className ? ' ' + className : '')) },
      label && _react2.default.createElement(_Label2.default, { className: 'cui-label', label: label, htmlFor: htmlId }),
      secondaryLabel && secondaryLabelWrapper() || inputElement,
      inputHelpText && _react2.default.createElement(_InputHelper2.default, { message: inputHelpText }),
      errors && errors.map(function (e, i) {
        return _react2.default.createElement(_InputError2.default, { error: e, key: 'input-error-' + i });
      }),
      children
    );
  };

  return Input;
}(_react2.default.Component);

Input.displayName = 'Input';
exports.default = Input;


/**
* @name Default Input
* @description Inputs are useful.
*
* @category controls
* @component input
* @section default
*
* @js

export default class Default extends React.PureComponent {

  render() {
    return (
      <div className='row'>
      <Input
        name='defaultInput'
        label='Default Input'
        htmlId='defaultInput'
        inputSize='small-5'
        placeholder='Placeholder Text'
      />
    </div>
    );
  }
}

**/

/**
* @name Input Type = Number
* @description Inputs are useful.
*
* @category controls
* @component input
* @section number
*
* @js

export default class Default extends React.PureComponent {
  render() {
    return (
      <div className='row'>
      <Input
        name='input2'
        label='Number Input'
        htmlId='input2'
        type='number'
      />
    </div>
    );
  }
}

**/

/**
* @name Input Type = Password
* @description Inputs are useful.
*
* @category controls
* @component input
* @section Type Attribute
*
* @js

export default class Default extends React.PureComponent {
  render() {
    return (
      <div className='row'>
      <Input
        name='input3'
        label='Password Input'
        htmlId='input3'
        type='password'
      />
    </div>
    );
  }
}

**/

/**
* @name Input Size
* @description Inputs are useful.
*
* @category controls
* @component input
* @section inputSize Attribute
*
* @js

export default function InputSize() {
  return (
    <div className='row'>
      <Input
        name='input4'
        label='Large Input'
        htmlId='input4'
        inputSize='medium-12'
      />
    </div>
  );
}

**/

/**
* @name Input Secondary Label
* @description Inputs are useful.
*
* @category controls
* @component input
* @section secondary-label
*
* @js

export default function InputSecondary() {
  return (
    <div className='row'>
      <Input
        name='inputSecondaryLabel'
        label='Input with Secondary Label'
        htmlId='inputSecondaryLabel'
        inputSize='small-5'
        secondaryLabel='Secondary Label'
      />
    </div>
  );
}

**/

/**
* @name Input Required
* @description Inputs are useful.
*
* @category controls
* @component input
* @section Required Attribute
*
* @js

export default function InputRequired() {
  return (
    <div className='row'>
      <Input
        name='input6'
        label='Required Input'
        htmlId='input6'
        required
      />
    </div>
  );
}

**/

/**
* @name Input Placeholder
* @description Inputs are useful.
*
* @category controls
* @component input
* @section placeholder Attribute
*
* @js

export default function InputPlaceholder() {
  return (
    <div className='row'>
      <Input
        name='input7'
        label='Placeholder Input'
        htmlId='input7'
        placeholder='Placeholder'
      />
    </div>
  );
}

**/

/**
* @name Input Help Text
* @description Inputs are useful.
*
* @category controls
* @component input
* @section help-text
*
* @js

export default function InputHelp() {
  return (
    <div className='row'>
      <Input
        name='inputHelpText'
        label='Help Text Input'
        htmlId='inputHelpText'
        inputSize='small-5'
        inputHelpText='Help Text'
      />
    </div>
  );
}

**/

/**
* @name Input Disabled
* @description Inputs are useful.
*
* @category controls
* @component input
* @section disabled
*
* @js

export default function InputDisabled() {
  return (
    <div className='row'>
      <Input
        name='inputDisabled'
        label='Disabled Input'
        htmlId='inputDisabled'
        inputSize='small-5'
        value='Disabled Text'
        disabled
      />
    </div>
  );
}

**/

/**
* @name Input Read Only
* @description Inputs are useful.
*
* @category controls
* @component input
* @section read-only
*
* @js

export default function InputReadonly() {
  return (
    <div className='row'>
      <Input
        name='inputReadonly'
        label='Read Only Input'
        htmlId='inputReadonly'
        inputSize='small-5'
        value='Read Only Text'
        readOnly
      />
    </div>
  );
}

**/

/**
* @name Input Nested
* @description Inputs are useful.
*
* @category controls
* @component input
* @section nested
*
* @js

export default function InputNested() {
  return (
    <div className='row' key={'input1'}>
      <Input
        name='inputParent'
        label='Parent Input Example'
        htmlId='inputParent'
        inputSize='small-5'
      />
    </div>,
    <div className='row' key={'input2'}>
      <Input
        name='inputNested1'
        label='Child Input Nested 1 Level'
        inputSize='small-5'
        htmlId='inputNested1'
        nestedLevel={1}
      />
    </div>,
    <div className='row' key={'input3'}>
      <Input
        name='inputNested2'
        label='Child Input Nested 2 Levels'
        inputSize='small-5'
        htmlId='inputNested2'
        nestedLevel={2}
      />
    </div>,
    <div className='row' key={'input4'}>
      <Input
        name='inputNested3'
        label='Child Input Nested 3 Levels'
        inputSize='small-5'
        htmlId='inputNested3'
        nestedLevel={3}
      />
    </div>
  );
}

**/

/**
* @name Input Error (Warning)
* @description Inputs are useful.
*
* @category controls
* @component input
* @section warning
*
* @js

export default function InputError() {
  return (
    <div className='row'>
      <Input
        name='inputWarning'
        label='Error (Warning) Input'
        htmlId='inputWarning'
        inputSize='small-5'
        errorArr={ [{error: 'This is where the warning message would be.', type: 'warning'}] }
      />
    </div>
  );
}

**/

/**
* @name Input Error (Error)
* @description Inputs are useful.
*
* @category controls
* @component input
* @section error
*
* @js

export default function InputError() {
  return (
    <div className='row'>
      <Input
        name='inputError'
        label='Error (Error) Input'
        htmlId='inputError'
        inputSize='small-5'
        errorArr={ [{error: 'This is where the error message would be.', type: 'error'}] }
      />
    </div>
  );
}

**/

/**
* @name Input Error (Success)
* @description Inputs are useful.
*
* @category controls
* @component input
* @section success
*
* @js

export default function InputError() {
  return (
    <div className='row'>
      <Input
        name='inputSuccess'
        label='Error (Success) Input'
        htmlId='inputSuccess'
        inputSize='small-5'
        errorArr={ [{error: 'This is where the success message would be.', type: 'success'}] }
      />
    </div>
  );
}

**/

/**
* @name Advanced Validation
* @description Example of advanced validation.
*
* @category controls
* @component input
* @section advanced-validation
*
* @js

export default class Form extends React.PureComponent {
  constructor() {
    super();

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.validateField = this.validateField.bind(this);
    this.removeElement = this.removeElement.bind(this);
    this.retrieveState = this.retrieveState.bind(this);
    this.addElement = this.addElement.bind(this);
    this.createErrorArr = this.createErrorArr.bind(this);
  }

  state = {
    testMe: '',
    testMeError: []
  }

  handleChange(value) {
    this.setState({
      testMe: value
    });
  }

  handleSubmit(event) {
    event && event.preventDefault();
    this.validateField('testMe', this.state.testMe);
  }

  retrieveState() {
    return this.state;
  }

  addElement(array, element) {
    return array.includes(element)
    ? [...array]
    : [...array, element];
  }

  removeElement(array, element) {
    return array.filter((ele) => ele !== element);
  }

  createErrorArr(validationArr, value) {
    return validationArr.reduce((agg, e) =>
      value.match(e.test)
      ? this.removeElement(agg, e)
      : this.addElement(agg, e)
    , []);
  }

  validateField(fieldName, value, cb) {
    const rules = {
      testMe: {
        validation: [
          {
            error: 'Preferred if TestMe Field is 8 characters',
            test: '^[a-zA-Z]{8,}$',
            type: 'warning'
          },
          {
            error: 'TestMe Field is too short',
            test: '^[a-zA-Z]{6,}$',
            type: 'error'
          },
          {
            error: 'TestMe Field must contain Caps',
            test: '[A-Z]',
            type: 'error'
          },
          {
            error: 'Preferred if TestMe Field has 2 caps',
            test: '[A-Z]{2}',
            type: 'warning'
          }
        ],
        errors: this.state.testMeError
      }
    };

    return (
      this.setState({
        [`${fieldName}Error`]: this.createErrorArr(rules[fieldName].validation, value)
      },
        cb
      )
    );
  }

  render() {
    return (
      <form name='testFrom' onSubmit={this.handleSubmit}>
        <div className='row'>
          <Input
            inputSize='small-5'
            htmlId='testMe'
            value={this.state.testMe}
            name='testMe'
            label='Advanced Validation'
            onChange={this.handleChange}
            inputHelpText='Field Must contain at least 6 characters and 1 capital letter'
            errorArr={this.state.testMeError}
          />
        </div>
          {this.props.children}
      </form>
    );
  }
}

**/
Input.defaultProps = {
  onDoneEditing: null,
  onMouseDown: null,
  onFocus: null,
  onKeyDown: null,
  type: 'text',
  defaultValue: '',
  placeholder: '',
  inputHelpText: '',
  value: '',
  errorArr: [],
  children: '',
  required: false,
  inputSize: '',
  onChange: null,
  inputRef: null,
  disabled: false,
  readOnly: false,
  secondaryLabel: '',
  nestedLevel: 0,
  className: '',
  inputClassName: ''
};

module.exports = exports['default'];