function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
import React, { Component } from "react";
import PropTypes from "prop-types";
import { connect } from "react-redux";
import { MdLoop } from "react-icons/md";
import qs from "query-string";
import DestinationInput from "./DestinationInput";
import { ReactComponent as SBBClock } from "../../img/clock_10_large.svg";
import { setDeparturesFilter } from "../../model/app/actions";
import "./DeparturePopupContent.scss";
const DESTINATION_FILTER = "destination";
const propTypes = {
  uic: PropTypes.number.isRequired,
  icon: PropTypes.object,
  platform: PropTypes.string,
  showTitle: PropTypes.bool,
  children: PropTypes.node,
  // react-i18next
  t: PropTypes.func.isRequired,
  // mapStateToProps
  departuresUrl: PropTypes.string.isRequired,
  destinationUrl: PropTypes.string.isRequired,
  apiKey: PropTypes.string,
  // mapDispatchToProps
  dispatchSetDeparturesFilter: PropTypes.func.isRequired
};
const defaultProps = {
  icon: null,
  showTitle: false,
  apiKey: null,
  platform: undefined,
  // important to avoid the platform param to be add in the url.
  children: undefined
};
class DeparturePopupContent extends Component {
  static updatePermalink(destination) {
    const oldParams = qs.parse(window.location.search);
    const parameters = _objectSpread(_objectSpread({}, oldParams), {
      [DESTINATION_FILTER]: destination ? destination.label : undefined
    });
    const qStr = qs.stringify(parameters);
    const search = qStr ? "?".concat(qStr) : "";
    if (!qStr && window.location.search || qStr && search !== window.location.search) {
      const {
        hash
      } = window.location;
      window.history.replaceState(undefined, undefined, "".concat(search).concat(hash || ""));
    }
  }
  static formatTime(time) {
    const d = new Date(time);
    return ["0".concat(d.getHours()).slice(-2), "0".concat(d.getMinutes()).slice(-2)].join(":");
  }
  static getMinDiff(time) {
    const min = Math.floor((new Date(time) - new Date()) / 1000 / 60);
    if (min < 0) {
      return null;
    }
    return min > 0 && min < 60 ? [min, "'"].join("") : null;
  }
  static getDelayColor(estimatedTimeLocal, timetabledTimeLocal) {
    if (!estimatedTimeLocal || !timetabledTimeLocal) {
      return "green";
    }
    const min = Math.floor((new Date(estimatedTimeLocal) - new Date(timetabledTimeLocal)) / 1000 / 60);
    if (min >= 3 && min < 5) {
      return "orange";
    }
    if (min >= 5) {
      return "red";
    }
    return "green";
  }
  constructor(props) {
    super(props);
    this.state = {
      departures: [],
      departuresLoading: true,
      destinationFilter: null,
      platformName: "abfahrtszeiten_kante",
      isOffline: false
    };
    this.loadInterval = null;
    this.mounted = false;
    this.abortController = new AbortController();
  }
  componentDidMount() {
    const {
      destinationUrl,
      dispatchSetDeparturesFilter,
      uic,
      platform
    } = this.props;
    const {
      destinationFilter
    } = this.state;
    this.mounted = true;
    this.loadDepartures();
    this.loadInterval = window.setInterval(() => this.loadDepartures(), 10000);
    dispatchSetDeparturesFilter(uic.toString(), platform);
    const parameters = qs.parse(window.location.search);
    if (parameters[DESTINATION_FILTER]) {
      const url = "".concat(destinationUrl, "/").concat(uic, "?&destination=").concat(parameters[DESTINATION_FILTER]);
      fetch(url).then(response => response.json()).then(data => {
        const destination = data ? {
          label: data[0].dest,
          id: data[0].stop
        } : null;
        this.onDestinationSelect(destination);
      }).catch(() => {});
    } else {
      this.onDestinationSelect(destinationFilter);
    }
  }
  componentDidUpdate(prevProps, prevState) {
    const {
      destinationFilter
    } = this.state;
    if (destinationFilter !== prevState.destinationFilter) {
      this.loadDepartures();
    }
  }
  componentWillUnmount() {
    const {
      dispatchSetDeparturesFilter
    } = this.props;
    this.abortController.abort();
    this.mounted = false;
    window.clearInterval(this.loadInterval);
    dispatchSetDeparturesFilter();
  }

  /**
   * On selection of a destination in the input.
   * @private
   */
  onDestinationSelect(selectedDestination) {
    this.setState({
      destinationFilter: selectedDestination
    });
    DeparturePopupContent.updatePermalink(selectedDestination);
  }

  /**
   * Load departures.
   * @param {string} destination Selected destination.
   * @private
   */
  loadDepartures() {
    const {
      apiKey,
      uic,
      departuresUrl
    } = this.props;
    const {
      destinationFilter
    } = this.state;
    const urlParams = {
      key: apiKey,
      limit: "30"
    };
    if (uic) {
      urlParams.uic = uic;
    }
    if (destinationFilter) {
      urlParams.destination_uic = "".concat(destinationFilter.id);
    }
    const url = "".concat(departuresUrl, "/?").concat(qs.stringify(urlParams));
    this.abortController.abort();
    this.abortController = new AbortController();
    fetch(url, {
      signal: this.abortController.signal
    }).then(response => response.json()).then(data => {
      // HACK to prevent "update of unmounted component" warning
      if (!this.mounted) {
        return;
      }
      if (data.error) {
        // eslint-disable-next-line no-console
        console.warn(data.error);
        return;
      }
      // mode of transport does not change between departures
      const platformType = data && data.length ? data[0].modeOfTransport : null;
      let platformName = null;
      switch (platformType) {
        case "rail":
          platformName = "abfahrtszeiten_gleis";
          break;
        case "water":
          platformName = "abfahrtszeiten_steg";
          break;
        default:
          platformName = "abfahrtszeiten_kante";
          break;
      }
      this.setState({
        departures: data,
        departuresLoading: false,
        platformName,
        isOffline: !navigator.onLine
      });
    }).catch(err => {
      if (err && err.name === "AbortError") {
        // ignore user abort request
        return;
      }
      this.setState({
        departuresLoading: false,
        isOffline: true
      });
    });
  }
  renderMinDiff(minDiff) {
    const {
      isOffline
    } = this.state;
    if (isOffline && minDiff) {
      return /*#__PURE__*/React.createElement(React.Fragment, null, "\xA0\xA0-\xA0");
    }
    return minDiff;
  }
  render() {
    const {
      uic,
      icon,
      showTitle,
      t,
      children
    } = this.props;
    let {
      departures
    } = this.state;
    departures = departures.sort((a, b) => new Date(a.estimatedTimeLocal || a.timetabledTimeLocal).getTime() - new Date(b.estimatedTimeLocal || b.timetabledTimeLocal).getTime());
    const {
      destinationFilter,
      departuresLoading,
      platformName,
      isOffline
    } = this.state;
    const loading = departuresLoading ? /*#__PURE__*/React.createElement("div", {
      className: "tm-loader"
    }, /*#__PURE__*/React.createElement(MdLoop, {
      className: "tm-load-spinner",
      focusable: false
    })) : null;
    let info = null;
    if (!departuresLoading && departures.length === 0) {
      info = /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("i", null, "".concat(t("Für den aktuellen Zeitraum konnten keine " + "Verbindungen gefunden werden"), ".")));
    }
    return /*#__PURE__*/React.createElement("div", {
      className: "tm-departure-popup-body"
    }, icon, showTitle && /*#__PURE__*/React.createElement("div", {
      className: "tm-departure-title"
    }, "".concat(t("Abfahrtszeiten aller ".concat(platformName)))), /*#__PURE__*/React.createElement(DestinationInput, {
      destination: destinationFilter,
      onSelect: d => this.onDestinationSelect(d),
      uic: uic
    }), loading, info, /*#__PURE__*/React.createElement("div", {
      className: "tm-table-wrapper".concat(departuresLoading ? " loading" : "")
    }, /*#__PURE__*/React.createElement("table", {
      className: "tm-departures"
    }, /*#__PURE__*/React.createElement("tbody", null, /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("th", {
      className: "tm-departure-line-cell"
    }, t("Linie")), /*#__PURE__*/React.createElement("th", null, t("Ziel")), /*#__PURE__*/React.createElement("th", {
      colSpan: "2"
    }, /*#__PURE__*/React.createElement(SBBClock, {
      focusable: false,
      height: "23px",
      width: "23px"
    })), /*#__PURE__*/React.createElement("th", null, t(platformName)[0].toUpperCase() + t(platformName).substring(1))), departures.map((departure, idx) =>
    /*#__PURE__*/
    // eslint-disable-next-line react/no-array-index-key
    React.createElement("tr", {
      key: idx
    }, /*#__PURE__*/React.createElement("td", {
      className: "tm-departure-line-cell"
    }, /*#__PURE__*/React.createElement("div", {
      className: "tm-departure-name"
    }, departure.lineName)), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement("div", {
      className: "tm-departure-destination"
    }, departure.destinationText)), /*#__PURE__*/React.createElement("td", null, DeparturePopupContent.formatTime(departure.timetabledTimeLocal)), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement("div", {
      className: "tm-departure-min",
      style: {
        color: isOffline ? "#333" : DeparturePopupContent.getDelayColor(departure.estimatedTimeLocal, departure.timetabledTimeLocal)
      }
    }, this.renderMinDiff(DeparturePopupContent.getMinDiff(departure.estimatedTimeLocal || departure.timetabledTimeLocal)))), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement("div", {
      className: "tm-departure-platform " + "".concat(departure.modeOfTransport === "rail" ? "train" : "")
    }, /*#__PURE__*/React.createElement("div", {
      className: "tm-platform-inner"
    }, departure.plannedQuay)))))))), children);
  }
}
const mapStateToProps = state => ({
  departuresUrl: state.app.departuresUrl,
  destinationUrl: state.app.destinationUrl,
  apiKey: state.app.apiKey,
  t: state.app.t
});
const mapDispatchToProps = {
  dispatchSetDeparturesFilter: setDeparturesFilter
};
DeparturePopupContent.propTypes = propTypes;
DeparturePopupContent.defaultProps = defaultProps;
export default connect(mapStateToProps, mapDispatchToProps)(DeparturePopupContent);
//# sourceMappingURL=DeparturePopupContent.js.map