"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.useChatConfig = void 0;
var _react = require("react");
var _useLocalStorage = _interopRequireDefault(require("react-use/lib/useLocalStorage"));
var _services = require("../../services");
var _get_chat_context = require("./get_chat_context");
/*
 * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
 * or more contributor license agreements. Licensed under the Elastic License
 * 2.0; you may not use this file except in compliance with the Elastic License
 * 2.0.
 */

const MESSAGE_WIDGET_READY = 'driftWidgetReady';
const MESSAGE_IFRAME_READY = 'driftIframeReady';
const MESSAGE_RESIZE = 'driftIframeResize';
const MESSAGE_SET_CONTEXT = 'driftSetContext';
const MESSAGE_CHAT_CLOSED = 'driftChatClosed';
const MESSAGE_PLAYBOOK_FIRED = 'driftPlaybookFired';
/**
 * Hook which handles positioning and communication with the chat widget.
 */
const useChatConfig = ({
  onReady = () => {},
  onResize = () => {},
  onPlaybookFired = () => {},
  controlled = true
}) => {
  const ref = (0, _react.useRef)(null);
  const chat = (0, _services.useChat)();
  const [style, setStyle] = (0, _react.useState)({
    height: 0,
    width: 0
  });
  const [isReady, setIsReady] = (0, _react.useState)(false);
  const [isResized, setIsResized] = (0, _react.useState)(false);
  const isChatOpenRef = (0, _react.useRef)(false);
  const [hasPlaybookFiredOnce, setPlaybookFiredOnce] = (0, _useLocalStorage.default)('cloudChatPlaybookFiredOnce', false);
  (0, _react.useEffect)(() => {
    const handleMessage = event => {
      const {
        current: chatIframe
      } = ref;
      if (!chat || !(chatIframe !== null && chatIframe !== void 0 && chatIframe.contentWindow) || event.source !== (chatIframe === null || chatIframe === void 0 ? void 0 : chatIframe.contentWindow)) {
        return;
      }
      const context = (0, _get_chat_context.getChatContext)();
      const {
        data: message
      } = event;
      const {
        user: userConfig,
        chatVariant
      } = chat;
      const {
        id,
        email,
        jwt,
        trialEndDate,
        kbnVersion,
        kbnBuildNum
      } = userConfig;
      const chatApi = {
        show: () => {
          var _ref$current, _ref$current$contentW, _ref$current2, _ref$current2$content;
          (_ref$current = ref.current) === null || _ref$current === void 0 ? void 0 : (_ref$current$contentW = _ref$current.contentWindow) === null || _ref$current$contentW === void 0 ? void 0 : _ref$current$contentW.postMessage({
            type: `driftShow`
          }, '*');
          (_ref$current2 = ref.current) === null || _ref$current2 === void 0 ? void 0 : (_ref$current2$content = _ref$current2.contentWindow) === null || _ref$current2$content === void 0 ? void 0 : _ref$current2$content.postMessage({
            type: `driftOpenChat`
          }, '*');
          isChatOpenRef.current = true;
        },
        hide: () => {
          var _ref$current3, _ref$current3$content;
          (_ref$current3 = ref.current) === null || _ref$current3 === void 0 ? void 0 : (_ref$current3$content = _ref$current3.contentWindow) === null || _ref$current3$content === void 0 ? void 0 : _ref$current3$content.postMessage({
            type: `driftHide`
          }, '*');
          isChatOpenRef.current = false;
        },
        toggle: () => {
          if (isChatOpenRef.current) {
            chatApi.hide();
          } else {
            chatApi.show();
          }
        }
      };
      switch (message.type) {
        // The IFRAME is ready to receive messages.
        case MESSAGE_IFRAME_READY:
          {
            const user = {
              id,
              attributes: {
                email,
                trial_end_date: trialEndDate,
                kbn_version: kbnVersion,
                kbn_build_num: kbnBuildNum,
                kbn_chat_variant: chatVariant
              },
              jwt
            };
            chatIframe.contentWindow.postMessage({
              type: MESSAGE_SET_CONTEXT,
              data: {
                context,
                user
              }
            }, '*');
            break;
          }

        // Drift is attempting to resize the IFRAME based on interactions with
        // its interface.
        case MESSAGE_RESIZE:
          {
            const styles = message.data.styles || {};
            // camelize to avoid style warnings from react
            const camelize = s => s.replace(/-./g, x => x[1].toUpperCase());
            const camelStyles = Object.keys(styles).reduce((acc, key) => {
              acc[camelize(key)] = styles[key];
              return acc;
            }, {});
            setStyle({
              ...style,
              ...camelStyles
            });
            if (!isResized) {
              setIsResized(true);
            }
            onResize();
            break;
          }

        // The chat widget is ready.
        case MESSAGE_WIDGET_READY:
          if (controlled) chatApi.hide();
          setIsReady(true);
          onReady(chatApi);
          if (hasPlaybookFiredOnce) {
            // The `MESSAGE_PLAYBOOK_FIRED` event is only fired until the interaction,
            // so we need to manually trigger the callback if the event has already fired.
            // otherwise, users might have an ongoing conversion, but they can't get back to it
            onPlaybookFired();
          }
          break;
        case MESSAGE_CHAT_CLOSED:
          if (controlled) chatApi.hide();
          break;
        case MESSAGE_PLAYBOOK_FIRED:
          onPlaybookFired();
          setPlaybookFiredOnce(true);
          break;
        default:
          break;
      }
    };
    window.addEventListener('message', handleMessage);
    return () => window.removeEventListener('message', handleMessage);
  }, [chat, style, onReady, onResize, isReady, isResized, controlled, hasPlaybookFiredOnce, onPlaybookFired, setPlaybookFiredOnce]);
  if (chat) {
    return {
      enabled: true,
      src: chat.chatURL,
      ref,
      style,
      isReady,
      isResized
    };
  }
  return {
    enabled: false
  };
};
exports.useChatConfig = useChatConfig;