"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 _helpers2 = require("../../components/helpers");
var _Core = require("../../Core.constants");
var _helpers3 = require("../../helpers");
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 _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 {
  COMPARE,
  GTM
} = _Core.PERFORMANCE || {};
let counter = 0;
let memoizedPendingEvents = [];
const PerformanceManager = () => {
  const device = (0, _ui.useDevice)();
  const _useStore = (0, _dataSources.useStore)(),
    {
      value: {
        performance: storePerformance = []
      }
    } = _useStore,
    store = _objectWithoutProperties(_useStore.value, _excluded);
  const [consentMode, setConsentMode] = (0, _react.useState)((0, _helpers.getConsentMode)());
  const [performance, setPerformance] = (0, _react.useState)(storePerformance);
  const {
    components,
    finder: {
      place
    } = {},
    hotel = {},
    id: instanceId,
    session,
    type
  } = store;
  (0, _react.useEffect)(() => {
    const handleMetrics = _ref => {
      let {
          id
        } = _ref,
        props = _objectWithoutProperties(_ref, _excluded2);
      if (!id || window.IS_PLAYWRIGHT || window.location.host === 'monalisa.mirai.com') return;
      _services.ServiceAnna.track(_objectSpread(_objectSpread({}, props), {}, {
        eventName: id,
        hotel: hotel.id,
        chain: type === 'chain' ? instanceId : undefined,
        session
      }));
    };
    _dataSources.Event.subscribe(_helpers2.EVENT.METRICS, handleMetrics);
    return () => _dataSources.Event.unsubscribe(_helpers2.EVENT.METRICS, handleMetrics);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);
  (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 {
          provider
        } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
        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;
        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,
      finder: {
        place: {
          id: [hotelId] = [],
          isHotel
        } = {}
      } = {}
    } = store;
    if (place) {
      setPerformance((0, _helpers3.getPerformance)(config, isHotel ? hotelId : undefined));
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [place]);
  (0, _react.useEffect)(() => {
    const handleEvent = _ref2 => {
      let {
          event
        } = _ref2,
        value = _objectWithoutProperties(_ref2, _excluded3);
      if (performance.length === 0) return;
      const currentConsentMode = (0, _helpers.getConsentMode)(true);
      const availableProviders = performance.map(function () {
        let {
          type
        } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
        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(_ref3 => {
        let [propProvider, callback = () => {}] = _ref3;
        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 {
      provider,
      callback,
      value,
      event
    } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
    let nextConsentMode = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : consentMode;
    loadScripts(performance.filter(function () {
      let {
        type
      } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
      return type === provider && type !== COMPARE;
    }), nextConsentMode).then(() => {
      const config = performance.find(_ref4 => {
        let {
          type
        } = _ref4;
        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 {
            type
          } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
          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 {
        type
      } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
      return propConsentMode === true || !_PerformanceManager.CONSENT_MODE_REQUIRED.includes(type);
    }).forEach(function () {
      let {
        type,
        instances: propInstances = []
      } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
      const {
        components = [],
        init = () => {},
        once = false
      } = _PerformanceManager3.SCRIPTS[type] || {};
      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,
            instanceId,
            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