import { intersectionWith } from 'lodash-es';
import PropTypes from 'prop-types';
import React from 'react';
import CreatableSelect from 'react-select/lib/Creatable';
import UI from '../../../config/ui/config';

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

    this.onChange = this.onChange.bind(this);
    this.getCustomStyles = this.getCustomStyles.bind(this);
  }
  render() {
    const options = this.props.availableTags
      ? this.props.availableTags.map((tag) => ({
          value: tag._id,
          label: tag.name,
        }))
      : [];
    const value = this.props.selectedTags
      ? this.props.selectedTags.map((tag) => ({
          value: tag._id,
          label: tag.name,
        }))
      : [];

    return (
      <CreatableSelect
        formatCreateLabel={(inputValue) =>
          `Create "${inputValue.toLowerCase()}"`
        }
        isMulti
        isLoading={this.props.isFetching}
        menuPlacement="top"
        noOptionsMessage={() => 'No existing tag'}
        onChange={this.onChange}
        onMenuOpen={this.props.getTags}
        options={options}
        styles={this.getCustomStyles()}
        value={value}
      />
    );
  }

  /**
   * Callback function triggered when the input has changed.
   */
  onChange(option, action) {
    if (option && action) {
      if (action.action === 'create-option') {
        const newTag = {
          color: UI.logbook.DEFAULT_TAG_COLOR,
          description: null,
          name: option[option.length - 1].label,
        };

        this.props.onTagCreatedinWidget(newTag);
      } else if (
        action.action === 'select-option' ||
        action.action === 'remove-value'
      ) {
        this.props.onTagSelectedInWidget(
          intersectionWith(
            this.props.availableTags,
            option,
            (availableTag, optionItem) => availableTag.name === optionItem.label
          )
        );
      }
    }
  }

  /**
   * Get the curstom styles used for the creqtqbleSelect component
   */
  getCustomStyles() {
    return {
      dropdownIndicator: (provided) => ({ ...provided, padding: 1 }),
      clearIndicator: (provided) => ({ ...provided, padding: 1 }),
      control: (provided) => ({ ...provided, minHeight: 25 }),
      valueContainer: (provided) => ({
        ...provided,
        paddingTop: 0,
        paddingBottom: 0,
      }),
    };
  }
}

TagSelector.propTypes = {
  /** list of available tags */
  availableTags: PropTypes.array.isRequired,
  /** callback function triggered when a tag is created in the select element */
  onTagCreatedinWidget: PropTypes.func,
  /** Callback funnction triggered when a tag is selected in the select element */
  onTagSelectedInWidget: PropTypes.func,
  /* list of selected tags */
  selectedTags: PropTypes.array,
};

export default TagSelector;
