/**
 * Copyright (c) Nicolas Gallagher.
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * 
 */

import invariant from 'fbjs/lib/invariant';
import canUseDOM from '../../modules/canUseDom';
var initialURL = canUseDOM ? window.location.href : '';
class Linking {
  constructor() {
    this._eventCallbacks = {};
  }
  /**
   * An object mapping of event name
   * and all the callbacks subscribing to it
   */
  _dispatchEvent(event) {
    for (var _len = arguments.length, data = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
      data[_key - 1] = arguments[_key];
    }
    var listeners = this._eventCallbacks[event];
    if (listeners != null && Array.isArray(listeners)) {
      listeners.map(listener => {
        listener(...data);
      });
    }
  }

  /**
   * Adds a event listener for the specified event. The callback will be called when the
   * said event is dispatched.
   */
  addEventListener(eventType, callback) {
    var _this = this;
    if (!_this._eventCallbacks[eventType]) {
      _this._eventCallbacks[eventType] = [callback];
    }
    _this._eventCallbacks[eventType].push(callback);
    return {
      remove() {
        var callbacks = _this._eventCallbacks[eventType];
        var filteredCallbacks = callbacks.filter(c => c.toString() !== callback.toString());
        _this._eventCallbacks[eventType] = filteredCallbacks;
      }
    };
  }

  /**
   * Removes a previously added event listener for the specified event. The callback must
   * be the same object as the one passed to `addEventListener`.
   */
  removeEventListener(eventType, callback) {
    console.error("Linking.removeEventListener('" + eventType + "', ...): Method has been " + 'deprecated. Please instead use `remove()` on the subscription ' + 'returned by `Linking.addEventListener`.');
    var callbacks = this._eventCallbacks[eventType];
    var filteredCallbacks = callbacks.filter(c => c.toString() !== callback.toString());
    this._eventCallbacks[eventType] = filteredCallbacks;
  }
  canOpenURL() {
    return Promise.resolve(true);
  }
  getInitialURL() {
    return Promise.resolve(initialURL);
  }

  /**
   * Try to open the given url in a secure fashion. The method returns a Promise object.
   * If a target is passed (including undefined) that target will be used, otherwise '_blank'.
   * If the url opens, the promise is resolved. If not, the promise is rejected.
   * Dispatches the `onOpen` event if `url` is opened successfully.
   */
  openURL(url, target) {
    if (arguments.length === 1) {
      target = '_blank';
    }
    try {
      open(url, target);
      this._dispatchEvent('onOpen', url);
      return Promise.resolve();
    } catch (e) {
      return Promise.reject(e);
    }
  }
  _validateURL(url) {
    invariant(typeof url === 'string', 'Invalid URL: should be a string. Was: ' + url);
    invariant(url, 'Invalid URL: cannot be empty');
  }
}
var open = (url, target) => {
  if (canUseDOM) {
    var urlToOpen = new URL(url, window.location).toString();
    if (urlToOpen.indexOf('tel:') === 0) {
      window.location = urlToOpen;
    } else {
      window.open(urlToOpen, target, 'noopener');
    }
  }
};
export default new Linking();