import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import { toggleAdvancedSettings } from 'Store/Actions/settingsActions';
import SettingsToolbar from './SettingsToolbar';

function mapStateToProps(state) {
  return {
    advancedSettings: state.settings.advancedSettings
  };
}

const mapDispatchToProps = {
  toggleAdvancedSettings
};

class SettingsToolbarConnector extends Component {

  //
  // Lifecycle

  constructor(props, context) {
    super(props, context);

    this.state = {
      nextLocation: null,
      nextLocationAction: null,
      confirmed: false
    };

    this._unblock = null;
  }

  componentDidMount() {
    this._unblock = this.props.history.block(this.routerWillLeave);
  }

  componentWillUnmount() {
    if (this._unblock) {
      this._unblock();
    }
  }

  //
  // Control

  routerWillLeave = (nextLocation, nextLocationAction) => {
    if (this.state.confirmed) {
      this.setState({
        nextLocation: null,
        nextLocationAction: null,
        confirmed: false
      });

      return true;
    }

    if (this.props.hasPendingChanges ) {
      this.setState({
        nextLocation,
        nextLocationAction
      });

      return false;
    }

    return true;
  };

  //
  // Listeners

  onAdvancedSettingsPress = () => {
    this.props.toggleAdvancedSettings();
  };

  onConfirmNavigation = () => {
    const {
      nextLocation,
      nextLocationAction
    } = this.state;

    const history = this.props.history;

    const path = `${nextLocation.pathname}${nextLocation.search}`;

    this.setState({
      confirmed: true
    }, () => {
      if (nextLocationAction === 'PUSH') {
        history.push(path);
      } else {
        // Unfortunately back and forward both use POP,
        // which means we don't actually know which direction
        // the user wanted to go, assuming back.

        history.goBack();
      }
    });
  };

  onCancelNavigation = () => {
    this.setState({
      nextLocation: null,
      nextLocationAction: null,
      confirmed: false
    });
  };

  //
  // Render

  render() {
    const hasPendingLocation = this.state.nextLocation !== null;

    return (
      <SettingsToolbar
        hasPendingLocation={hasPendingLocation}
        onSavePress={this.props.onSavePress}
        onAdvancedSettingsPress={this.onAdvancedSettingsPress}
        onConfirmNavigation={this.onConfirmNavigation}
        onCancelNavigation={this.onCancelNavigation}
        {...this.props}
      />
    );
  }
}

const historyShape = {
  block: PropTypes.func.isRequired,
  goBack: PropTypes.func.isRequired,
  push: PropTypes.func.isRequired
};

SettingsToolbarConnector.propTypes = {
  hasPendingChanges: PropTypes.bool.isRequired,
  history: PropTypes.shape(historyShape).isRequired,
  onSavePress: PropTypes.func,
  toggleAdvancedSettings: PropTypes.func.isRequired
};

SettingsToolbarConnector.defaultProps = {
  hasPendingChanges: false
};

export default withRouter(connect(mapStateToProps, mapDispatchToProps)(SettingsToolbarConnector));
