'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var React = require('react');
var useSendbirdStateContext = require('../useSendbirdStateContext.js');
var _rollupPluginBabelHelpers = require('../_rollupPluginBabelHelpers-acf412a3.js');
require('../withSendbird.js');

function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }

var React__default = /*#__PURE__*/_interopDefaultLegacy(React);

const GET_SEARCHED_MESSAGES = 'GET_SEARCHED_MESSAGES';
const GET_NEXT_SEARCHED_MESSAGES = 'GET_NEXT_SEARCHED_MESSAGES';
const START_MESSAGE_SEARCH = 'START_MESSAGE_SEARCH';
const START_GETTING_SEARCHED_MESSAGES = 'START_GETTING_SEARCHED_MESSAGES';
const SET_QUERY_INVALID = 'SET_QUERY_INVALID';
const SET_CURRENT_CHANNEL = 'SET_CURRENT_CHANNEL';
const CHANNEL_INVALID = 'CHANNEL_INVALID';
const RESET_SEARCH_STRING = 'RESET_SEARCH_STRING';

function reducer(state, action) {
  switch (action.type) {
    case SET_CURRENT_CHANNEL:
      {
        const currentChannel = action.payload;
        return _rollupPluginBabelHelpers._objectSpread2(_rollupPluginBabelHelpers._objectSpread2({}, state), {}, {
          currentChannel,
          initialized: true
        });
      }
    case CHANNEL_INVALID:
      {
        return _rollupPluginBabelHelpers._objectSpread2(_rollupPluginBabelHelpers._objectSpread2({}, state), {}, {
          currentChannel: null,
          initialized: false
        });
      }
    case GET_SEARCHED_MESSAGES:
      {
        const {
          messages,
          createdQuery
        } = action.payload;
        if (createdQuery && createdQuery.channelUrl === (state === null || state === void 0 ? void 0 : state.currentMessageSearchQuery).channelUrl && createdQuery.key === (state === null || state === void 0 ? void 0 : state.currentMessageSearchQuery).key) {
          return _rollupPluginBabelHelpers._objectSpread2(_rollupPluginBabelHelpers._objectSpread2({}, state), {}, {
            loading: false,
            isInvalid: false,
            allMessages: [...messages],
            hasMoreResult: (state === null || state === void 0 ? void 0 : state.currentMessageSearchQuery).hasNext
          });
        }
        return _rollupPluginBabelHelpers._objectSpread2({}, state);
      }
    case SET_QUERY_INVALID:
      {
        return _rollupPluginBabelHelpers._objectSpread2(_rollupPluginBabelHelpers._objectSpread2({}, state), {}, {
          isInvalid: true
        });
      }
    case START_MESSAGE_SEARCH:
      {
        return _rollupPluginBabelHelpers._objectSpread2(_rollupPluginBabelHelpers._objectSpread2({}, state), {}, {
          isInvalid: false,
          loading: false
        });
      }
    case START_GETTING_SEARCHED_MESSAGES:
      {
        const currentMessageSearchQuery = action.payload;
        return _rollupPluginBabelHelpers._objectSpread2(_rollupPluginBabelHelpers._objectSpread2({}, state), {}, {
          loading: true,
          currentMessageSearchQuery
        });
      }
    case GET_NEXT_SEARCHED_MESSAGES:
      {
        const messages = action.payload;
        return _rollupPluginBabelHelpers._objectSpread2(_rollupPluginBabelHelpers._objectSpread2({}, state), {}, {
          allMessages: [...state.allMessages, ...messages],
          hasMoreResult: (state === null || state === void 0 ? void 0 : state.currentMessageSearchQuery).hasNext
        });
      }
    case RESET_SEARCH_STRING:
      {
        return _rollupPluginBabelHelpers._objectSpread2(_rollupPluginBabelHelpers._objectSpread2({}, state), {}, {
          allMessages: []
        });
      }
    default:
      {
        return state;
      }
  }
}

const initialState = {
  allMessages: [],
  loading: false,
  isInvalid: false,
  initialized: false,
  currentChannel: null,
  currentMessageSearchQuery: null,
  hasMoreResult: false
};

function useSetChannel(_ref, _ref2) {
  let {
    channelUrl,
    sdkInit
  } = _ref;
  let {
    sdk,
    logger,
    messageSearchDispatcher
  } = _ref2;
  React.useEffect(() => {
    if (channelUrl && sdkInit && sdk !== null && sdk !== void 0 && sdk.groupChannel) {
      sdk.groupChannel.getChannel(channelUrl).then(groupChannel => {
        logger.info('MessageSearch | useSetChannel group channel', groupChannel);
        messageSearchDispatcher({
          type: SET_CURRENT_CHANNEL,
          payload: groupChannel
        });
      }).catch(() => {
        messageSearchDispatcher({
          type: CHANNEL_INVALID,
          payload: null
        });
      });
    }
  }, [channelUrl, sdkInit]);
}

var MessageSearchOrder = /*#__PURE__*/function (MessageSearchOrder) {
  MessageSearchOrder["SCORE"] = "score";
  MessageSearchOrder["TIMESTAMP"] = "ts";
  return MessageSearchOrder;
}(MessageSearchOrder || {});
function useGetSearchedMessages(_ref, _ref2) {
  let {
    currentChannel,
    channelUrl,
    requestString,
    messageSearchQuery,
    onResultLoaded,
    retryCount
  } = _ref;
  let {
    sdk,
    logger,
    messageSearchDispatcher
  } = _ref2;
  React.useEffect(() => {
    messageSearchDispatcher({
      type: START_MESSAGE_SEARCH,
      payload: null
    });
    if (sdk && channelUrl && sdk.createMessageSearchQuery && currentChannel) {
      if (requestString) {
        currentChannel.refresh().then(channel => {
          const inputSearchMessageQueryObject = _rollupPluginBabelHelpers._objectSpread2({
            order: MessageSearchOrder.TIMESTAMP,
            channelUrl,
            messageTimestampFrom: channel.invitedAt,
            keyword: requestString
          }, messageSearchQuery);
          const createdQuery = sdk.createMessageSearchQuery(inputSearchMessageQueryObject);
          createdQuery.next().then(messages => {
            logger.info('MessageSearch | useGetSearchedMessages: succeeded getting messages', messages);
            messageSearchDispatcher({
              type: GET_SEARCHED_MESSAGES,
              payload: {
                messages,
                createdQuery
              }
            });
            if (onResultLoaded && typeof onResultLoaded === 'function') {
              onResultLoaded(messages, null);
            }
          }).catch(error => {
            logger.warning('MessageSearch | useGetSearchedMessages: getting failed', error);
            messageSearchDispatcher({
              type: SET_QUERY_INVALID,
              payload: null
            });
            if (onResultLoaded && typeof onResultLoaded === 'function') {
              onResultLoaded(null, error);
            }
          });
          messageSearchDispatcher({
            type: START_GETTING_SEARCHED_MESSAGES,
            payload: createdQuery
          });
        });
      } else {
        logger.info('MessageSearch | useGetSeasrchedMessages: search string is empty');
      }
    }
  }, [channelUrl, messageSearchQuery, requestString, currentChannel, retryCount]);
}

function useScrollCallback(_ref, _ref2) {
  let {
    currentMessageSearchQuery,
    hasMoreResult,
    onResultLoaded
  } = _ref;
  let {
    logger,
    messageSearchDispatcher
  } = _ref2;
  return React.useCallback(cb => {
    if (!hasMoreResult) {
      logger.warning('MessageSearch | useScrollCallback: no more searched results', hasMoreResult);
    }
    if (currentMessageSearchQuery && currentMessageSearchQuery.hasNext) {
      currentMessageSearchQuery.next().then(messages => {
        logger.info('MessageSearch | useScrollCallback: succeeded getting searched messages', messages);
        messageSearchDispatcher({
          type: GET_NEXT_SEARCHED_MESSAGES,
          payload: messages
        });
        cb(messages, null);
        if (onResultLoaded && typeof onResultLoaded === 'function') {
          onResultLoaded(messages, null);
        }
      }).catch(error => {
        logger.warning('MessageSearch | useScrollCallback: failed getting searched messages', error);
        cb(null, error);
        if (onResultLoaded && typeof onResultLoaded === 'function') {
          onResultLoaded(null, error);
        }
      });
    } else {
      logger.warning('MessageSearch | useScrollCallback: no currentMessageSearchQuery');
    }
  }, [currentMessageSearchQuery, hasMoreResult]);
}

const DEBOUNCING_TIME = 500;
function useSearchStringEffect(_ref, _ref2) {
  let {
    searchString
  } = _ref;
  let {
    messageSearchDispatcher
  } = _ref2;
  const [requestString, setRequestString] = React.useState('');
  const [debouncingTimer, setDebouncingTimer] = React.useState(null);
  React.useEffect(() => {
    clearTimeout(debouncingTimer);
    if (searchString) {
      setDebouncingTimer(setTimeout(() => {
        setRequestString(searchString);
      }, DEBOUNCING_TIME));
    } else {
      setRequestString('');
      messageSearchDispatcher({
        type: RESET_SEARCH_STRING,
        payload: ''
      });
    }
  }, [searchString]);
  return requestString;
}

const MessageSearchContext = /*#__PURE__*/React__default["default"].createContext(undefined);
const MessageSearchProvider = props => {
  var _globalState$config, _globalState$stores, _globalState$stores$s, _globalState$stores2, _globalState$stores2$;
  const {
    // message search props
    channelUrl,
    searchString,
    messageSearchQuery,
    onResultLoaded,
    onResultClick
  } = props;
  const globalState = useSendbirdStateContext();

  // hook variables
  const [retryCount, setRetryCount] = React.useState(0); // this is a trigger flag for activating useGetSearchMessages
  const [selectedMessageId, setSelectedMessageId] = React.useState(0);
  const [messageSearchStore, messageSearchDispatcher] = React.useReducer(reducer, initialState);
  const {
    allMessages,
    loading,
    isInvalid,
    currentChannel,
    currentMessageSearchQuery,
    hasMoreResult
  } = messageSearchStore;
  const logger = globalState === null || globalState === void 0 ? void 0 : (_globalState$config = globalState.config) === null || _globalState$config === void 0 ? void 0 : _globalState$config.logger;
  const sdk = globalState === null || globalState === void 0 ? void 0 : (_globalState$stores = globalState.stores) === null || _globalState$stores === void 0 ? void 0 : (_globalState$stores$s = _globalState$stores.sdkStore) === null || _globalState$stores$s === void 0 ? void 0 : _globalState$stores$s.sdk;
  const sdkInit = globalState === null || globalState === void 0 ? void 0 : (_globalState$stores2 = globalState.stores) === null || _globalState$stores2 === void 0 ? void 0 : (_globalState$stores2$ = _globalState$stores2.sdkStore) === null || _globalState$stores2$ === void 0 ? void 0 : _globalState$stores2$.initialized;
  const scrollRef = React.useRef(null);
  const handleOnScroll = e => {
    const scrollElement = e.target;
    const {
      scrollTop,
      scrollHeight,
      clientHeight
    } = scrollElement;
    if (!hasMoreResult) {
      return;
    }
    if (scrollTop + clientHeight >= scrollHeight) {
      onScroll(() => {
        // after load more searched messages
      });
    }
  };
  useSetChannel({
    channelUrl,
    sdkInit
  }, {
    sdk,
    logger,
    messageSearchDispatcher
  });
  const requestString = useSearchStringEffect({
    searchString
  }, {
    messageSearchDispatcher
  });
  useGetSearchedMessages({
    currentChannel,
    channelUrl,
    requestString,
    messageSearchQuery,
    onResultLoaded,
    retryCount
  }, {
    sdk,
    logger,
    messageSearchDispatcher
  });
  const onScroll = useScrollCallback({
    currentMessageSearchQuery,
    hasMoreResult,
    onResultLoaded
  }, {
    logger,
    messageSearchDispatcher
  });
  const handleRetryToConnect = () => {
    setRetryCount(retryCount + 1);
  };
  return /*#__PURE__*/React__default["default"].createElement(MessageSearchContext.Provider, {
    value: {
      channelUrl,
      searchString,
      requestString,
      messageSearchQuery,
      onResultLoaded,
      onResultClick,
      retryCount,
      setRetryCount,
      selectedMessageId,
      setSelectedMessageId,
      messageSearchDispatcher,
      allMessages,
      loading,
      isInvalid,
      currentChannel,
      currentMessageSearchQuery,
      hasMoreResult,
      onScroll,
      scrollRef,
      handleRetryToConnect,
      handleOnScroll
    }
  }, props === null || props === void 0 ? void 0 : props.children);
};
const useMessageSearchContext = () => React__default["default"].useContext(MessageSearchContext);

exports.MessageSearchProvider = MessageSearchProvider;
exports.useMessageSearchContext = useMessageSearchContext;
//# sourceMappingURL=context.js.map
