import React from 'react';
import PropTypes from 'prop-types';
import composeStyles from '../../shared/stylesheetComposer';
import styles from './navigationTiers.scss';
import Dropdown from './Dropdown';
import ListProvider from './ListProvider';
import OpenProvider from './OpenProvider';
import PageProvider from './PageProvider';

export default class NavigationTiers extends React.Component {
  constructor(props) {
    super(props);
    this.styles = composeStyles(styles, [...props.stylesheets]);
    this.state = {};
  }

  componentDidMount() {
    this.props.searchOnKeyDown && this.addKeyDownListener(this);
  }

  addKeyDownListener(component) {
    document.addEventListener('keydown', function _listener() {
      component.setState({ open: true });
      document.removeEventListener('keydown', _listener);
    });
  }

  render() {
    const {
      children,
      clipResultsAt,
      i18n,
      id,
      initialData,
      initialDisplay,
      initialPath,
      onOpen,
      root,
      style,
      triggerZone,
    } = this.props;

    return (
      <OpenProvider onOpen={onOpen} open={this.state.open}>
        {
          (open, toggle) => (
            <div
              className={open ? this.styles['is--open'] : this.styles.root}
              id={id}
              style={style}
            >
              <div className={this.styles.trigger} onClick={toggle}>
                {triggerZone}
                <div className={this.styles.triggerCaret} />
              </div>
              <PageProvider
                defaultErrorMessage={i18n.errorMessage}
                initialData={initialData}
                initialDisplay={initialDisplay}
                initialPath={initialPath}
                root={root}
                tierChildren={React.Children.toArray(children)}
              >
                {
                  (tierProps, pageData, pageActions) => (
                    <ListProvider
                      clipResultsAt={clipResultsAt}
                      dataIn={pageData.data}
                      itemSearch={tierProps.itemSearch}
                      onHrefPrint={tierProps.onHrefPrint}
                      onSelect={tierProps.onSelect}
                      shouldReset={!open}
                    >
                      {
                        (listData, listActions, dropdownRef) => {
                          if (open) {
                            return (
                              <div className={this.styles.positionContainer}>
                                <Dropdown
                                  actions={{
                                    advance: pageActions.advance,
                                    back: pageActions.back,
                                    clearSearch: listActions.clearSearch,
                                    onChange: listActions.onChange,
                                    onSelect: tierProps.onSelect,
                                    onKeyDown: listActions.onKeyDown,
                                    setHighlightIndex: listActions.setHighlightIndex
                                  }}
                                  breadcrumbs={pageData.displayPath}
                                  clippedResultsMessage={tierProps.clippedResultsMessage(clipResultsAt)}
                                  composedStyles={this.styles}
                                  data={listData.data}
                                  didClipData={listData.didClipData}
                                  didError={pageData.didError}
                                  errorMessage={pageData.errorMessage}
                                  highlightIndex={listData.highlightIndex}
                                  i18n={i18n}
                                  isLoading={pageData.loading}
                                  onHrefPrint={tierProps.onHrefPrint}
                                  optionIdKey={tierProps.id}
                                  ref={dropdownRef}
                                  placeholder={tierProps.placeholder}
                                  searchTerm={listData.searchTerm}
                                >
                                  {tierProps.children}
                                </Dropdown>
                              </div>
                            );
                          }
                          return null;
                        }
                      }
                    </ListProvider>
                  )
                }
              </PageProvider>
            </div>
          )
        }
      </OpenProvider>
    );
  }
}


NavigationTiers.propTypes = {
  children: PropTypes.arrayOf(PropTypes.element).isRequired,
  clipResultsAt: PropTypes.number,
  initialData: PropTypes.arrayOf(PropTypes.shape({})).isRequired,
  i18n: PropTypes.shape({
    errorTitle: PropTypes.string,
    errorMessage: PropTypes.string,
    noSearchResults: PropTypes.string
  }),
  id: PropTypes.string,
  initialDisplay: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.number, PropTypes.string])),
  initialPath: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.number, PropTypes.string])),
  onOpen: PropTypes.func,
  root: PropTypes.string,
  searchOnKeyDown: PropTypes.bool,
  style: PropTypes.shape({}),
  stylesheets: PropTypes.arrayOf(PropTypes.shape({})),
  triggerZone: PropTypes.node
};

NavigationTiers.defaultProps = {
  clipResultsAt: 500,
  i18n: {
    errorTitle: 'Error.',
    errorMessage: 'Could not load results.',
    noSearchResults: 'No Results Found'
  },
  id: 'navigation_tiers',
  initialDisplay: [],
  initialPath: [],
  root: 'Root',
  searchOnKeyDown: false,
  style: {},
  stylesheets: [],
  triggerZone: 'Select'
};
