"use strict";

require("core-js/modules/web.dom.iterable");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _auth0React = require("@auth0/auth0-react");

var _clone = _interopRequireDefault(require("clone"));

var _formik = require("formik");

var _react = _interopRequireWildcard(require("react"));

var _reactRedux = require("react-redux");

var yup = _interopRequireWildcard(require("yup"));

var _accountPage = _interopRequireDefault(require("../account-page"));

var uiActions = _interopRequireWildcard(require("../../../actions/ui"));

var userActions = _interopRequireWildcard(require("../../../actions/user"));

var _awaitingScreen = _interopRequireDefault(require("../awaiting-screen"));

var _constants = require("../../../util/constants");

var _itinerary = require("../../../util/itinerary");

var _monitoredTrip = require("../../../util/monitored-trip");

var _state = require("../../../util/state");

var _ui2 = require("../../../util/ui");

var _withLoggedInUserSupport = _interopRequireDefault(require("../with-logged-in-user-support"));

var _tripSummaryPane = _interopRequireDefault(require("./trip-summary-pane"));

var _tripNotificationsPane = _interopRequireDefault(require("./trip-notifications-pane"));

var _tripBasicsPane = _interopRequireDefault(require("./trip-basics-pane"));

var _savedTripEditor = _interopRequireDefault(require("./saved-trip-editor"));

function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }

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

function _extends() { _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; }; return _extends.apply(this, arguments); }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

// The validation schema shape for the form fields.
// TODO: add fields here as they are implemented.
const validationSchemaShape = {
  isActive: yup.boolean(),
  leadTimeInMinutes: yup.number().positive().integer(),
  tripName: yup.string().required('Please enter a trip name')
}; // Add the checks on each day that at least one day is monitored.

_monitoredTrip.ALL_DAYS.forEach(day => {
  validationSchemaShape[day] = yup.boolean().test('one-day-selected', 'Please select at least one day to monitor', function () {
    let selectedDays = 0;

    _monitoredTrip.ALL_DAYS.forEach(day => {
      if (this.parent[day]) selectedDays++;
    });

    return selectedDays !== 0;
  });
});
/**
 * Checks that the maximum allowed number of saved trips has not been reached.
 */


function hasMaxTripCount(trips) {
  // TODO: Obtain the maximum number from a query to middleware (it is currently hard coded there too).
  return trips && trips.length >= 5;
}
/**
 * This screen handles saving a trip from an OTP query, or editing an existing saved trip
 * for the currently logged-in user.
 */


class SavedTripScreen extends _react.Component {
  constructor(...args) {
    super(...args);

    _defineProperty(this, "_createMonitoredTrip", () => {
      const {
        itinerary,
        loggedInUser,
        queryParams
      } = this.props;
      const monitoredDays = (0, _itinerary.getItineraryDefaultMonitoredDays)(itinerary);
      return { ...(0, _monitoredTrip.arrayToDayFields)(monitoredDays),
        arrivalVarianceMinutesThreshold: 5,
        departureVarianceMinutesThreshold: 5,
        excludeFederalHolidays: true,
        isActive: true,
        itinerary,
        leadTimeInMinutes: 30,
        // when creating a monitored trip, the query params will be changed on the
        // backend so that the modes parameter will reflect the modes seen in the
        // itinerary
        queryParams,
        tripName: '',
        // FIXME: Handle populating/checking userID from middleware too,
        // so that providing this field is no longer needed.
        userId: loggedInUser.id
      };
    });

    _defineProperty(this, "_updateMonitoredTrip", monitoredTrip => {
      const {
        createOrUpdateUserMonitoredTrip,
        isCreating
      } = this.props;
      createOrUpdateUserMonitoredTrip(monitoredTrip, isCreating);
    });

    _defineProperty(this, "_goToTripPlanner", () => this.props.routeTo('/'));

    _defineProperty(this, "_goToSavedTrips", () => this.props.routeTo(_constants.TRIPS_PATH));

    _defineProperty(this, "_panes", {
      basics: _tripBasicsPane.default,
      notifications: _tripNotificationsPane.default,
      summary: _tripSummaryPane.default
    });

    _defineProperty(this, "_getTripToEdit", () => {
      const {
        isCreating,
        monitoredTrips,
        tripId
      } = this.props;
      return isCreating ? this._createMonitoredTrip() : monitoredTrips.find(trip => trip.id === tripId);
    });
  }

  componentDidMount() {
    const {
      isCreating,
      monitoredTrips
    } = this.props;

    if (isCreating && hasMaxTripCount(monitoredTrips)) {
      // There is a middleware limit of 5 saved trips,
      // so if that limit is already reached, alert, then show editing mode.
      alert('You already have reached the maximum of five saved trips.\n' + 'Please remove unused trips from your saved trips, and try again.');

      this._goToSavedTrips();
    } // TODO: Update title bar during componentDidMount.

  }
  /**
   * Gets (or creates) the trip to edit from the props.
   */


  render() {
    const {
      isCreating,
      loggedInUser,
      monitoredTrips
    } = this.props;
    let screenContents;

    if (!monitoredTrips) {
      // Flash an indication while user trips are being loaded.
      screenContents = /*#__PURE__*/_react.default.createElement(_awaitingScreen.default, null);
    } else {
      const monitoredTrip = this._getTripToEdit();

      const otherTripNames = monitoredTrips.filter(trip => trip !== monitoredTrip).map(trip => trip.tripName);
      const clonedSchemaShape = (0, _clone.default)(validationSchemaShape);
      clonedSchemaShape.tripName = yup.string().required('Please enter a trip name').notOneOf(otherTripNames, 'Another saved trip already uses this name. Please choose a different name.');
      const validationSchema = yup.object(clonedSchemaShape);
      screenContents = /*#__PURE__*/_react.default.createElement(_formik.Formik, {
        enableReinitialize: true,
        initialValues: monitoredTrip,
        onSubmit: this._updateMonitoredTrip,
        validateOnBlur: true // Avoid validating on change as it is annoying. Validating on blur is enough.
        ,
        validateOnChange: false,
        validationSchema: validationSchema
      }, // Formik props provide access to the current user data state and errors
      // (in props.values, props.touched, props.errors)
      // and to its own blur/change/submit event handlers that automate the state.
      // We pass the Formik props below to the components rendered so that individual controls
      // can be wired to be managed by Formik.
      props => {
        return /*#__PURE__*/_react.default.createElement(_formik.Form, {
          noValidate: true
        }, /*#__PURE__*/_react.default.createElement(_savedTripEditor.default, _extends({}, props, {
          isCreating: isCreating,
          notificationChannel: loggedInUser.notificationChannel,
          onCancel: isCreating ? this._goToTripPlanner : this._goToSavedTrips,
          panes: this._panes
        })));
      });
    }

    return /*#__PURE__*/_react.default.createElement(_accountPage.default, null, screenContents);
  }

} // connect to the redux store


const mapStateToProps = (state, ownProps) => {
  const activeSearch = (0, _state.getActiveSearch)(state);
  const activeItinerary = activeSearch && activeSearch.activeItinerary;
  const itineraries = (0, _state.getActiveItineraries)(state) || [];
  const tripId = ownProps.match.params.id;
  return {
    activeSearchId: state.otp.activeSearchId,
    isCreating: tripId === 'new',
    itinerary: itineraries[activeItinerary],
    loggedInUser: state.user.loggedInUser,
    monitoredTrips: state.user.loggedInUserMonitoredTrips,
    queryParams: state.router.location.search,
    tripId
  };
};

const mapDispatchToProps = {
  createOrUpdateUserMonitoredTrip: userActions.createOrUpdateUserMonitoredTrip,
  routeTo: uiActions.routeTo
};

var _default = (0, _withLoggedInUserSupport.default)((0, _auth0React.withAuthenticationRequired)((0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(SavedTripScreen), _ui2.RETURN_TO_CURRENT_ROUTE), true);

exports.default = _default;
module.exports = exports.default;

//# sourceMappingURL=saved-trip-screen.js