
import classNames from 'classnames';
import extend from 'extend';
import _, { flatten, get } from 'lodash';
import React from 'react';
import PropTypes from 'prop-types';

import ClearAll from '../ClearAll';

import wrap from '../ItemContainerWrapper';
import { buildOptions, buildCustomOption, buildChickletValue } from './options';
import { fireEvents } from '../../utils';
import { ANY, SELECT_OPTION, ADD_CHICKLET } from '../../constants';

const defaultProps = {
  emptyItems: true,
  selectBehavior: ADD_CHICKLET,
  mainSelector: {
    visible: true,
    notSelectedOption: null,
    selectOption: { label: 'Select...' },
    optionGroups: [],
  },
  events: {},
  clearAll: { visible: true },
  chicklets: {
    clearAll: { visible: true },

  },
};

const propTypes = {
  theme: PropTypes.oneOfType([
    PropTypes.object,
    PropTypes.func,
  ]).isRequired,
  emptyItems: PropTypes.bool,
  onOptionSelected: PropTypes.func,
  onItemAdded: PropTypes.func,
  onClearChicklets: PropTypes.func,
  onSetChicklets: PropTypes.func,
  kdFilterModel: PropTypes.object,


  mainSelector: PropTypes.shape({
    visible: PropTypes.bool,
    notSelectedOption: PropTypes.shape({
      label: PropTypes.string,
      selected: PropTypes.bool,
    }),
    optionGroups: PropTypes.arrayOf(
      PropTypes.shape({
        label: PropTypes.string,
        options: PropTypes.arrayOf(
          PropTypes.shape({
            values: PropTypes.arrayOf(
              PropTypes.oneOfType([
                PropTypes.object,
                PropTypes.string,
              ]),
            ),
            direction: PropTypes.string,
            selected: PropTypes.bool,
          }),
        ),
      }),
    ),
  }),

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

  selectedValuesInitial: PropTypes.array,
};

class KdSelectSortOrder extends React.Component {
  constructor(props) {
    super(props);

    this.mainSelector = extend(true, {}, { visible: true }, props.mainSelector);

    this.chicklets = extend(true, {}, defaultProps.chicklets, props.chicklets);

    const { optionGroups, notSelectedOption, selectOption } = this.mainSelector;
    const options = flatten(optionGroups.map(opt => opt.options));
    this.options = buildOptions(options, notSelectedOption, selectOption);

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

  componentWillMount() {
    const selected = this.props.selectedValuesInitial;
    if (selected && selected.length) {
      const customInitialOptions = selected.map(buildCustomOption);
      const selectedChicklets = flatten(
        customInitialOptions.map(
          option => option.values.map(
            value => buildChickletValue({ option, model: this.props.kdFilterModel, value }),
          )
        )
      );

      const customOptions = _(this.props.mainSelector.optionGroups)
        .map(og => og.options)
        .flatten()
        .value();
      const chicklets = selectedChicklets.map(chicklet => ({
        ...chicklet,
        chickletLabel: get(customOptions.find(co => co.value === chicklet.value), 'label', chicklet.chickletLabel),
      }));

      this.props.onSetChicklets({ chicklets, model: this.props.kdFilterModel });
      if (this.props.isChickletNone) {
        const selectedOption = [...customInitialOptions].pop();
        this.setState({
          selectedOption,
        },
          () => this.props.onOptionSelected(selectedOption.id)
        );
      }
    } else {
      this.props.onOptionSelected(this.state.selectedOption.id);
    }
  }

  onSelectChange = ({ target }) => {
    const { kdFilterModel, events: { onChange, onSelect } } = this.props;

    let selectedOption = this.options.find(
      option => option.id === target.value,
    );

    if (selectedOption.id === ANY) {
      this.props.onClearChicklets();
    } else if (selectedOption.id !== SELECT_OPTION) {
      selectedOption.values.forEach(
        (value) => {
          const item = buildChickletValue({
            option: selectedOption,
            model: kdFilterModel,
            value,
          });
          const callback = () => {
            const data = {
              model: kdFilterModel,
              values: { ...kdFilterModel.getSortOrderModelValue() },
            };
            onChange && onChange({ data });
          };
          this.props.onItemAdded(item, callback);
        }
      );
      if (!this.props.isChickletNone) {
        selectedOption = this.options.find(
          option => option.id === SELECT_OPTION,
        ) || selectedOption;
      }
    }
    this.setState({
      selectedOption,
    }, () => {
      this.props.onOptionSelected(selectedOption.id);
      const event = {
        label: selectedOption.displayName,
        value: selectedOption.id,
        direction: selectedOption.direction,
      };

      fireEvents([onSelect], event);
    });
  }

  render() {
    const { theme } = this.props;
    return (
      <div
        className={
          classNames(
            'infront',
            'ofd-select-sort-order',
            theme.infront,
            theme['ofd-select-sort-order'],
          )
        }
      >
        <div className={classNames('c-base-select', theme['c-base-select'])}>
          <select onChange={this.onSelectChange} value={this.state.selectedOption.id}>
            {
              this.options.map(option =>
                (
                  <option value={option.id} key={option.id}>{option.displayName}</option>
                ),
              )
            }
          </select>
        </div>
        {
          !this.props.emptyItems &&
            !this.props.isChickletNone &&
              this.chicklets.clearAll.visible &&
              <ClearAll theme={theme} onClick={this.props.onClearChicklets} />
        }
      </div>
    );
  }
}

KdSelectSortOrder.propTypes = propTypes;
KdSelectSortOrder.defaultProps = defaultProps;

export default wrap(KdSelectSortOrder);
