import classNames from 'classnames/dedupe';
import React from 'react';

import Dropdown from '../Dropdown/Dropdown';

class FieldSelect extends React.Component {

  handleChange(selectedValue) {
    this.props.handleEvent('change',
      this.props.name, selectedValue);
  }

  hasError() {
    let {props} = this;
    let validationError = props.validationError;
    return !!(validationError && validationError[props.name]);
  }

  getDropDown(dropdownItems) {
    let {
      defaultValue,
      dropdownMenuButtonClassName,
      dropdownMenuClassName,
      dropdownMenuListClassName,
      dropdownMenuWrapperClassName,
      persistentID
    } = this.props;

    if (defaultValue == null) {
      defaultValue = dropdownItems[0];
    }

    if (typeof defaultValue === 'string'){
      defaultValue = {
        html: defaultValue,
        id: defaultValue.toLowerCase()
      };
    }

    let dropdownMenuButtonClassSet = classNames('button dropdown-toggle',
      dropdownMenuButtonClassName);
    let dropdownMenuClassSet = classNames('dropdown-menu',
      dropdownMenuClassName);
    let dropdownMenuListClassSet = classNames('dropdown-menu-list',
      dropdownMenuListClassName);
    let dropdownMenuWrapperClassSet = classNames('dropdown',
      dropdownMenuWrapperClassName);

    return (
      <Dropdown buttonClassName={dropdownMenuButtonClassSet}
        dropdownMenuClassName={dropdownMenuClassSet}
        dropdownMenuListClassName={dropdownMenuListClassSet}
        items={dropdownItems}
        onItemSelection={this.handleChange.bind(this)}
        transition={true}
        persistentID={persistentID}
        initialID={defaultValue.id}
        wrapperClassName={dropdownMenuWrapperClassSet} />
    );
  }

  getErrorMsg() {
    let errorMsg = null;
    let {props} = this;

    if (this.hasError()) {
      errorMsg = (
        <p className={props.helpBlockClass}>
          {props.validationError[props.name]}
        </p>
      );
    }

    return errorMsg;
  }

  getLabel() {
    let {label, showLabel} = this.props;

    if (!showLabel) {
      return null;
    }

    if (typeof showLabel === 'string') {
      label = showLabel;
    }

    if (typeof showLabel !== 'string' && showLabel !== true) {
      return showLabel;
    }

    return (
      <label>{label}</label>
    );
  }

  render() {
    let {
      columnWidth, formGroupClass, formElementClass, formGroupErrorClass,
      options
    } = this.props;

    options = options.map(function (option) {
      if (typeof option === 'string') {
        return {
          html: option,
          id: option.toLowerCase()
        };
      }

      return option;
    });

    let classes = classNames(
      formGroupClass,
      {
        [formGroupErrorClass]: this.hasError()
      }
    );

    let rowClass = classNames(
      `column-${columnWidth}`,
      formElementClass
    );

    return (
      <div className={rowClass}>
        <div className={classes}>
          {this.getLabel()}
          {this.getDropDown(options)}
          {this.getErrorMsg()}
        </div>
      </div>
    );
  }
}

FieldSelect.defaultProps = {
  columnWidth: 12,
  formElementClass: 'form-row-element'
};

FieldSelect.propTypes = {
  // Optional number of columns to take up of the grid
  columnWidth: React.PropTypes.number.isRequired,

  // Name of the field property
  // (usually passed down from form definition)
  name: React.PropTypes.string.isRequired,
  // Optional boolean, string, or react node.
  // If boolean: true - shows name as label; false - shows nothing.
  // If string: shows string as label.
  // If node: returns the node as the label.
  showLabel: React.PropTypes.oneOfType([
    React.PropTypes.node,
    React.PropTypes.string,
    React.PropTypes.bool
  ]),

  // Function to handle events like 'change', 'blur', 'focus', etc on the field
  // (usually passed down from form definition)
  handleEvent: React.PropTypes.func,

  // These are the options for the DropDown Component
  options: React.PropTypes.arrayOf(
    React.PropTypes.oneOfType([
      React.PropTypes.string,
      React.PropTypes.shape({
        html: React.PropTypes.string,
        id: React.PropTypes.string
      })
    ])
  ).isRequired,
  defaultValue: React.PropTypes.oneOfType([
    React.PropTypes.string,
    React.PropTypes.shape({
      html: React.PropTypes.string,
      id: React.PropTypes.string
    })
  ]),
  persisitentID: React.PropTypes.string,

  // Optional object of error messages, with key equal to field property name
  validationError: React.PropTypes.object,

  // Classes
  formGroupClass: React.PropTypes.string,
  formGroupErrorClass: React.PropTypes.string,
  helpBlockClass: React.PropTypes.string,
  formElementClass: React.PropTypes.string,

  //Classes for the Dropdown
  dropdownMenuButtonClassName: React.PropTypes.string,
  dropdownMenuListClassName: React.PropTypes.string,
  dropdownMenuClassName: React.PropTypes.string,
};

module.exports = FieldSelect;

@@ -465,23 +465,16 @@
    let %7B
-%0A      
 defaultV
@@ -482,42 +482,105 @@
 lue,
-%0A      dropdownMenuButtonClassName
+ persistentID%7D = this.props;%0A%0A    let classes = %7B%0A      buttonClassName: 'button dropdown-toggle'
 ,%0A  
@@ -596,32 +596,49 @@
 ownMenuClassName
+: 'dropdown-menu'
 ,%0A      dropdown
@@ -654,32 +654,27 @@
 lassName
-,%0A      
+: '
 dropdown
 MenuWrap
@@ -669,67 +669,312 @@
 down
-MenuWrapperClassName,%0A      persistentID%0A    %7D = this.props
+-menu-list',%0A      wrapperClassName: 'dropdown'%0A    %7D;%0A%0A    classes = Object.keys(classes)%0A      .reduce(function (classSet, className) %7B%0A        classSet%5BclassName%5D = classNames(%0A          classes%5BclassName%5D,%0A          this.props%5BclassName%5D%0A        );%0A        return classSet;%0A    %7D.bind(this), classes)
 ;%0A%0A 
@@ -1207,590 +1207,80 @@
     
-let dropdownMenuButtonClassSet = classNames('button dropdown-toggle',
+return (
 %0A      
-d
+%3CD
 ropdown
-MenuButtonClassName);%0A    let dropdownMenuClassSet = classNames('dropdown-menu',%0A      dropdownMenuClassName);%0A    let dropdownMenuListClassSet = classNames('dropdown-menu-list',%0A      dropdownMenuListClassName);%0A    let dropdownMenuWrapperClassSet = classNames('dropdown',%0A      dropdownMenuWrapperClassName);%0A%0A    return (%0A      %3CDropdown buttonClassName=%7BdropdownMenuButtonClassSet%7D%0A        dropdownMenuClassName=%7BdropdownMenuClassSet%7D%0A        dropdownMenuListClassName=%7BdropdownMenuListClassSet
+ %7B...classes%7D%0A        initialID=%7BdefaultValue.id
 %7D%0A  
@@ -1366,34 +1366,8 @@
 s)%7D%0A
-        transition=%7Btrue%7D%0A
     
@@ -1410,89 +1410,24 @@
     
-initialID=%7BdefaultValue.id%7D%0A        wrapperClassName=%7BdropdownMenuWrapperClassSet
+transition=%7Btrue
 %7D /%3E
@@ -4492,16 +4492,59 @@
 ropdown%0A
+  buttonClassName: React.PropTypes.string,%0A
   dropdo
@@ -4553,14 +4553,8 @@
 Menu
-Button
 Clas
@@ -4635,36 +4635,31 @@
 s.string,%0A  
-dropdownMenu
+wrapper
 ClassName: R
@@ -4679,17 +4679,16 @@
 s.string
-,
 %0A%7D;%0A%0Amod

Remove code repetition while generating classNames