"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.ChatWrapper = void 0;
var _react = _interopRequireWildcard(require("react"));
var _reactRedux = require("react-redux");
var _ChatRoom = _interopRequireDefault(require("./ChatRoom"));
var _chatSettingsSlice = require("../../roomStore/chatSettingsSlice");
var _ChatWrapperBox = require("../styled/ChatWrapperBox");
var _MediaModal = require("../styled/MediaModal");
var _ConnectionBanner = _interopRequireDefault(require("./ConnectionBanner"));
var _Message = require("../MessageBubble/Message");
var _xmppProvider = require("../../context/xmppProvider");
var _Login = _interopRequireDefault(require("../AuthForms/Login"));
var _Loader = _interopRequireDefault(require("../styled/Loader"));
var _roomsSlice = require("../../roomStore/roomsSlice");
var _apiClient = require("../../networking/apiClient");
var _RoomList = _interopRequireDefault(require("./RoomList"));
var _StyledComponents = require("../styled/StyledComponents");
var _Modal = _interopRequireDefault(require("../Modals/Modal/Modal"));
var _ModalWrapper = require("../Modals/ModalWrapper/ModalWrapper");
var _useChatSettingState = require("../../hooks/useChatSettingState");
var _reactNative = require("react-native");
var _devLogger = require("../../utils/devLogger");
var _normalizeRoomJid = require("../../helpers/normalizeRoomJid");
var _buildSeedRoom = require("../../helpers/buildSeedRoom");
var _InteractionsOverlay = require("../MessageBubble/InteractionsOverlay");
var _jsxRuntime = require("react/jsx-runtime");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
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); }
const ChatWrapper = ({
  MainComponentStyles,
  CustomMessageComponent,
  room,
  config,
  roomJID
}) => {
  const {
    user,
    activeModal,
    deleteModal,
    client: storedClient
  } = (0, _useChatSettingState.useChatSettingState)();
  const [isInited, setInited] = (0, _react.useState)(false);
  const [showModal, setShowModal] = (0, _react.useState)(false);
  const [errorMsg, setErrorMsg] = (0, _react.useState)(null);
  // const [isModalDeleteOpen, setIsModalDeleteOpen] = useState(false);

  const [isChatVisible, setIsChatVisible] = (0, _react.useState)(false);
  const [isSmallScreen, setIsSmallScreen] = (0, _react.useState)(false);
  const handleItemClick = value => {
    setIsChatVisible(value);
  };
  const dispatch = (0, _reactRedux.useDispatch)();
  const {
    client,
    initializeClient,
    setClient,
    providerBootstrapStatus,
    initMode
  } = (0, _xmppProvider.useXmppClient)();
  const {
    rooms,
    activeRoomJID
  } = (0, _reactRedux.useSelector)(state => state.rooms);
  const activeMessage = (0, _react.useMemo)(() => {
    if (activeRoomJID) {
      return rooms[activeRoomJID]?.messages?.find(message => message?.activeMessage);
    }
  }, [rooms, activeRoomJID]);
  const handleChangeChat = chat => {
    dispatch((0, _roomsSlice.setCurrentRoom)({
      roomJID: chat.jid
    }));
    activeRoomJID !== chat.jid && dispatch((0, _roomsSlice.setIsLoading)({
      chatJID: chat.jid,
      loading: true
    }));
    dispatch((0, _roomsSlice.setEditAction)({
      isEdit: false
    }));
    handleItemClick(true);
  };
  const handleDeleteClick = () => {
    if (!client || !deleteModal?.roomJid || !deleteModal?.messageId) {
      dispatch((0, _chatSettingsSlice.setDeleteModal)({
        isDeleteModal: false
      }));
      return;
    }
    client.deleteMessageStanza(deleteModal.roomJid, deleteModal.messageId);
    dispatch((0, _chatSettingsSlice.setDeleteModal)({
      isDeleteModal: false
    }));
  };
  const handleCloseDeleteModal = () => {
    dispatch((0, _chatSettingsSlice.setDeleteModal)({
      isDeleteModal: false
    }));
  };
  (0, _react.useEffect)(() => {
    return () => {
      if (client && user.xmppPassword === '') {
        console.log('closing client');
        client.close();
        setClient(null);
      }
    };
  }, [user.xmppPassword]);

  // Tell the XMPP client which room is currently active so the QoS
  // scheduler can prioritize its history fetches.
  (0, _react.useEffect)(() => {
    if (!client) {
      return;
    }
    client.setActiveRoomJid?.(activeRoomJID || null);
  }, [client, activeRoomJID]);
  const seededRoomJID = (0, _react.useMemo)(() => roomJID ? (0, _normalizeRoomJid.normalizeRoomJid)(roomJID, config?.xmppSettings?.conference) : '', [roomJID, config?.xmppSettings?.conference]);
  const seededRoomMissing = !!seededRoomJID && !rooms[seededRoomJID];
  (0, _react.useEffect)(() => {
    if (!seededRoomJID || !seededRoomMissing) {
      return;
    }
    (0, _devLogger.pushLog)('rn', `ChatWrapper: seeding minimal room for single-room JID ${seededRoomJID}`);
    dispatch((0, _roomsSlice.addRoom)({
      roomData: (0, _buildSeedRoom.buildSeedRoom)(seededRoomJID)
    }));
  }, [seededRoomJID, seededRoomMissing, dispatch]);
  (0, _react.useEffect)(() => {
    if (roomJID) {
      dispatch((0, _roomsSlice.setCurrentRoom)({
        roomJID: (0, _normalizeRoomJid.normalizeRoomJid)(roomJID, config?.xmppSettings?.conference)
      }));
    }
    const initXmmpClient = async () => {
      // Only sync config to redux if we have one — passing `undefined`
      // wipes whatever XmppProvider already set up.
      if (config) {
        dispatch((0, _chatSettingsSlice.setConfig)(config));
      }
      try {
        const hasUser = !!user?.defaultWallet?.walletAddress && user?.defaultWallet.walletAddress !== '' && !!user?.xmppPassword;

        // initBeforeLoad path — provider owns auth + xmpp connect; we just wait.
        if (config?.initBeforeLoad && initMode === 'provider') {
          if (providerBootstrapStatus === 'failed') {
            (0, _devLogger.pushLog)('error', 'ChatWrapper: bootstrap failed');
            setErrorMsg('Could not authenticate against the server.\n' + 'Check baseUrl, XMPP host fields, and the token / credentials you entered.');
            setShowModal(true);
            setInited(false);
            return;
          }
          if (providerBootstrapStatus !== 'ready') {
            // 'idle' or 'running' → just wait; effect will re-run when status flips.
            (0, _devLogger.pushLog)('rn', `ChatWrapper: waiting for provider (${providerBootstrapStatus})`);
            return;
          }
          // ready — fall through to client wiring below
        }
        if (!hasUser) {
          // No user yet. In initBeforeLoad mode this is normal during the
          // bootstrap window; show the loader (no modal). In legacy mode
          // it's an error.
          if (config?.initBeforeLoad) {
            (0, _devLogger.pushLog)('rn', 'ChatWrapper: no user yet, awaiting provider');
            setShowModal(false);
            return;
          }
          (0, _devLogger.pushLog)('error', 'ChatWrapper: no user (legacy login path)');
          setErrorMsg('No authenticated user available.\n' + 'For JWT login pass `jwtLogin.token`; for email login pass the `user={{email,password}}` prop and `customAppToken`.');
          setShowModal(true);
          return;
        }

        // We have a user. Modal should be down.
        setShowModal(false);
        setErrorMsg(null);
        if (!client && !storedClient) {
          (0, _devLogger.pushLog)('rn', 'ChatWrapper: initing xmpp client (legacy path)');
          // The outer `.then(c => {...})` used to lack a `.catch()` —
          // if initializeClient rejected (network / SASL), the outer
          // try/catch couldn't see it because the rejection happens in
          // the .then handler, not in the awaited promise itself.
          // Convert to await + try/catch.
          try {
            const c = await initializeClient(user.xmppUsername || user.defaultWallet?.walletAddress, user.xmppPassword, config?.xmppSettings);
            try {
              await c.getRoomsStanza();
              c.getChatsPrivateStoreRequestStanza().catch(err => console.warn('getChatsPrivateStoreRequestStanza failed', err));
              dispatch((0, _chatSettingsSlice.setStoreClient)(c));
              setClient(c);
            } catch (err) {
              console.warn('getRoomsStanza failed', err);
            }
          } catch (err) {
            (0, _devLogger.pushLog)('warn', 'initializeClient failed (legacy path)', err);
          }
          setInited(true);
          if (config?.refreshTokens?.enabled) {
            // refresh() is fire-and-forget but rejects on bad
            // refreshToken / network — surface via .catch instead of
            // leaving the rejection unhandled (was bug #4, id:2).
            (0, _apiClient.refresh)().catch(err => console.warn('refresh failed', err));
          }
        } else if (storedClient) {
          (0, _devLogger.pushLog)('rn', 'ChatWrapper: reusing storedClient');
          setClient(storedClient);
          if (!activeRoomJID) {
            storedClient.getRoomsStanza().then(() => {
              storedClient.getChatsPrivateStoreRequestStanza().catch(err => console.warn('getChatsPrivateStoreRequestStanza failed', err));
            }).catch(err => console.warn('getRoomsStanza failed', err));
          }
          setInited(true);
          if (config?.refreshTokens?.enabled) {
            (0, _apiClient.refresh)().catch(err => console.warn('refresh failed', err));
          }
        } else if (client) {
          (0, _devLogger.pushLog)('rn', 'ChatWrapper: reusing provider client');
          if (!activeRoomJID) {
            client.getRoomsStanza().then(() => {
              client.getChatsPrivateStoreRequestStanza().catch(err => console.warn('getChatsPrivateStoreRequestStanza failed', err));
            }).catch(err => console.warn('getRoomsStanza failed', err));
          }
          client.getChatsPrivateStoreRequestStanza().catch(err => console.warn('getChatsPrivateStoreRequestStanza failed', err));
          setInited(true);
          if (config?.refreshTokens?.enabled) {
            (0, _apiClient.refresh)().catch(err => console.warn('refresh failed', err));
          }
        }
        dispatch((0, _roomsSlice.setIsLoading)({
          loading: false
        }));
      } catch (error) {
        (0, _devLogger.pushLog)('error', 'ChatWrapper: init failed', error);
        const msg = error?.response?.data?.message || error?.message || String(error);
        setErrorMsg(`Init failed: ${msg}`);
        setShowModal(true);
        setInited(false);
        dispatch((0, _roomsSlice.setIsLoading)({
          loading: false
        }));
      }
    };
    initXmmpClient();
  }, [user.xmppPassword, user.defaultWallet, providerBootstrapStatus, initMode, config?.initBeforeLoad]);

  // Cache-first display (initBeforeLoad). The main effect above only marks
  // the chat `inited` once the provider bootstrap reaches 'ready' — which
  // waits on the cold XMPP connect. On re-entry that left the user staring
  // at a loader while fully-cached rooms/messages sat in redux-persist
  // ("pulls a new connection for 100 years"). Here we render the cached
  // content the instant rehydration lands; the live client gets wired by
  // the main effect when the connect completes (send/loadMore activate
  // then). Mirrors web showing cached rooms immediately + refreshing in
  // the background.
  (0, _react.useEffect)(() => {
    if (!config?.initBeforeLoad || initMode !== 'provider') {
      return;
    }
    if (isInited || showModal) {
      return;
    }
    if (providerBootstrapStatus === 'failed') {
      return;
    }
    const haveCachedRooms = !!rooms && Object.keys(rooms).length > 0;
    const haveUser = !!user?.xmppUsername || !!user?.defaultWallet?.walletAddress;
    if (haveCachedRooms && haveUser) {
      (0, _devLogger.pushLog)('rn', 'ChatWrapper: cache-first — showing persisted rooms while provider connects');
      setShowModal(false);
      setInited(true);
    }
  }, [config?.initBeforeLoad, initMode, isInited, showModal, providerBootstrapStatus, rooms, user?.xmppUsername, user?.defaultWallet?.walletAddress]);

  // Skip the legacy email/password LoginForm entirely when XmppProvider
  // is driving auth via initBeforeLoad — the bootstrap effect will
  // populate the user shortly. Showing LoginForm here causes a flicker
  // and (worse) a stale form that races against the in-flight bootstrap.
  if (user.xmppPassword === '' && user.xmppUsername === '' && !config?.initBeforeLoad) {
    return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Login.default, {
      config: config
    });
  }

  // Mirror the web layout: when `disableRooms` is false and the
  // consumer didn't preselect a `roomJID`, show the RoomList until the
  // user picks one; then show the chat with a back button to return to
  // the list. With `roomJID` or `disableRooms`, skip the list entirely.
  const showRoomList = !config?.disableRooms && !roomJID && !activeRoomJID;
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
    children: [showModal && config?.disableConnectionErrorOverlay && /*#__PURE__*/(0, _jsxRuntime.jsx)(_ConnectionBanner.default, {}), showModal && !config?.disableConnectionErrorOverlay && /*#__PURE__*/(0, _jsxRuntime.jsx)(_MediaModal.Overlay, {
      children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
        style: {
          padding: 20,
          backgroundColor: '#fff',
          borderRadius: 12,
          maxWidth: 320,
          alignItems: 'stretch'
        },
        children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
          style: {
            fontSize: 16,
            fontWeight: '600',
            marginBottom: 8,
            color: '#222'
          },
          children: "Connection error"
        }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
          style: {
            fontSize: 13,
            color: '#444',
            marginBottom: 16
          },
          children: errorMsg ?? 'Something went wrong while connecting to chat.'
        }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
          onPress: () => {
            setShowModal(false);
            setErrorMsg(null);
            setInited(false);
            // Signal a clean re-bootstrap. XmppProvider listens and
            // resets its state machine so the next effect run resolves
            // the user from scratch.
            _reactNative.DeviceEventEmitter.emit('ethora:retryBootstrap');
          },
          style: ({
            pressed
          }) => ({
            paddingVertical: 10,
            paddingHorizontal: 16,
            borderRadius: 6,
            backgroundColor: pressed ? '#0040A0' : '#0052CD',
            alignItems: 'center'
          }),
          children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
            style: {
              color: '#fff',
              fontWeight: '600'
            },
            children: "Retry"
          })
        })]
      })
    }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
      children: isInited ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_ChatWrapperBox.ChatWrapperBox, {
        style: {
          ...MainComponentStyles
        },
        children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_InteractionsOverlay.InteractionsOverlayProvider, {
          children: showRoomList ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_RoomList.default, {
            chats: Object.values(rooms),
            onRoomClick: handleChangeChat
          }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_ChatWrapperBox.ChatWrapperBox, {
            style: {
              ...MainComponentStyles
            },
            children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_ChatRoom.default, {
              CustomMessageComponent: CustomMessageComponent || _Message.Message,
              handleBackClick: roomJID || config?.disableRooms ? undefined : () => {
                dispatch((0, _roomsSlice.setCurrentRoom)({
                  roomJID: ''
                }));
              }
            })
          })
        }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Modal.default, {
          modal: activeModal,
          setOpenModal: value => dispatch((0, _chatSettingsSlice.setActiveModal)(value))
        }), deleteModal?.isDeleteModal && /*#__PURE__*/(0, _jsxRuntime.jsx)(_ModalWrapper.ModalWrapper, {
          title: "Delete Message",
          description: "Are you sure you want to delete this message?",
          buttonText: "Delete",
          backgroundColorButton: "#E53935",
          handleClick: handleDeleteClick,
          handleCloseModal: handleCloseDeleteModal,
          compact: true
        })]
      }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_StyledComponents.StyledLoaderWrapper, {
        children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Loader.default, {
          color: config?.colors?.primary
        })
      })
    })]
  });
};
exports.ChatWrapper = ChatWrapper;
//# sourceMappingURL=ChatWrapper.js.map