import axios from 'axios';
import PropTypes from 'prop-types';
import React from 'react';
import { connect } from 'react-redux';
import { setLogbookContextAction } from '../../actions/logbook';
import {
  createEvent as createEventURL,
  getEventCountByInvestigationId,
  getEventsByInvestigationId,
  updateEvent as updateEventURL,
} from '../../api/icat/icatPlus';
import Loader from '../../components/Loader';
import EventList from '../../components/Logbook/List/EventList';
import EventListMenu from '../../components/Logbook/Menu/EventListMenu';
import NewOrEditEventPanel from '../../components/Logbook/NewOrEditEventPanel';
import OverlayBox from '../../components/Logbook/OverlayBox';
import PublicEventPanel from '../../components/Logbook/PublicEventPanel';
import UserMessage from '../../components/UserMessage';
import UI from '../../config/ui/config';
import {
  ERROR_MESSAGE_TYPE,
  INFO_MESSAGE_TYPE,
  LIST_VIEW,
  LOGBOOK_CONTEXT_NAME_PROPOSAL,
  NEW_EVENT_INVISIBLE,
  NEW_EVENT_VISIBLE,
} from '../../constants/eventTypes';
import { getSortingOrder, parseHTTPError } from '../../helpers/eventHelpers';
import {
  convertPageToPageEventIndexes,
  isRangeAvailableOnTheClient,
} from '../../helpers/paginationHelpers';
import PeriodicRefresher from './PeriodicRefresher';
import {
  getSelectionFiltersBySearchCriteria,
  getSelectionFiltersForMongoQuery,
} from './SelectionFilterHelper';

/**
 * This class represents the event container component. It's role is to retrieve events from the server asynchronuously.
 * Also, it is connected to redux and retrieves user data and sessionId.
 */
class LogbookContainer extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      activePage: 1,
      eventCountBySelectionFilter: 0, // count of events for the current selection filter found in the logbook since last refresh
      allEventsCountAtLastRefresh: 0, // count of all events found in the logbook since last refresh

      downloadedEvents: [], //events already downloaded
      pageEvents: [], // events currently displayed on the page
      downloadedEventIndexes: { start: 0 },

      errorMessage: '',
      fetchingEventList: true,
      fetchedEventList: false,
      fetchingEventCount: true,
      fetchedEventCount: false,

      event: null, // event being edited
      isNewEventPanelVisible: false,
      isShowingEditEventUI: false,
      isShowingPublicEventUI: false,

      autorefresh: {
        isEnabled: UI.logbook.AUTOREFRESH_EVENTLIST,
        isFetchingEvents: false,
        isFetchingEventCount: false,
        isLockingRefresh: false, // prevent EventList refresh even if isEnabled is true
      },

      sortingFilter: { [UI.logbook.SORT_EVENTS_BY]: UI.logbook.SORTING_ORDER }, // current sorting flter
      searchCriteria: [],
      view: LIST_VIEW,
    };

    this.createEvent = this.createEvent.bind(this);
    this.getAllEventsAndRefresh = this.getAllEventsAndRefresh.bind(this);
    this.getEventsBySelectionFilter = this.getEventsBySelectionFilter.bind(
      this
    );
    this.getEventCountBySelectionFilter = this.getEventCountBySelectionFilter.bind(
      this
    );
    this.isAppProperlyConfigured = this.isAppProperlyConfigured.bind(this);
    this.onCancelButtonClicked = this.onCancelButtonClicked.bind(this);
    this.onCloseButtonClicked = this.onCloseButtonClicked.bind(this);
    this.onEventCountReceptionFailure = this.onEventCountReceptionFailure.bind(
      this
    );
    this.onEventClicked = this.onEventClicked.bind(this);
    this.onNewEventCountReceived = this.onNewEventCountReceived.bind(this);
    this.onPageClicked = this.onPageClicked.bind(this);
    this.onSaveButtonClicked = this.onSaveButtonClicked.bind(this);
    this.flipEventsSortingOrder = this.flipEventsSortingOrder.bind(this);
    this.searchEvents = this.searchEvents.bind(this);
    this.setNewEventVisibility = this.setNewEventVisibility.bind(this);
    this.setView = this.setView.bind(this);
  }

  render() {
    const { investigationId, user } = this.props;

    if (this.isAppProperlyConfigured()) {
      return (
        <div style={{ marginBottom: 40 }}>
          <OverlayBox
            open={!!this.state.errorMessage}
            onClose={() => {
              this.setState({ errorMessage: null });
            }}
            classNames={{
              modal: 'userMessageModalClass',
              closeButton: 'userMessageCloseButton',
            }}
          >
            {this.state.errorMessage && (
              <UserMessage
                type={ERROR_MESSAGE_TYPE}
                message={this.state.errorMessage}
              />
            )}
          </OverlayBox>

          <PeriodicRefresher
            initialValue={0}
            intervalInMilliSeconds={UI.logbook.AUTOREFRESH_DELAY}
            isEnabled
            onCallbackSuccess={this.onNewEventCountReceived}
            periodicCallback={(onSuccess, onFailure) => {
              this.getEventCountBySelectionFilter(
                getSelectionFiltersBySearchCriteria(
                  this.state.searchCriteria,
                  LIST_VIEW
                )
              ).then(
                (eventCount) => onSuccess(eventCount),
                (error) => onFailure(error)
              );
            }}
          >
            <EventListMenu
              activePage={this.state.activePage}
              autorefreshEventList={this.state.autorefresh.isEnabled}
              //availableTags={this.props.availableTags}
              eventCountBySelectionFilter={
                this.state.eventCountBySelectionFilter
              }
              eventCountSinceLastRefresh={
                this.state.allEventsCountAtLastRefresh
              }
              getEvents={this.getAllEventsAndRefresh}
              investigationId={investigationId}
              isNewButtonEnabled={!this.state.isNewEventPanelVisible}
              isSortingLatestEventsFirst={
                getSortingOrder(this.state.sortingFilter) === -1 ? true : false
              }
              logbookContext={this.props.logbookContext}
              onPageClicked={this.onPageClicked}
              onRefreshEventListMenuItemClicked={() =>
                this.setState({
                  autorefresh: {
                    ...this.state.autorefresh,
                    isEnabled: !this.state.autorefresh.isEnabled,
                  },
                })
              }
              onSortingButtonClicked={this.flipEventsSortingOrder}
              searchEvents={this.searchEvents}
              selectionFilter={getSelectionFiltersForMongoQuery(
                this.state.searchCriteria,
                this.state.sortingFilter,
                this.state.view
              )}
              sessionId={user.sessionId}
              setNewEventVisibility={this.setNewEventVisibility}
              setView={this.setView}
              view={this.state.view}
            />
          </PeriodicRefresher>

          <OverlayBox
            open={
              this.state.isNewEventPanelVisible ||
              this.state.isShowingEditEventUI ||
              this.state.isShowingPublicEventUI
            }
            classNames={{
              overlay: 'newOrEditOverlayClass',
              modal: 'newOrEditModalClass',
            }}
          >
            {this.state.isNewEventPanelVisible && (
              <div
                style={{
                  height: this.getPanelHeightInPercent(),
                  paddingBottom: this.state.isShowingEditEventUI ? 5 : 0,
                }}
              >
                <NewOrEditEventPanel
                  investigationId={investigationId}
                  onCancelButtonClicked={this.onCancelButtonClicked}
                  onSaveButtonClicked={this.onSaveButtonClicked}
                  user={user}
                />
              </div>
            )}

            {this.props.logbookContext.isReleased ? (
              <div style={{ height: '100%', paddingBottom: 0 }}>
                <PublicEventPanel
                  event={this.state.event}
                  onCloseButtonClicked={this.onCloseButtonClicked}
                />
              </div>
            ) : (
              this.state.isShowingEditEventUI && (
                <div
                  style={{
                    height: this.getPanelHeightInPercent(),
                    paddingBottom: this.state.isNewEventPanelVisible ? 5 : 0,
                  }}
                >
                  <NewOrEditEventPanel
                    event={this.state.event}
                    investigationId={investigationId}
                    onCancelButtonClicked={this.onCancelButtonClicked}
                    onSaveButtonClicked={this.onSaveButtonClicked}
                    user={user}
                  />
                </div>
              )
            )}
          </OverlayBox>

          {!this.state.fetchedEventList && this.state.fetchingEventList && (
            <Loader message="Loading logbook..." />
          )}

          {this.state.fetchedEventList && (
            <div>
              {this.state.pageEvents.length === 0 ? (
                <UserMessage
                  message="The logbook is empty."
                  type={INFO_MESSAGE_TYPE}
                  isTextCentered
                />
              ) : (
                <EventList
                  activePage={this.state.activePage}
                  events={this.state.pageEvents}
                  eventCountBySelectionFilter={
                    this.state.eventCountBySelectionFilter
                  }
                  logbookContext={this.props.logbookContext}
                  onEventClicked={this.onEventClicked}
                  onPageClicked={this.onPageClicked}
                />
              )}
            </div>
          )}
        </div>
      );
    }
    return (
      <div style={{ marginBottom: 40 }}>
        <UserMessage
          type={ERROR_MESSAGE_TYPE}
          message={
            'Sorry, the application is not properly configured for wall-eLog. Can not start. Check the console.'
          }
        />
      </div>
    );
  }

  /**
   * Executed the first time the component is mounted
   */
  componentDidMount() {
    this.getAllEventsAndRefresh(this.state.view);

    const isCurrentProposalReleased = () => {
      const _this = this;
      return (
        this.props.releasedInvestigations.find(
          (releasedInvestigation) =>
            String(releasedInvestigation.id) === _this.props.investigationId
        ) !== undefined
      );
    };

    this.props.setLogbookContext({
      name: LOGBOOK_CONTEXT_NAME_PROPOSAL,
      isReleased: isCurrentProposalReleased(),
    });
  }

  /** Get the height percentage value for the panels for new and edition of an event */
  getPanelHeightInPercent() {
    return this.state.isNewEventPanelVisible && this.state.isShowingEditEventUI
      ? '50%'
      : '100%';
  }

  /**
   * Callback function triggered when event count retreval failed
   * @param {*} error
   * @param {String} event counter to reset
   */
  onEventCountReceptionFailure(error, eventCounterToReset) {
    this.setState({
      errorMessage: parseHTTPError(error),
      [eventCounterToReset]: 0,
      fetchingEventCount: false,
    });
  }

  onEventClicked(event) {
    if (this.state.isShowingEditEventUI && this.state.event !== event) {
      this.setState({
        errorMessage:
          'Action refused. Please save or cancel the log which is currently being edited.',
      });
    }

    if (this.props.logbookContext.isReleased) {
      this.setState({ event, isShowingPublicEventUI: true });
    } else {
      this.setState({ event, isShowingEditEventUI: true });
    }
  }

  /**
   * Function triggered periodically by the periodicRefresher
   * @param {object} eventCount event count received from the periodic refresher
   */
  onNewEventCountReceived() {
    if (this.state.autorefresh.isEnabled) {
      if (!this.state.autorefresh.isFetchingEvents) {
        this.setState({
          autorefresh: { ...this.state.autorefresh, isFetchingEvents: true },
        });

        this.getEventsBySelectionFilter(
          this.state.downloadedEventIndexes.start,
          getSelectionFiltersBySearchCriteria(
            this.state.searchCriteria,
            this.state.view
          ),
          this.state.sortingFilter
        ).then(
          (events) => {
            this.setState({
              autorefresh: {
                ...this.state.autorefresh,
                isFetchingEvents: false,
              },
            });
            if (this.state.autorefresh.isLockingRefresh) {
              console.log(
                'Event list not refreshed automatically because a user triggered request occured in the mean time'
              );
            } else {
              this.refreshEventList(
                events,
                this.state.downloadedEventIndexes.start,
                getSelectionFiltersBySearchCriteria(
                  this.state.searchCriteria,
                  this.state.view
                ),
                this.state.sortingFilter
              );
            }
            this.setState({
              autorefresh: {
                ...this.state.autorefresh,
                isLockingRefresh: false,
              },
            });
          },
          () => {
            this.setState({
              autorefresh: {
                ...this.state.autorefresh,
                isFetchingEvents: false,
              },
            });
          }
        );
      }

      if (!this.state.autorefresh.isFetchingEventCount) {
        this.setState({
          autorefresh: {
            ...this.state.autorefresh,
            isFetchingEventCount: true,
          },
        });
        this.getEventCountBySelectionFilter(
          getSelectionFiltersBySearchCriteria(
            this.state.searchCriteria,
            this.state.view
          )
        ).then(
          (eventCount) => {
            this.setState({
              eventCountBySelectionFilter: parseInt(eventCount, 10),
              autorefresh: {
                ...this.state.autorefresh,
                isFetchingEventCount: false,
              },
            });
          },
          () => {
            this.setState({
              autorefresh: {
                ...this.state.autorefresh,
                isFetchingEventCount: false,
              },
            });
          }
        );
      }
    }
  }

  /**
   * Refresh the event list
   * @param {*} downloadedEvents events which have been downloaded
   * @param {*} offset offset used for getting downloadedEvents
   * @param {*} selectionFilter
   * @param {*} sortingFilter
   */
  refreshEventList(downloadedEvents, offset, selectionFilter, sortingFilter) {
    const pageEventIndexes = convertPageToPageEventIndexes(
      this.state.activePage,
      UI.logbook.EVENTS_PER_PAGE,
      downloadedEvents
    );

    this.setState({
      activePage: this.state.activePage,
      downloadedEvents,
      downloadedEventIndexes: {
        start: offset,
        end: offset + downloadedEvents.length - 1,
      },
      fetchedEventList: true,
      pageEvents: downloadedEvents.slice(
        pageEventIndexes.start - offset,
        pageEventIndexes.end - offset + 1
      ),
      selectionFilter,
      sortingFilter,
    });
  }

  /**
   * Function triggered when the user clicks on a page
   * @param {integer} page the page the user has clicked
   */
  onPageClicked(page) {
    if (page) {
      page = page.selected + 1;
      const pageEventIndexes = convertPageToPageEventIndexes(
        page,
        UI.logbook.EVENTS_PER_PAGE,
        this.state.eventCountBySelectionFilter
      );
      const areEventsAlreadyDownloaded = isRangeAvailableOnTheClient(
        pageEventIndexes,
        this.state.downloadedEventIndexes
      );

      if (areEventsAlreadyDownloaded) {
        this.setState({
          pageEvents: this.state.downloadedEvents.slice(
            pageEventIndexes.start - this.state.downloadedEventIndexes.start,
            pageEventIndexes.end - this.state.downloadedEventIndexes.start + 1
          ),
        });
      } else {
        this.getEventsBySelectionFilter(
          pageEventIndexes.start,
          getSelectionFiltersBySearchCriteria(
            this.state.searchCriteria,
            this.state.view
          ),
          this.state.sortingFilter
        ).then((events) => {
          this.refreshEventList(
            events,
            pageEventIndexes.start,
            getSelectionFiltersBySearchCriteria(
              this.state.searchCriteria,
              this.state.view
            ),
            this.state.sortingFilter
          );
        });
      }
      this.setState({ activePage: page });
    }
  }

  /** Callback function triggered when the user starts a new search
   * @param {Array} searchCriteria the search criteria as provided by the search component
   */
  searchEvents(searchCriteria) {
    this.setState({ searchCriteria });

    this.getEventsBySelectionFilter(
      0,
      getSelectionFiltersBySearchCriteria(searchCriteria, this.state.view),
      this.state.sortingFilter
    ).then((events) => {
      if (this.state.autorefresh.isFetchingEvents) {
        this.setState({
          autorefresh: { ...this.state.autorefresh, isLockingRefresh: true },
        });
      }
      this.refreshEventList(
        events,
        0,
        getSelectionFiltersBySearchCriteria(searchCriteria, this.state.view),
        this.state.sortingFilter
      );
    });

    this.getEventCountBySelectionFilter(
      getSelectionFiltersBySearchCriteria(searchCriteria, this.state.view)
    ).then((eventCount) => {
      this.setState({ eventCountBySelectionFilter: parseInt(eventCount, 10) });
    });
  }

  /**
   * Function triggered when the user hits the cancel button during event creation or edition
   */
  onCancelButtonClicked() {
    if (this.state.event) {
      // editing an event
      this.setState({ isShowingEditEventUI: false });
    } else {
      // creating an event
      this.setState({ isNewEventPanelVisible: false });
    }
  }

  /**
   * Set the visibility of the new event panel
   * @param {string} visibility the requested visibility
   */
  setNewEventVisibility(visibility) {
    if (visibility) {
      if (visibility === NEW_EVENT_VISIBLE) {
        this.setState({ isNewEventPanelVisible: true });
      } else if (visibility === NEW_EVENT_INVISIBLE) {
        this.setState({ isNewEventPanelVisible: false });
      }
    }
  }

  /**
   * Function triggered when the user clicks on the close button while view a public event
   */
  onCloseButtonClicked() {
    this.setState({ isShowingPublicEventUI: false });
  }

  /**
   * Change the current view to the requested view
   * @param {string} view the requested view
   */
  setView(view) {
    if (view && view !== this.state.view) {
      this.getAllEventsAndRefresh(view);
    }
    this.setState({ view });
  }

  /**
   * Callback function which reverses the sorting order of events
   */
  flipEventsSortingOrder() {
    const newSortingFilter = { ...this.state.sortingFilter };
    newSortingFilter[Object.keys(this.state.sortingFilter)[0]] =
      getSortingOrder(this.state.sortingFilter) * -1;

    this.getEventsBySelectionFilter(
      0,
      getSelectionFiltersBySearchCriteria(
        this.state.searchCriteria,
        this.state.view
      ),
      newSortingFilter
    ).then((events) => {
      if (this.state.autorefresh.isFetchingEvents) {
        this.setState({
          autorefresh: { ...this.state.autorefresh, isLockingRefresh: true },
        });
      }
      this.refreshEventList(
        events,
        0,
        getSelectionFiltersBySearchCriteria(
          this.state.searchCriteria,
          this.state.view
        ),
        newSortingFilter
      );
    });

    this.getEventCountBySelectionFilter(
      getSelectionFiltersBySearchCriteria(
        this.state.searchCriteria,
        this.state.view
      )
    ).then((eventCount) => {
      this.setState({ eventCountBySelectionFilter: parseInt(eventCount, 10) });
    });
  }

  /**
   * Get events
   * @param {integer} offset the offset of events
   * @param {Object} selectionFilter selection filter in mongodb format
   * @param {object} sortingFilter the sorting filter to use , optional
   * @param {bool} useLimit if false, the limit property is not used in the request. True by default.
   */
  getEventsBySelectionFilter(
    offset,
    selectionFilter,
    sortingFilter,
    useLimit = true
  ) {
    const { investigationId, user } = this.props;
    sortingFilter = sortingFilter || {
      [UI.logbook.SORT_EVENTS_BY]: UI.logbook.SORTING_ORDER,
    };
    if (!selectionFilter) {
      // there is not selectionfilter as parameter when the user has clicked on a page
      selectionFilter = getSelectionFiltersBySearchCriteria(
        this.state.searchCriteria,
        this.state.view
      );
    }

    if (investigationId && user.sessionId) {
      return new Promise((resolve, reject) =>
        axios({
          method: 'post',
          url: getEventsByInvestigationId(user.sessionId, investigationId),
          data: {
            find: selectionFilter,
            sort: sortingFilter,
            limit: useLimit ? UI.logbook.EVENTS_PER_DOWNLOAD : null,
            skip: offset,
          },
        }).then(
          (data) => {
            resolve(data.data);
          },
          (error) => {
            console.log(
              '[ERROR] An error occured while retrieving the event list.'
            );
            reject(error);
          }
        )
      );
    }
    //onError('[ERROR] Missing query parameters in the request handled by getEventsByInvestigationId()');
  }

  getAllEventsAndRefresh(view) {
    this.getEventsBySelectionFilter(
      0,
      getSelectionFiltersBySearchCriteria([], view),
      this.state.sortingFilter
    ).then((events) =>
      this.refreshEventList(
        events,
        0,
        getSelectionFiltersBySearchCriteria([], view),
        this.state.sortingFilter
      )
    );

    this.getEventCountBySelectionFilter(
      getSelectionFiltersBySearchCriteria([], view)
    ).then((eventCount) => {
      this.setState({
        allEventsCountAtLastRefresh: parseInt(eventCount, 10),
        eventCountBySelectionFilter: parseInt(eventCount, 10),
      });
    });
  }

  /**
   * Get event count by selection filter
   * @param {object} selectionFilter the selection filter used to know which events of the logbook need to be counted
   */
  getEventCountBySelectionFilter(selectionFilter) {
    const { investigationId, user } = this.props;

    this.setState({ fetchingEventCount: true });

    if (investigationId && user.sessionId) {
      return new Promise((resolve, reject) =>
        axios({
          method: 'post',
          url: getEventCountByInvestigationId(user.sessionId, investigationId),
          data: { find: selectionFilter },
        }).then(
          (data) => {
            this.setState({ fetchedEventCount: true });
            resolve(data.data);
          },
          (error) => {
            console.log(
              '[ERROR] An error occurred while retrieving the event count.'
            );
            reject(error);
          }
        )
      );
    }
    //onError('[ERROR] Missing query parameters in the request handled by getEventCountByInvestigationId()');
  }

  /**
   * Update the event on ICAT+ server
   * @param {*} event event object to be updated
   */
  updateEvent(event) {
    return new Promise((resolve) =>
      axios({
        method: 'put',
        url: updateEventURL(
          this.props.user.sessionId,
          this.props.investigationId
        ),
        data: { event },
      })
        .then((response) => {
          console.log('the event was modified successfully on ICAT+ server.');
          resolve(response.data);
        })
        .catch((error) => {
          this.setState({ errorMessage: parseHTTPError(error) });
        })
    );
  }

  /**
   * Create the event
   * @param {*} newEvent event object to be created
   */
  createEvent(newEvent) {
    return new Promise((resolve) =>
      axios({
        method: 'post',
        url: createEventURL(
          this.props.user.sessionId,
          this.props.investigationId
        ),
        data: newEvent,
      })
        .then(() => {
          console.log(
            'The new event was created successfully on ICAT+ server.'
          );
          resolve();
        })
        .catch((error) => {
          this.setState({ errorMessage: parseHTTPError(error) });
        })
    );
  }

  /**
   * Function triggered when the user hits the save button to create or edit an event
   * @param {*} event event to be created or updated
   */
  onSaveButtonClicked(event) {
    if (this.state.event) {
      //editing an event
      this.updateEvent(event).then((updatedEvent) => {
        const copyPageEvents = this.state.pageEvents.map((event) => event);
        const foundIndex1 = copyPageEvents.findIndex(
          (event) => event._id === updatedEvent._id
        );
        copyPageEvents.splice(foundIndex1, 1, updatedEvent);

        const copyDownloadedEvents = this.state.downloadedEvents.map(
          (event) => event
        );
        const foundIndex2 = copyDownloadedEvents.findIndex(
          (event) => event._id === updatedEvent._id
        );
        copyDownloadedEvents.splice(foundIndex2, 1, updatedEvent);

        this.setState({
          downloadedEvents: copyDownloadedEvents,
          pageEvents: copyPageEvents,
          event: null,
          isShowingEditEventUI: false,
        });
      });
    } else {
      // creating an event
      this.createEvent(event).then(() => {
        this.setState({ isNewEventPanelVisible: false, activePage: 1 });

        this.getEventsBySelectionFilter(
          0,
          getSelectionFiltersBySearchCriteria(
            this.state.searchCriteria,
            this.state.view
          ),
          this.state.sortingFilter
        ).then((events) =>
          this.refreshEventList(
            events,
            0,
            getSelectionFiltersBySearchCriteria(
              this.state.searchCriteria,
              this.state.sortingFilter
            )
          )
        );
        this.getEventCountBySelectionFilter(
          getSelectionFiltersBySearchCriteria(
            this.state.searchCriteria,
            this.state.view
          )
        ).then((eventCount) =>
          this.setState({
            eventCountBySelectionFilter: parseInt(eventCount, 10),
          })
        );
        this.getEventCountBySelectionFilter(
          getSelectionFiltersBySearchCriteria([], this.state.view)
        ).then((eventCount) =>
          this.setState({
            allEventsCountAtLastRefresh: parseInt(eventCount, 10),
          })
        );
      });
    }
  }

  /**
   * Checks whether the app is properly configured for wall-eLog
   * @returns {boolean} true when the app is properly configured
   */
  isAppProperlyConfigured() {
    if (!UI.logbook) {
      console.log(
        '[ERROR] [CONFIG] logbook section is missing in File src/config/ui/config'
      );
      return false;
    }
    if (!UI.logbook.SORT_EVENTS_BY) {
      console.log('[ERROR] [CONFIG] SORT_EVENTS_BY object is missing');
      return false;
    } else if (
      UI.logbook.SORT_EVENTS_BY !== 'creationDate' &&
      UI.logbook.SORT_EVENTS_BY !== '_id' &&
      UI.logbook.SORT_EVENTS_BY !== 'createdAt' &&
      UI.logbook.SORT_EVENTS_BY !== 'updatedAt'
    ) {
      console.log(
        "[ERROR] [CONFIG] SORT_EVENTS_BY value is not supported. Possible values are 'creationDate', '_id', 'createdAt' and 'updatedAt' "
      );
      return false;
    }
    if (!UI.logbook.SORTING_ORDER) {
      console.log('[ERROR] [CONFIG] SORTING_ORDER object is missing');
      return false;
    }
    if (!UI.logbook.EVENTS_PER_PAGE) {
      console.log('[ERROR] [CONFIG] EVENTS_PER_PAGE value is missing');
      return false;
    }
    return true;
  }
}

function mapStateToProps(state) {
  return {
    releasedInvestigations: state.releasedInvestigations.data,
    logbookContext: state.logbook.context,
    user: state.user,
  };
}

/**
 * Redux related function which is used to map local function with redux dispatch()
 * @param {*} dispatch redux dispatch function
 */
function mapDispatchToProps(dispatch) {
  return {
    setLogbookContext: (context) => dispatch(setLogbookContextAction(context)),
  };
}

LogbookContainer.propTypes = {
  /** the investigationId */
  investigationId: PropTypes.string.isRequired,
};

export default connect(mapStateToProps, mapDispatchToProps)(LogbookContainer);
