"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.PerformanceManager = void 0;
var _dataSources = require("@mirai/data-sources");
var _services = require("@mirai/services");
var _ui = require("@mirai/ui");
var _react = require("react");
var _helpers = require("./helpers");
var _PerformanceManager = require("./PerformanceManager.constants");
var _PerformanceManager2 = require("./PerformanceManager.events");
var _PerformanceManager3 = require("./PerformanceManager.scripts");
var _package = require("../../../package.json");
var _helpers2 = require("../../components/helpers");
var _Core = require("../../Core.constants");
var _helpers3 = require("../../helpers");
var _getSuperProps = require("../../helpers/getSuperProps");
const _excluded = ["performance"],
  _excluded2 = ["id"],
  _excluded3 = ["event"];
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); }
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
const MAX_COUNTER = 5;
const _ref = _Core.PERFORMANCE || {},
  COMPARE = _ref.COMPARE,
  GTM = _ref.GTM;
let counter = 0;
let memoizedPendingEvents = [];
const PerformanceManager = () => {
  const device = (0, _ui.useDevice)();
  const _useMetrics = (0, _dataSources.useMetrics)(),
    track = _useMetrics.track;
  const _useStore = (0, _dataSources.useStore)(),
    _useStore$value = _useStore.value,
    _useStore$value$perfo = _useStore$value.performance,
    storePerformance = _useStore$value$perfo === void 0 ? [] : _useStore$value$perfo,
    store = _objectWithoutProperties(_useStore$value, _excluded);
  const _useState = (0, _react.useState)((0, _helpers.getConsentMode)()),
    _useState2 = _slicedToArray(_useState, 2),
    consentMode = _useState2[0],
    setConsentMode = _useState2[1];
  const _useState3 = (0, _react.useState)(storePerformance),
    _useState4 = _slicedToArray(_useState3, 2),
    performance = _useState4[0],
    setPerformance = _useState4[1];
  const components = store.components,
    _store$finder = store.finder,
    _store$finder2 = _store$finder === void 0 ? {} : _store$finder,
    place = _store$finder2.place,
    _store$hotel = store.hotel,
    hotel = _store$hotel === void 0 ? {} : _store$hotel,
    instanceId = store.id,
    locale = store.locale,
    session = store.session,
    type = store.type;
  (0, _react.useEffect)(() => {
    const metrics = _services.ServiceFeatures.get('metrics', instanceId);
    const handleMetrics = _ref2 => {
      let id = _ref2.id,
        props = _objectWithoutProperties(_ref2, _excluded2);
      if (!id || !metrics || window.IS_PLAYWRIGHT || window.location.host === 'monalisa.mirai.com') return;
      const event = id.toUpperCase().trim();
      track(event, _objectSpread(_objectSpread(_objectSpread({}, props), (0, _getSuperProps.getSuperProps)({
        store,
        engineVersion: _package.version
      })), {}, {
        locale,
        mobile: device.mobile,
        session,
        type
      }));
    };
    _dataSources.Event.subscribe(_helpers2.EVENT.METRICS, handleMetrics);
    return () => _dataSources.Event.unsubscribe(_helpers2.EVENT.METRICS, handleMetrics);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [store]);
  (0, _react.useEffect)(() => {
    if (consentMode) return;
    const interval = setInterval(async () => {
      counter !== undefined && counter++;
      const nextConsentMode = (0, _helpers.getConsentMode)(counter >= MAX_COUNTER);
      const isGtm = provider => [COMPARE, GTM].includes(provider);
      if (nextConsentMode === undefined && memoizedPendingEvents.filter(function () {
        let _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
          provider = _ref3.provider;
        return isGtm(provider);
      }).length === 0 || !nextConsentMode && counter < MAX_COUNTER) return;
      const nextMemoizedPendingEvents = [];
      memoizedPendingEvents.forEach(function () {
        let event = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
        const provider = event.provider;
        const execute = nextConsentMode || counter >= MAX_COUNTER && _PerformanceManager.CONSENT_MODE_ANSWERED.includes(provider) && (nextConsentMode === false || isGtm(provider));
        const requeue = nextConsentMode === undefined && !isGtm(provider);
        if (execute) {
          executeEvent(event, nextConsentMode);
          if (!nextConsentMode && !isGtm(provider)) nextMemoizedPendingEvents.push(event);
        } else if (!execute || requeue) {
          nextMemoizedPendingEvents.push(event);
        }
      });
      memoizedPendingEvents = nextMemoizedPendingEvents;
      if (nextConsentMode !== undefined) {
        counter = undefined;
        setConsentMode(nextConsentMode);
      }
    }, 1000);
    return () => clearInterval(interval);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [consentMode]);
  (0, _react.useEffect)(() => {
    const config = store.config,
      _store$finder3 = store.finder,
      _store$finder4 = _store$finder3 === void 0 ? {} : _store$finder3,
      _store$finder4$place = _store$finder4.place,
      _store$finder4$place2 = _store$finder4$place === void 0 ? {} : _store$finder4$place,
      _store$finder4$place3 = _store$finder4$place2.id,
      _store$finder4$place4 = _store$finder4$place3 === void 0 ? [] : _store$finder4$place3,
      _store$finder4$place5 = _slicedToArray(_store$finder4$place4, 1),
      hotelId = _store$finder4$place5[0],
      isHotel = _store$finder4$place2.isHotel;
    if (place) {
      setPerformance((0, _helpers3.getPerformance)(config, isHotel ? hotelId : undefined));
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [place]);
  (0, _react.useEffect)(() => {
    const handleEvent = _ref4 => {
      let event = _ref4.event,
        value = _objectWithoutProperties(_ref4, _excluded3);
      if (performance.length === 0) return;
      const currentConsentMode = (0, _helpers.getConsentMode)(true);
      const availableProviders = performance.map(function () {
        let _ref5 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
          type = _ref5.type;
        return type;
      }).filter(type => !(!currentConsentMode && _PerformanceManager.CONSENT_MODE_ANSWERED.includes(type))).filter(type => currentConsentMode || !_PerformanceManager.CONSENT_MODE_REQUIRED.includes(type));
      Object.entries(_PerformanceManager2.EVENTS[event]).forEach(_ref6 => {
        let _ref7 = _slicedToArray(_ref6, 2),
          propProvider = _ref7[0],
          _ref7$ = _ref7[1],
          callback = _ref7$ === void 0 ? () => {} : _ref7$;
        const provider = parseInt(propProvider);
        const props = {
          callback,
          event,
          provider,
          value
        };
        if (!currentConsentMode && !availableProviders.includes(provider)) {
          if (counter === undefined && _PerformanceManager.CONSENT_MODE_ANSWERED.includes(provider)) {
            executeEvent(props);
          } else if (!memoizedPendingEvents.some(item => item.event === event && item.provider === provider)) {
            memoizedPendingEvents.push(props);
          }
        } else executeEvent(props, currentConsentMode);
      });
    };
    Object.keys(_PerformanceManager2.EVENTS).forEach(event => _dataSources.Event.subscribe(event, handleEvent));
    return () => Object.keys(_PerformanceManager2.EVENTS).forEach(event => _dataSources.Event.unsubscribe(event, handleEvent));
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [device, performance, store]);
  const executeEvent = function () {
    let _ref8 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
      provider = _ref8.provider,
      callback = _ref8.callback,
      value = _ref8.value,
      event = _ref8.event;
    let nextConsentMode = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : consentMode;
    loadScripts(performance.filter(function () {
      let _ref9 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
        type = _ref9.type;
      return type === provider && type !== COMPARE;
    }), nextConsentMode).then(() => {
      const config = performance.find(_ref0 => {
        let type = _ref0.type;
        return type === provider;
      });
      const response = callback(_objectSpread(_objectSpread(_objectSpread({}, value), config), {}, {
        device,
        store
      }));
      if (!response) return;
      const label = "\u26A1\uFE0F ".concat((0, _helpers.getPerformanceLabel)(provider), " ").concat(event);
      // eslint-disable-next-line no-console
      response.then ? response.then(value => console.log(label, value)) : console.log(label, response);
      if (provider === GTM) {
        window.Mirai.urlParameters = (0, _helpers3.fetchUrlParams)(location.search);
        loadScripts(performance.filter(function () {
          let _ref1 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
            type = _ref1.type;
          return type === COMPARE;
        }), nextConsentMode);
      }
    });
  };
  const loadScripts = async function () {
    let performance = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
    let propConsentMode = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : consentMode;
    const loadedComponents = Object.keys(components);
    const scripts = [];
    performance.filter(function () {
      let _ref10 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
        type = _ref10.type;
      return propConsentMode === true || !_PerformanceManager.CONSENT_MODE_REQUIRED.includes(type);
    }).forEach(function () {
      let _ref11 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
        type = _ref11.type,
        _ref11$instances = _ref11.instances,
        propInstances = _ref11$instances === void 0 ? [] : _ref11$instances,
        gtgEnabled = _ref11.gtgEnabled;
      const _ref12 = _PerformanceManager3.SCRIPTS[type] || {},
        _ref12$components = _ref12.components,
        components = _ref12$components === void 0 ? [] : _ref12$components,
        _ref12$init = _ref12.init,
        init = _ref12$init === void 0 ? () => {} : _ref12$init,
        _ref12$once = _ref12.once,
        once = _ref12$once === void 0 ? false : _ref12$once;
      if (components.length === 0 || components.some(item => loadedComponents.includes(item))) {
        const instances = once ? [propInstances[0]] : propInstances;
        scripts.push(...instances.map(function () {
          let config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
          let index = arguments.length > 1 ? arguments[1] : undefined;
          return _objectSpread(_objectSpread({
            domain: "performance-".concat((0, _helpers.getPerformanceLabel)(type)),
            id: index + 1
          }, init(_objectSpread(_objectSpread({}, config), {}, {
            hotel,
            index,
            instanceId,
            gtgEnabled,
            loadedComponents,
            place
          }))), {}, {
            type
          });
        }));
      }
    });
    for (let index = 0; index < scripts.length; index++) {
      await (0, _helpers3.loadScript)(scripts[index]).catch(() => {});
    }
  };
  return null;
};
exports.PerformanceManager = PerformanceManager;
//# sourceMappingURL=PerformanceManager.js.map