"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.Chat = void 0;
var _dataSources = require("@mirai/data-sources");
var _locale = require("@mirai/locale");
var _services = require("@mirai/services");
var _ui = require("@mirai/ui");
var _react = _interopRequireWildcard(require("react"));
var _Chat = require("./Chat.constants");
var _Chat2 = require("./Chat.l10n");
var style = _interopRequireWildcard(require("./Chat.module.css"));
var _components = require("./components");
var _Aura = require("./components/Aura/Aura");
var _helpers = require("./helpers");
var _lobby = require("./services/lobby.service");
var _Core = require("../../Core.constants");
var _helpers2 = require("../helpers");
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
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 _objectDestructuringEmpty(t) { if (null == t) throw new TypeError("Cannot destructure " + t); }
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
let client;
const Chat = _ref => {
  var _channelSettings$web, _channelSettings$ai;
  let others = _extends({}, (_objectDestructuringEmpty(_ref), _ref));
  const {
    translate
  } = (0, _locale.useLocale)();
  const {
    isMobile
  } = (0, _ui.useDevice)();
  const {
    value: {
      calendar,
      components = {},
      currency,
      hotel,
      id,
      locale,
      occupation,
      origin,
      session,
      skeleton = false,
      type
    } = {}
  } = (0, _dataSources.useStore)();
  const [busy, setBusy] = (0, _react.useState)(false);
  const [channelSettings, setChannelSettings] = (0, _react.useState)();
  const [inputMode, setInputMode] = (0, _react.useState)();
  const [messages, setMessages] = (0, _react.useState)([]);
  const [visible, setVisible] = (0, _react.useState)(false);
  (0, _react.useEffect)(() => {
    if (skeleton) return;
    _dataSources.Event.subscribe(_helpers2.EVENT.CHAT_OPEN, handleOpen);
    return () => _dataSources.Event.unsubscribe(_helpers2.EVENT.CHAT_OPEN, handleOpen);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [skeleton]);
  (0, _react.useEffect)(() => {
    if (skeleton || !id) {
      setChannelSettings();
      return;
    }
    let active = true;
    const loadSettings = async () => {
      const channel = await (0, _lobby.getChannelSettings)({
        channelId: id
      });
      if (!active) return;
      setChannelSettings(channel === null || channel === void 0 ? void 0 : channel.settings);
    };
    loadSettings();
    return () => {
      active = false;
    };
  }, [id, skeleton]);
  (0, _react.useEffect)(() => {
    var _client;
    if (!visible || inputMode !== _Chat.INPUT_MODE.TEXT) return (_client = client) === null || _client === void 0 ? void 0 : _client.disconnect();
    client = new _helpers.ClientLobby({
      channelId: id,
      session
    });
    client.onMessage(message => {
      var _client2;
      const {
        author,
        body,
        createdAt,
        fingerprint
      } = message || {};
      if (fingerprint !== ((_client2 = client) === null || _client2 === void 0 ? void 0 : _client2.fingerprint) || author !== 'human') return;
      setMessages(prev => [...prev, {
        synapse: true,
        text: body,
        timestamp: createdAt
      }]);
    });
    client.connect();
  }, [id, inputMode, session, visible]);
  const handleInput = function (input) {
    var _client3;
    let shortcutMessage = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
    const nextMessages = [...messages, {
      text: input,
      timestamp: new Date().getTime()
    }];
    setMessages(nextMessages);
    (_client3 = client) === null || _client3 === void 0 ? void 0 : _client3.send({
      body: input
    });
    setTimeout(async () => {
      var _client4;
      if ((_client4 = client) !== null && _client4 !== void 0 && _client4.aiBlocked) return;
      setBusy(true);
      const context = {
        calendar,
        currency,
        isMobile,
        locale,
        occupation,
        origin,
        shortcutMessage
      };
      if (type === _Core.TYPE.CHAIN) context.chain = {
        id
      };
      if (hotel.id) context.hotel = hotel;
      const response = await _services.ServiceSynapse.message({
        context,
        input,
        session,
        mcp: false
      }).catch(() => {});
      if (response) {
        var _client5;
        setMessages([...nextMessages, _objectSpread({
          synapse: true
        }, response)]);
        (_client5 = client) === null || _client5 === void 0 ? void 0 : _client5.send({
          body: response.text,
          author: 'ai'
        });

        // ! TODO: Handle locale
        // if (response.locale !== locale) Event.publish(EVENT.INTENT_LOCALE, { locale: response.locale });
        (0, _helpers.audioNotification)();
      }
      setBusy(false);
    }, _Chat.DELAY_RESPONSE);
  };
  const handleInputMode = next => {
    _dataSources.Event.publish(_helpers2.EVENT.METRICS, {
      id: _helpers2.METRICS_EVENTS.SARAI_INTERACTION,
      action: 'click',
      method: next
    });
    if (next === _Chat.INPUT_MODE.WHATSAPP) return handleClose();
    setInputMode(next);
  };
  const handleOpen = function () {
    let {
      source = _Core.SARAI_SOURCE
    } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
    setVisible(true);
    _dataSources.Event.publish(_helpers2.EVENT.CHAT_OPENED, {
      event: _helpers2.EVENT.CHAT_OPENED,
      source
    });
    _dataSources.Event.publish(_helpers2.EVENT.METRICS, {
      id: _helpers2.METRICS_EVENTS.SARAI_INTERACTION,
      action: 'open',
      method: inputMode
    });
  };
  const handleClose = () => {
    _dataSources.Event.publish(_helpers2.EVENT.CHAT_CLOSE, {
      inputMode
    });
    _dataSources.Event.publish(_helpers2.EVENT.METRICS, {
      id: _helpers2.METRICS_EVENTS.SARAI_INTERACTION,
      action: 'close',
      method: inputMode
    });
    setVisible(false);
    setInputMode();
  };
  const isReady = !skeleton && Object.keys(components).every(item => !_Chat.BANNED_COMPONENTS.includes(item)) && (channelSettings === null || channelSettings === void 0 ? void 0 : (_channelSettings$web = channelSettings.web) === null || _channelSettings$web === void 0 ? void 0 : _channelSettings$web.active);
  const {
    entities = {}
  } = messages[messages.length - 1] || {};
  return isReady ? /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_ui.Modal, _extends({}, others, {
    fit: true,
    portal: true,
    visible: visible,
    className: (0, _ui.styles)(style.container, others.className)
  }), /*#__PURE__*/_react.default.createElement(_components.Header, {
    settings: channelSettings,
    onClose: handleClose
  }), !inputMode ? /*#__PURE__*/_react.default.createElement(_components.Welcome, {
    settings: channelSettings,
    onInputMode: handleInputMode
  }) : inputMode === _Chat.INPUT_MODE.TEXT ? /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_ui.ScrollView, {
    scrollTo: new Date().getTime(),
    snap: false,
    className: style.messages
  }, messages.map((message, index) => /*#__PURE__*/_react.default.createElement(_components.Message, _extends({
    key: "message:".concat(index),
    disabled: busy || index < messages.length - 1
  }, message))), busy && /*#__PURE__*/_react.default.createElement(_components.Message, {
    busy: true,
    synapse: true
  })), /*#__PURE__*/_react.default.createElement(_components.Input, {
    disabled: busy,
    entities: entities,
    onValue: handleInput,
    className: style.input
  })) : inputMode === _Chat.INPUT_MODE.AUDIO ? /*#__PURE__*/_react.default.createElement(_Aura.Aura, {
    settings: channelSettings,
    onCallEnd: () => setInputMode(_Chat.INPUT_MODE.RATING)
  }) : inputMode === _Chat.INPUT_MODE.RATING ? /*#__PURE__*/_react.default.createElement(_components.Rating, {
    onRejoin: () => setInputMode(_Chat.INPUT_MODE.AUDIO),
    onReturnHome: handleClose
  }) : null, /*#__PURE__*/_react.default.createElement(_ui.Text, {
    light: true,
    tiny: true,
    className: style.warning
  }, translate(_Chat2.L10N.LABEL_WARNING_RESPONSES, {
    name: (channelSettings === null || channelSettings === void 0 ? void 0 : (_channelSettings$ai = channelSettings.ai) === null || _channelSettings$ai === void 0 ? void 0 : _channelSettings$ai.name) || _Chat.DEFAULT_NAME
  }))), /*#__PURE__*/_react.default.createElement(_components.ButtonDispatcher, {
    settings: channelSettings,
    visible: visible,
    onPress: handleOpen
  })) : null;
};
exports.Chat = Chat;
//# sourceMappingURL=Chat.js.map