"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.resetAndToggleCallHistory = resetAndToggleCallHistory;
exports.beginCallIfNeeded = beginCallIfNeeded;
exports.endCall = endCall;
exports.initializeModules = initializeModules;
exports.fetchCalls = fetchCalls;
exports.saveQueriesForCall = saveQueriesForCall;
exports.fetchQueries = fetchQueries;
exports.toggleMailables = exports.toggleCallHistory = exports.beginCall = void 0;

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

var _query = require("@opentripplanner/core-utils/lib/query");

var _objectToFormdata = require("object-to-formdata");

var _qs = _interopRequireDefault(require("qs"));

var _reduxActions = require("redux-actions");

var _callTaker = require("../util/call-taker");

var _config = require("../util/config");

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

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

var _form = require("./form");

var _fieldTrip = require("./field-trip");

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

if (typeof fetch === 'undefined') require('isomorphic-fetch'); /// PRIVATE ACTIONS

const endingCall = (0, _reduxActions.createAction)('END_CALL');
const receivedCalls = (0, _reduxActions.createAction)('RECEIVED_CALLS');
const receivedQueries = (0, _reduxActions.createAction)('RECEIVED_QUERIES');
const requestingCalls = (0, _reduxActions.createAction)('REQUESTING_CALLS');
const requestingQueries = (0, _reduxActions.createAction)('REQUESTING_QUERIES');
const storeSession = (0, _reduxActions.createAction)('STORE_SESSION'); /// PUBLIC ACTIONS

const beginCall = (0, _reduxActions.createAction)('BEGIN_CALL');
exports.beginCall = beginCall;
const toggleCallHistory = (0, _reduxActions.createAction)('TOGGLE_CALL_HISTORY');
exports.toggleCallHistory = toggleCallHistory;
const toggleMailables = (0, _reduxActions.createAction)('TOGGLE_MAILABLES');
/**
 * Fully reset form and toggle call history (and close field trips if open).
 */

exports.toggleMailables = toggleMailables;

function resetAndToggleCallHistory() {
  return function (dispatch, getState) {
    dispatch((0, _form.resetForm)(true));
    dispatch(toggleCallHistory());
    if (getState().callTaker.fieldTrip.visible) dispatch((0, _fieldTrip.toggleFieldTrips)());
  };
}
/**
 * Start a new call (and show the call history window) if
 * - the call module is enabled, and
 * - a call is not in progress, and
 * - the field trip window is not visible.
 */


function beginCallIfNeeded() {
  return function (dispatch, getState) {
    const state = getState();
    const {
      activeCall,
      fieldTrip
    } = state.callTaker;
    const callTakerEnabled = (0, _config.isModuleEnabled)(state, _config.Modules.CALL_TAKER);

    if (callTakerEnabled && !activeCall && !fieldTrip.visible) {
      dispatch(beginCall());
    }
  };
}
/**
 * End the active call and store the queries made during the call.
 */


function endCall() {
  return async function (dispatch, getState) {
    const {
      callTaker,
      otp
    } = getState();
    const {
      activeCall,
      session
    } = callTaker;
    const {
      sessionId
    } = session;
    if ((0, _callTaker.sessionIsInvalid)(session)) return; // Make POST request to store new call.

    const callData = (0, _objectToFormdata.serialize)({
      call: {
        endTime: (0, _state.getTimestamp)(),
        startTime: activeCall.startTime
      },
      sessionId
    });

    try {
      const fetchResult = await fetch(`${otp.config.datastoreUrl}/calltaker/call`, {
        body: callData,
        method: 'POST'
      });
      const id = await fetchResult.json(); // Inject call ID into active call and save queries.

      await dispatch(saveQueriesForCall({ ...activeCall,
        id
      })); // Wait until query was saved before re-fetching queries for this call.

      await dispatch(fetchCalls());
    } catch (err) {
      console.error(err);
      alert(`Could not save call: ${JSON.stringify(err)}`);
    } // Clear itineraries shown when ending call.


    dispatch((0, _form.resetForm)(true));
    dispatch(endingCall());
  };
}
/**
 * Initialize the Call Taker and Field Trip modules by checking the session
 * query param against sessions in the datastore backend or initializing a new
 * session via Trinet.
 */


function initializeModules() {
  return function (dispatch, getState) {
    const {
      datastoreUrl,
      trinetReDirect
    } = getState().otp.config; // Initialize session if datastore enabled.

    if (datastoreUrl && trinetReDirect) {
      // TODO: Generalize for non-TriNet instances.
      const sessionId = (0, _query.getUrlParams)().sessionId;

      if (sessionId) {
        // Initialize the session if found in URL query params.
        dispatch(checkSession(datastoreUrl, sessionId));
      } else {
        // No sessionId was passed in, so we must request one from server.
        newSession(datastoreUrl, trinetReDirect, _constants.URL_ROOT);
      }
    }
  };
}
/**
 * Handle initializing a new Trinet session by redirecting to Trinet auth and
 * returning once authenticated successfully.
 */


function newSession(datastoreUrl, verifyLoginUrl, redirect) {
  fetch(datastoreUrl + '/auth/newSession').then(res => res.json()).then(data => {
    const {
      sessionId: session
    } = data;
    const windowUrl = `${verifyLoginUrl}?${_qs.default.stringify({
      redirect,
      session
    })}`; // Redirect to login url.

    window.location = windowUrl;
  }).catch(error => {
    console.error('newSession error', error);
  });
}
/**
 * Check that a particular session ID is valid and store resulting session
 * data.
 */


function checkSession(datastoreUrl, sessionId) {
  return function (dispatch, getState) {
    fetch(datastoreUrl + `/auth/checkSession?sessionId=${sessionId}`).then(res => res.json()).then(session => dispatch(storeSession({
      session
    }))).catch(error => {
      dispatch(storeSession({
        session: null
      }));
      alert(`Error establishing auth session: ${JSON.stringify(error)}`);
    });
  };
}
/**
 * Fetch latest calls for a particular session.
 */


function fetchCalls() {
  return async function (dispatch, getState) {
    dispatch(requestingCalls());
    const {
      callTaker,
      otp
    } = getState();
    if ((0, _callTaker.sessionIsInvalid)(callTaker.session)) return;
    const {
      datastoreUrl
    } = otp.config;
    const {
      sessionId
    } = callTaker.session;
    const limit = 1000;

    try {
      const fetchResult = await fetch(`${datastoreUrl}/calltaker/call?${_qs.default.stringify({
        limit,
        sessionId
      })}`);
      const calls = await fetchResult.json();
      dispatch(receivedCalls({
        calls
      }));
    } catch (err) {
      alert(`Error fetching calls: ${JSON.stringify(err)}`);
    }
  };
}
/**
 * Store the trip queries made over the course of a call (to be called when the
 * call terminates).
 */


function saveQueriesForCall(call) {
  return function (dispatch, getState) {
    const {
      callTaker,
      otp
    } = getState();
    const {
      datastoreUrl
    } = otp.config;
    if ((0, _callTaker.sessionIsInvalid)(callTaker.session)) return;

    if (!call) {
      alert(`Could not find call for ${call.id}. Cancelling save queries request.`);
      return;
    }

    return Promise.all(call.searches.map(searchId => {
      const search = otp.searches[searchId];
      const query = (0, _callTaker.searchToQuery)(search, call, otp.config);
      const {
        sessionId
      } = callTaker.session;
      const queryData = (0, _objectToFormdata.serialize)({
        query,
        sessionId
      });
      return fetch(`${datastoreUrl}/calltaker/callQuery?sessionId=${sessionId}`, {
        body: queryData,
        method: 'POST'
      }).then(res => res.json()).catch(err => {
        alert(`Error storing call queries: ${JSON.stringify(err)}`);
      });
    }));
  };
}
/**
 * Fetch the trip queries that were made during a particular call.
 */


function fetchQueries(callId) {
  return function (dispatch, getState) {
    dispatch(requestingQueries());
    const {
      callTaker,
      otp
    } = getState();
    const {
      datastoreUrl
    } = otp.config;
    if ((0, _callTaker.sessionIsInvalid)(callTaker.session)) return;
    const {
      sessionId
    } = callTaker.session;
    fetch(`${datastoreUrl}/calltaker/callQuery?sessionId=${sessionId}&call.id=${callId}`).then(res => res.json()).then(queries => {
      dispatch(receivedQueries({
        callId,
        queries
      }));
    }).catch(err => {
      alert(`Error fetching queries: ${JSON.stringify(err)}`);
    });
  };
}

//# sourceMappingURL=call-taker.js