'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; /* eslint-env browser */

exports.default = createBrowserApp;

var _history = require('history');

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _core = require('@react-navigation/core');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/* eslint-disable import/no-commonjs */
const queryString = require('query-string');

const getPathAndParamsFromLocation = location => {
  const path = encodeURI(location.pathname.substr(1));
  const params = queryString.parse(location.search);
  return { path, params };
};

const matchPathAndParams = (a, b) => {
  if (a.path !== b.path) {
    return false;
  }
  if (queryString.stringify(a.params) !== queryString.stringify(b.params)) {
    return false;
  }
  return true;
};

function getHistory(history) {
  if (typeof history === 'string') {
    switch (history) {
      case 'browser':
        return (0, _history.createBrowserHistory)();
      case 'hash':
        return (0, _history.createHashHistory)();
      case 'memory':
        return (0, _history.createMemoryHistory)();
      default:
        throw new Error('@react-navigation/web: createBrowserApp() Invalid value for options.history ' + history);
    }
  }
  return history || (0, _history.createBrowserHistory)();
}

function createBrowserApp(App, { history: historyOption } = {}) {
  const history = getHistory(historyOption);
  let currentPathAndParams = getPathAndParamsFromLocation(history.location);
  const initAction = App.router.getActionForPathAndParams(currentPathAndParams.path, currentPathAndParams.params) || _core.NavigationActions.init();

  const setHistoryListener = dispatch => {
    history.listen(location => {
      const pathAndParams = getPathAndParamsFromLocation(location);
      if (matchPathAndParams(pathAndParams, currentPathAndParams)) {
        return;
      }
      currentPathAndParams = pathAndParams;
      const action = App.router.getActionForPathAndParams(pathAndParams.path, pathAndParams.params);
      if (action) {
        dispatch(action);
      } else {
        dispatch(initAction);
      }
    });
  };

  class WebApp extends _react2.default.Component {
    constructor(...args) {
      var _temp;

      return _temp = super(...args), this.state = { nav: App.router.getStateForAction(initAction) }, this._title = document.title, this._actionEventSubscribers = new Set(), this.dispatch = action => {
        const lastState = this.state.nav;
        const newState = App.router.getStateForAction(action, lastState);
        const dispatchEvents = () => this._actionEventSubscribers.forEach(subscriber => subscriber({
          type: 'action',
          action,
          state: newState,
          lastState
        }));
        if (newState && newState !== lastState) {
          this.setState({ nav: newState }, () => {
            this._onNavigationStateChange(lastState, newState, action);
            dispatchEvents();
          });
          const pathAndParams = App.router.getPathAndParamsForState && App.router.getPathAndParamsForState(newState);
          if (pathAndParams && !matchPathAndParams(pathAndParams, currentPathAndParams)) {
            currentPathAndParams = pathAndParams;
            history.push(`/${pathAndParams.path}?${queryString.stringify(pathAndParams.params)}`);
          }
        } else {
          dispatchEvents();
        }
      }, _temp;
    }

    componentDidMount() {
      setHistoryListener(this.dispatch);
      this.updateTitle();
      this._actionEventSubscribers.forEach(subscriber => subscriber({
        type: 'action',
        action: initAction,
        state: this.state.nav,
        lastState: null
      }));
    }
    componentDidUpdate() {
      this.updateTitle();
    }
    updateTitle() {
      const { state } = this._navigation;
      const childKey = state.routes[state.index].key;
      const activeNav = this._navigation.getChildNavigation(childKey);
      const opts = App.router.getScreenOptions(activeNav);
      this._title = opts.title || opts.headerTitle;
      if (this._title) {
        document.title = this._title;
      }
    }

    _onNavigationStateChange(prevNav, nav, action) {
      if (typeof this.props.onNavigationStateChange === 'function') {
        this.props.onNavigationStateChange(prevNav, nav, action);
      }
    }

    render() {
      this._navigation = (0, _core.getNavigation)(App.router, this.state.nav, this.dispatch, this._actionEventSubscribers, () => this.props.screenProps, () => this._navigation);
      return _react2.default.createElement(
        _core.NavigationProvider,
        { value: this._navigation },
        _react2.default.createElement(App, _extends({}, this.props, { navigation: this._navigation }))
      );
    }
  }
  return WebApp;
}