import axios from 'axios';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import {
  createTagsByInvestigationId,
  getTagsByInvestigationId,
} from '../../../api/icat/icatPlus';
import TagSelector from '../../../components/Logbook/Tag/TagSelector';

class TagsSelectorContainer extends Component {
  constructor(props) {
    super(props);

    this.state = {
      availableTags: this.props.tags, //at initialization we know only the tags which where selected. Not all available tags.
      selectedTags: this.props.tags,
      isFetched: false,
      isFetching: false,
      errorMessage: null,
    };

    this.setSelectedTags = this.setSelectedTags.bind(this);
    this.getTags = this.getTags.bind(this);
    this.onTagCreatedinWidget = this.onTagCreatedinWidget.bind(this);
  }

  render() {
    return (
      <TagSelector
        availableTags={this.state.availableTags}
        selectedTags={this.state.selectedTags}
        onTagCreatedinWidget={this.onTagCreatedinWidget}
        onTagSelectedInWidget={this.setSelectedTags}
        getTags={this.getTags}
        isFetching={this.state.isFetching}
      />
    );
  }

  componentDidMount() {
    this.props.onChange(this.state.selectedTags);
  }

  onTagCreatedinWidget(newTag) {
    this.createTag(newTag).then((newlyCreatedTag) => {
      const selectedTags = [...this.state.selectedTags, newlyCreatedTag];
      this.setState({ selectedTags });
      this.props.onChange(selectedTags);
    });
  }

  /** Set selected tags
   * @param {*} selectedTags all currently selected tags
   */
  setSelectedTags(selectedTags) {
    this.setState({ selectedTags });
    this.props.onChange(selectedTags);
  }

  /**
   * Get available tags
   */
  getTags() {
    if (this.props.investigationId && this.props.user.sessionId) {
      this.setState({ isFetching: true, errorMessage: null });
      axios({
        method: 'get',
        url: getTagsByInvestigationId(
          this.props.user.sessionId,
          this.props.investigationId
        ),
      })
        .then((data) =>
          this.setState({
            availableTags: data.data.tags,
            isFetching: false,
            isFetched: true,
          })
        )
        .catch((error) => {
          console.log(
            `ERROR] An error occured while retrieving the tag list. The error is ${error}`
          );
          this.setState({
            errorMessage: 'An error occured while retrieving the tag list.',
          });
        });
    } else {
      console.log('[ERROR] Missing props in AvailableTagsContainer');
      this.setState({
        availableTags: [],
        isFetching: false,
        isFetched: true,
        errorMessage: null,
      });
    }
  }

  /** Creates an investigation tag on the server
   * @param {object} newTag new tag created on the widget
   */
  createTag(newTag) {
    if (newTag) {
      return new Promise((resolve, reject) => {
        axios({
          method: 'post',
          url: createTagsByInvestigationId(
            this.props.user.sessionId,
            this.props.investigationId
          ),
          data: { ...newTag, investigationId: this.props.investigationId },
        })
          .then((data) => resolve(data.data))
          .catch(() => {
            reject();
            console.log('createTag promise was rejected');
            //this.setMessage(ERROR_MESSAGE_TYPE, parseHTTPError(error), nextContext);
          });
      });
    }
  }
}

/**
 * Redux related function which is used to map local props with redux state
 * @param {*} state redux state
 */
function mapStateToProps(state) {
  return {
    user: state.user,
  };
}

TagsSelectorContainer.propTypes = {
  /* investigation identifier */
  investigationId: PropTypes.string.isRequired,
  /* function triggered when the tag selection has changed. Currently selected tags are argument of this function */
  onChange: PropTypes.func,
  /* Tags initially selected */
  tags: PropTypes.array,
  /* user details (redux props) */
  user: PropTypes.object.isRequired,
};

export default connect(mapStateToProps)(TagsSelectorContainer);
