import React, { PropTypes } from 'react';
import classNames from 'classnames';
import moment from 'moment';
import extend from 'extend';
import options, { defaultOptions, isValidOption, buildCustomOption  } from './options';
import BaseSelect from '../BaseSelect';
import KdSelectString from '../KdSelectString';
import wrap from '../ItemContainerWrapper';

import { ADD_CHICKLET, CHICKLET_ORANGE, USER_SPECIFIED_OPTION } from '../../constants';

const optionRegex = /^mainSelectorOptions(.+)IsVisible$/;

const defaultProps = {
  chickletsContainerShouldRender: true,
  chickletsClearAllLinkIsVisible: true,
  chickletsContainerRenderAsSortable: false,
  chickletsRenderAscDescButton: false,
  selectedValuesInitial: [],
  selectBehavior: ADD_CHICKLET,
  isDisabled: false,
  mainSelector: {
    visible: false,
    selected: '',
    optionValues: {
      anyOption: {
        visible: true,
      },
      customOptions: [],
      userSpecifiedOption: {
        visible: true,
      },
    }
  },
  events: {},
  autoComplete: {
    clearTextboxOnSelection: true,
    renderClearTextboxButton: true,
  }
};

const propTypes = {
  selectBehavior: PropTypes.string,
  kdFilterModel: PropTypes.object.isRequired,

  api: PropTypes.shape({
    url: PropTypes.string.isRequired,
    key: PropTypes.string.isRequired,
  }),

  events: PropTypes.shape({
    onSelect: PropTypes.func,
    onChange: PropTypes.func,
  }),

  mainSelector: PropTypes.shape({
    visible: PropTypes.bool,
    selected: PropTypes.string,

    optionValues: PropTypes.shape({
      selectOption: PropTypes.shape({
        visible: PropTypes.bool,
        label: PropTypes.string,
      }),
      anyOption: PropTypes.shape({
        visible: PropTypes.bool,
        label: PropTypes.string,
      }),
      customOptions: PropTypes.array,
      userSpecifiedOption: PropTypes.shape({
        visible: PropTypes.bool,
        label: PropTypes.string,
      }),
    })
  }),

  autoComplete: PropTypes.shape({
    onSuccess: PropTypes.func,
    onRender: PropTypes.func,
    onSelect: PropTypes.func,
    onFail: PropTypes.func,
    onDone: PropTypes.func,
    placeholderText: PropTypes.string,
    clearTextboxOnSelection: PropTypes.bool,
    renderClearTextboxButton: PropTypes.bool,
  }),

  // Chicklets Props (before rename)
  selectedValuesInitial: PropTypes.array,
  chickletsContainerShouldRender: PropTypes.bool,
  chickletsClearAllLinkIsVisible: PropTypes.bool,
  chickletsEventOnClick: PropTypes.func,
  chickletsRenderInfoButton: PropTypes.bool,
  chickletsContainerRenderAsSortable: PropTypes.bool,
  chickletsRenderAscDescButton: PropTypes.bool,
};

class KdSelectDropDown extends React.Component {

  constructor(props) {
    super(props);

    this.mainSelector = extend(true, {}, defaultProps.mainSelector, this.props.mainSelector);
    this.options = this.propBasedOptions();

    this.onSelectChange = this.onSelectChange.bind(this);
    this.addItem = this.addItem.bind(this);
    this.isInputVisible = this.isInputVisible.bind(this);

    this.state = {
      selectedOption: this.options[0],
      selectedValue: ''
    };
  }

  componentDidMount() {
    this.props.onOptionSelected(this.state.selectedOption.id);

    this.props.selectedValuesInitial.forEach(({ value, label })=> {
      const relatedOption = this.options.find(option => option.key === value);

      if (relatedOption) {
        relatedOption.selected = { value, label, option: value };
        this.props.onItemAdded(relatedOption.selected);
        if (this.props.isChickletNone) {
          this.setState({
            selectedOption: relatedOption,
            selectedValue: relatedOption.selectedLabel,
          }, () => this.props.onOptionSelected(this.state.selectedOption.id));
        }
      }
    });
  }

  propBasedOptions() {
    if (!this.mainSelector.visible) {
      return [options.create('Search')];
    }

    let optionSet = new Set(defaultOptions);

    for (let prop in this.props) {
      if (this.props.hasOwnProperty(prop) && prop.match(optionRegex)) {
        const optionEnabled = this.props[prop];
        const optionKey = prop.match(optionRegex)[1];

        optionEnabled && isValidOption(optionKey) ? optionSet.add(optionKey) : optionSet.delete(optionKey);
      }
    }
    return Array.from(optionSet)
      .map(type => options.create(type))
      .concat(this.mainSelector.optionValues.customOptions.map(buildCustomOption));
  }

  isInputVisible() {
    return (this.state.selectedOption.id === USER_SPECIFIED_OPTION)
  }

  onSelectChange({ target }) {
    const selectedOption = this.options.find(option => option.id === target.value);
    if (selectedOption.loadDefaultValue()) {
      this.props.onItemAdded(selectedOption.selected);
    }

    this.setState({
      selectedOption,
      selectedValue: selectedOption.selectedLabel,
    }, () => this.props.onOptionSelected(this.state.selectedOption.id));
  }

  addItem(value) {
    const remove = this.props.isChickletNone &&
      this.kdSelectString.setInputValue.bind(this.kdSelectString);
    this.props.onItemAdded({
      value,
      chickletLabel: value,
      option: value,
      remove: remove,
      inputVisible: this.isInputVisible(),
    });
  }

  optionHelper() {
    switch (this.state.selectedOption.id) {
      case USER_SPECIFIED_OPTION:
        return (
          <KdSelectString
            ref={ref => this.kdSelectString = ref}
            addItem={this.addItem}
            isChickletNone={this.props.isChickletNone}
          />
        );
      default:
        return null;
    }
  }

  render() {
    return(
      <div className={classNames({'u-disabled': this.props.isDisabled})}>
        {this.props.mainSelector.visible &&
          <BaseSelect options={this.options}
                      onChange={this.onSelectChange}
                      defaultValue={this.state.selectedOption.id} />}
        {this.optionHelper()}
      </div>
    );
  }

}

KdSelectDropDown.defaultProps = defaultProps;
KdSelectDropDown.propTypes = propTypes;

export default wrap(KdSelectDropDown);
