import { A as isUrl } from './index-eefb44ba.js';

const USER_MENTION_PREFIX = '@';

const TOKEN_TYPES = {
  string: 'string',
  mention: 'mention',
  url: 'url',
  undetermined: 'undetermined'
};

function getUserMentionRegex(mentionedUsers, templatePrefix_) {
  const templatePrefix = templatePrefix_ || USER_MENTION_PREFIX;
  return RegExp(`(${mentionedUsers.map(u => {
    const userId = u.userId.replace(
    // If user.id includes these patterns, need to convert it into an escaped one
    /([.*+?^${}()|[\]\\])/g, '\\$1');
    /**
     * //{ And //} are also for escaping
     * because curly braces `{}` are metacharacters in regular expressions used to specify repetition
     */
    return `${templatePrefix}\\{${userId}\\}`;
  }).join('|')})`, 'g');
}
function identifyMentions(_ref) {
  let {
    tokens,
    mentionedUsers = [],
    templatePrefix = USER_MENTION_PREFIX
  } = _ref;
  if (!(mentionedUsers !== null && mentionedUsers !== void 0 && mentionedUsers.length)) {
    return tokens;
  }
  const userMentionRegex = getUserMentionRegex(mentionedUsers, templatePrefix);
  const results = tokens.map(token => {
    // if the token is not undetermined, return it as is
    // is kinda unnecessary with TS, but just in case
    if (token.type !== TOKEN_TYPES.undetermined) {
      return token;
    }
    const {
      value
    } = token;
    const parts = value.split(userMentionRegex);
    const tokens = parts.map(part => {
      if (part.match(userMentionRegex)) {
        const matchedUser = mentionedUsers.find(user => `@{${user === null || user === void 0 ? void 0 : user.userId}}` === part);
        const nickname = (matchedUser === null || matchedUser === void 0 ? void 0 : matchedUser.nickname) || '(No name)';
        return {
          value: nickname,
          type: TOKEN_TYPES.mention,
          userId: matchedUser === null || matchedUser === void 0 ? void 0 : matchedUser.userId
        };
      } else {
        return {
          value: part,
          type: TOKEN_TYPES.undetermined
        };
      }
    });
    return tokens;
  }).flat();
  return results;
}
function identifyUrlsAndStrings(token) {
  const results = token.map(token => {
    if (token.type !== TOKEN_TYPES.undetermined) {
      return token;
    }
    const {
      value = ''
    } = token;
    const parts = value.split(' ');
    const tokens = parts.map(part => {
      if (isUrl(part)) {
        return {
          value: part,
          type: TOKEN_TYPES.url
        };
      } else {
        return {
          value: part,
          type: TOKEN_TYPES.string
        };
      }
    });
    return tokens;
  }).flat();
  return results;
}
function combineNearbyStrings(tokens) {
  const results = tokens.reduce((acc, token) => {
    const lastToken = acc[acc.length - 1];
    if ((lastToken === null || lastToken === void 0 ? void 0 : lastToken.type) === TOKEN_TYPES.string && token.type === TOKEN_TYPES.string) {
      lastToken.value = `${lastToken.value} ${token.value}`;
      return acc;
    }
    return [...acc, token];
  }, []);
  return results;
}

/**
 * Converts text into set of rich tokens
 */
function tokenizeMessage(_ref2) {
  let {
    messageText,
    mentionedUsers = [],
    templatePrefix = USER_MENTION_PREFIX
  } = _ref2;
  // mention can be squeezed-in(no-space-between) with other mentions and urls
  // if no users are mentioned, return the messageText as a single token
  const partialResult = [{
    type: TOKEN_TYPES.undetermined,
    value: messageText
  }];

  // order is important because we want to identify mentions first
  // identifyMentions will return a token with type mention or undetermined
  const partialWithMentions = identifyMentions({
    tokens: partialResult,
    mentionedUsers,
    templatePrefix
  });
  const partialsWithUrlsAndMentions = identifyUrlsAndStrings(partialWithMentions);
  const result = combineNearbyStrings(partialsWithUrlsAndMentions);
  return result;
}

/**
 * Don't need to use this util in DOM element since the white spaces will be kept as is,
 * but will need if the text is wrapped \w React.Fragement or </>
 * @link https://sendbird.slack.com/archives/GPGHESTL3/p1681180484341369
 * Or!!! -> convert any space or tab in leading/trailing to nbsp
 * to preserve the leading & trailing white spaces
 */
function getWhiteSpacePreservedText(text) {
  const NON_BREAKING_SPACE = '\u00A0';
  // Split the input string into lines
  const lines = text.split('\n');

  // Process each line and convert leading and trailing white spaces to "\u00A0"
  const processedLines = lines.map(line => {
    var _line$match, _line$match2;
    const leadingWhitespace = ((_line$match = line.match(/^\s*/)) === null || _line$match === void 0 ? void 0 : _line$match[0]) || '';
    const trailingWhitespace = ((_line$match2 = line.match(/\s*$/)) === null || _line$match2 === void 0 ? void 0 : _line$match2[0]) || '';
    const convertedLeadingWhitespace = leadingWhitespace.replace(/ /g, NON_BREAKING_SPACE);
    const convertedTrailingWhitespace = trailingWhitespace.replace(/ /g, NON_BREAKING_SPACE);
    return convertedLeadingWhitespace + line.trim() + convertedTrailingWhitespace;
  });

  // Combine the processed lines into a new string with "\n"
  const result = processedLines.join('\n');
  return result;
}

export { TOKEN_TYPES as T, USER_MENTION_PREFIX as U, getWhiteSpacePreservedText as g, tokenizeMessage as t };
//# sourceMappingURL=tokenize-b97bc343.js.map
