import { _ as _objectSpread2 } from '../_rollupPluginBabelHelpers-b9099c54.js';
import React__default, { useContext, useRef, useState, useMemo, useEffect, useCallback } from 'react';
import { renderToString } from 'react-dom/server';
import PropTypes from 'prop-types';
import { N as NodeTypes, M as MessageInputKeys, a as NodeNames } from '../const-16fc416a.js';
import { U as USER_MENTION_TEMP_CHAR } from '../const-07519343.js';
import IconButton from './IconButton.js';
import Button, { ButtonTypes, ButtonSizes } from './Button.js';
import MentionUserLabel from './MentionUserLabel.js';
import Icon, { IconTypes, IconColors } from './Icon.js';
import { L as Label, a as LabelTypography, b as LabelColors } from '../index-c2f20322.js';
import { a as LocalizationContext } from '../LocalizationContext-a6f8fb25.js';
import { l as convertWordToStringObj, S as StringObjType, m as arrayEqual, k as getClassName } from '../index-cc905e95.js';
import '../tslib.es6-84f8edfa.js';
import '../stringSet-ed906148.js';
import '../index-fb7fd76d.js';

const TEXT_FIELD_ID = 'sendbird-message-input-text-field';
const LINE_HEIGHT = 76;

const noop = () => {};

const handleUploadFile = callback => event => {
  if (event.target.files && event.target.files[0]) {
    callback(event.target.files[0]);
  } // eslint-disable-next-line no-param-reassign


  event.target.value = '';
};

const displayCaret = (element, position) => {
  const range = document.createRange();
  const sel = window.getSelection();
  range.setStart(element.childNodes[0], position);
  range.collapse(true);
  sel.removeAllRanges();
  sel.addRange(range);
  element.focus();
};

const initialTargetStringInfo = {
  targetString: '',
  startNodeIndex: null,
  startOffsetIndex: null,
  endNodeIndex: null,
  endOffsetIndex: null
};
const MessageInput = /*#__PURE__*/React__default.forwardRef((props, ref) => {
  const {
    className,
    isEdit,
    isMentionEnabled,
    disabled,
    message,
    placeholder,
    maxLength,
    onFileUpload,
    onSendMessage,
    onUpdateMessage,
    onCancelEdit,
    onStartTyping,
    channelUrl,
    mentionSelectedUser,
    onUserMentioned,
    onMentionStringChange,
    onMentionedUserIdsUpdated,
    onKeyUp,
    onKeyDown
  } = props;
  const {
    stringSet
  } = useContext(LocalizationContext);
  const fileInputRef = useRef(null);
  const [isInput, setIsInput] = useState(false);
  const [mentionedUserIds, setMentionedUserIds] = useState([]);
  const [targetStringInfo, setTargetStringInfo] = useState(_objectSpread2({}, initialTargetStringInfo));
  const setHeight = useMemo(() => () => {
    try {
      const elem = ref === null || ref === void 0 ? void 0 : ref.current;
      const MAX_HEIGHT = window.document.body.offsetHeight * 0.6;

      if (elem && elem.scrollHeight >= LINE_HEIGHT) {
        if (MAX_HEIGHT < elem.scrollHeight) {
          elem.style.height = 'auto';
          elem.style.height = `${MAX_HEIGHT}px`;
        } else {
          elem.style.height = 'auto';
          elem.style.height = `${elem.scrollHeight}px`;
        }
      } else {
        elem.style.height = '';
      }
    } catch (error) {// error
    }
  }, []); // for easilly initialize input value from outside, but
  // useEffect(_, [channelUrl]) erase it

  const initialValue = props === null || props === void 0 ? void 0 : props.value;
  useEffect(() => {
    var _textField$innerText;

    const textField = ref === null || ref === void 0 ? void 0 : ref.current;

    try {
      textField.innerHTML = initialValue;
      displayCaret(textField, initialValue === null || initialValue === void 0 ? void 0 : initialValue.length);
    } catch (_unused) {}

    setMentionedUserIds([]);
    setIsInput((textField === null || textField === void 0 ? void 0 : (_textField$innerText = textField.innerText) === null || _textField$innerText === void 0 ? void 0 : _textField$innerText.length) > 0);
    setHeight();
  }, [initialValue]); // #Mention | Clear input value when channel changes

  useEffect(() => {
    if (!isEdit) {
      setIsInput(false);
      document.getElementById(TEXT_FIELD_ID).innerHTML = '';
    }
  }, [channelUrl]); // #Mention | Fill message input values

  useEffect(() => {
    if (isEdit && message !== null && message !== void 0 && message.messageId) {
      var _message$mentionedUse, _message$mentionedMes, _textField$innerText2;

      // const textField = document.getElementById(TEXT_FIELD_ID);
      const textField = ref === null || ref === void 0 ? void 0 : ref.current;

      if (isMentionEnabled && (message === null || message === void 0 ? void 0 : (_message$mentionedUse = message.mentionedUsers) === null || _message$mentionedUse === void 0 ? void 0 : _message$mentionedUse.length) > 0 && (message === null || message === void 0 ? void 0 : (_message$mentionedMes = message.mentionedMessageTemplate) === null || _message$mentionedMes === void 0 ? void 0 : _message$mentionedMes.length) > 0) {
        var _message$mentionedMes2;

        /* mention enabled */
        const {
          mentionedUsers = []
        } = message;
        textField.innerHTML = message === null || message === void 0 ? void 0 : (_message$mentionedMes2 = message.mentionedMessageTemplate) === null || _message$mentionedMes2 === void 0 ? void 0 : _message$mentionedMes2.split(' ').map(word => convertWordToStringObj(word, mentionedUsers).map(stringObj => {
          const {
            type,
            value,
            userId
          } = stringObj;

          if (type === StringObjType.mention && mentionedUsers.some(user => (user === null || user === void 0 ? void 0 : user.userId) === userId)) {
            var _mentionedUsers$find;

            return renderToString( /*#__PURE__*/React__default.createElement(MentionUserLabel, {
              userId: userId
            }, `${USER_MENTION_TEMP_CHAR}${((_mentionedUsers$find = mentionedUsers.find(user => (user === null || user === void 0 ? void 0 : user.userId) === userId)) === null || _mentionedUsers$find === void 0 ? void 0 : _mentionedUsers$find.nickname) || value || stringSet.MENTION_NAME__NO_NAME}`));
          }

          return value;
        }).join('')).join(' ');
      } else {
        /* mention disabled */
        try {
          textField.innerHTML = message === null || message === void 0 ? void 0 : message.message;
        } catch (_unused2) {}

        setMentionedUserIds([]);
      }

      setIsInput((textField === null || textField === void 0 ? void 0 : (_textField$innerText2 = textField.innerText) === null || _textField$innerText2 === void 0 ? void 0 : _textField$innerText2.length) > 0);
      setHeight();
    }
  }, [isEdit, message]); // #Mention | Detect MentionedLabel modified

  const useMentionedLabelDetection = useCallback(() => {
    const textField = ref === null || ref === void 0 ? void 0 : ref.current;

    if (isMentionEnabled) {
      const newMentionedUserIds = [...textField.getElementsByClassName('sendbird-mention-user-label')].map(node => {
        var _node$dataset;

        return node === null || node === void 0 ? void 0 : (_node$dataset = node.dataset) === null || _node$dataset === void 0 ? void 0 : _node$dataset.userid;
      });

      if (!arrayEqual(mentionedUserIds, newMentionedUserIds) || newMentionedUserIds.length === 0) {
        onMentionedUserIdsUpdated(newMentionedUserIds);
        setMentionedUserIds(newMentionedUserIds);
      }
    }

    setIsInput(textField.innerText.length > 0);
  }, [targetStringInfo, isMentionEnabled]); // #Mention | Replace selected user nickname to the MentionedUserLabel

  useEffect(() => {
    if (isMentionEnabled && mentionSelectedUser) {
      const {
        targetString,
        startNodeIndex,
        startOffsetIndex,
        endNodeIndex,
        endOffsetIndex
      } = targetStringInfo;

      if (targetString && startNodeIndex !== null && startOffsetIndex !== null) {
        var _document, _childNodes$startNode, _document2, _childNodes$endNodeIn;

        // const textField = document.getElementById(TEXT_FIELD_ID);
        const textField = ref === null || ref === void 0 ? void 0 : ref.current;
        const childNodes = [...(textField === null || textField === void 0 ? void 0 : textField.childNodes)];
        const frontTextNode = (_document = document) === null || _document === void 0 ? void 0 : _document.createTextNode((_childNodes$startNode = childNodes[startNodeIndex]) === null || _childNodes$startNode === void 0 ? void 0 : _childNodes$startNode.textContent.slice(0, startOffsetIndex));
        const backTextNode = (_document2 = document) === null || _document2 === void 0 ? void 0 : _document2.createTextNode(`\u00A0${(_childNodes$endNodeIn = childNodes[endNodeIndex]) === null || _childNodes$endNodeIn === void 0 ? void 0 : _childNodes$endNodeIn.textContent.slice(endOffsetIndex)}`);
        const mentionLabel = renderToString( /*#__PURE__*/React__default.createElement(MentionUserLabel, {
          userId: mentionSelectedUser === null || mentionSelectedUser === void 0 ? void 0 : mentionSelectedUser.userId
        }, `${USER_MENTION_TEMP_CHAR}${(mentionSelectedUser === null || mentionSelectedUser === void 0 ? void 0 : mentionSelectedUser.nickname) || stringSet.MENTION_NAME__NO_NAME}`));
        const div = document.createElement('div');
        div.innerHTML = mentionLabel;
        const newNodes = [...childNodes.slice(0, startNodeIndex), frontTextNode, div.childNodes[0], backTextNode, ...childNodes.slice(endNodeIndex + 1)];
        textField.innerHTML = '';
        newNodes.forEach(newNode => {
          textField.appendChild(newNode);
        });
        onUserMentioned(mentionSelectedUser);

        if (window.getSelection || document.getSelection) {
          // set caret postion
          const selection = window.getSelection() || document.getSelection();
          selection.removeAllRanges();
          const range = new Range();
          range.selectNodeContents(textField);
          range.setStart(textField.childNodes[startNodeIndex + 2], 1);
          range.setEnd(textField.childNodes[startNodeIndex + 2], 1);
          range.collapse(false);
          selection.addRange(range);
          textField.focus();
        }

        setTargetStringInfo(_objectSpread2({}, initialTargetStringInfo));
        setHeight();
        useMentionedLabelDetection();
      }
    }
  }, [mentionSelectedUser, isMentionEnabled]); // #Mention | Detect mentioning user nickname

  const useMentionInputDetection = useCallback(() => {
    var _window, _window$getSelection, _document3, _document3$getSelecti;

    const selection = ((_window = window) === null || _window === void 0 ? void 0 : (_window$getSelection = _window.getSelection) === null || _window$getSelection === void 0 ? void 0 : _window$getSelection.call(_window)) || ((_document3 = document) === null || _document3 === void 0 ? void 0 : (_document3$getSelecti = _document3.getSelection) === null || _document3$getSelecti === void 0 ? void 0 : _document3$getSelecti.call(_document3));
    const textField = ref === null || ref === void 0 ? void 0 : ref.current;

    if (selection.anchorNode === textField) {
      onMentionStringChange('');
    }

    if (isMentionEnabled && selection && selection.anchorNode === selection.focusNode && selection.anchorOffset === selection.focusOffset) {
      let textStack = '';
      let startNodeIndex = null;
      let startOffsetIndex = null;

      for (let index = 0; index < textField.childNodes.length; index += 1) {
        const currentNode = textField.childNodes[index];

        if (currentNode.nodeType === NodeTypes.TextNode) {
          /* text node */
          const textContent = currentNode === selection.anchorNode ? (currentNode === null || currentNode === void 0 ? void 0 : currentNode.textContent.slice(0, selection.anchorOffset)) || '' : (currentNode === null || currentNode === void 0 ? void 0 : currentNode.textContent) || '';

          if (textStack.length > 0) {
            textStack += textContent;
          } else {
            let charLastIndex = textContent.lastIndexOf(USER_MENTION_TEMP_CHAR);

            for (let i = charLastIndex - 1; i > -1; i -= 1) {
              if (textContent[i] === USER_MENTION_TEMP_CHAR) {
                charLastIndex = i;
              } else {
                break;
              }
            }

            if (charLastIndex > -1) {
              textStack = textContent;
              startNodeIndex = index;
              startOffsetIndex = charLastIndex;
            }
          }
        } else {
          /* other nodes */
          textStack = '';
          startNodeIndex = null;
          startOffsetIndex = null;
        }

        if (currentNode === selection.anchorNode) {
          /**
           * targetString could be ''
           * startNodeIndex and startOffsetIndex could be null
           */
          const targetString = textStack ? textStack.slice(startOffsetIndex) : ''; // include template character

          setTargetStringInfo({
            targetString,
            startNodeIndex,
            startOffsetIndex,
            endNodeIndex: index,
            endOffsetIndex: selection.anchorOffset
          });
          onMentionStringChange(targetString);
          return;
        }
      }
    }
  }, [isMentionEnabled]);

  const sendMessage = () => {
    const textField = ref === null || ref === void 0 ? void 0 : ref.current;

    if (!isEdit && textField !== null && textField !== void 0 && textField.innerText) {
      let messageText = '';
      let mentionTemplate = '';
      textField.childNodes.forEach(node => {
        if (node.nodeType === NodeTypes.ElementNode && node.nodeName === NodeNames.Span) {
          const {
            innerText,
            dataset = {}
          } = node;
          const {
            userid = ''
          } = dataset;
          messageText += innerText;
          mentionTemplate += `${USER_MENTION_TEMP_CHAR}{${userid}}`;
        } else if (node.nodeType === NodeTypes.ElementNode && node.nodeName === NodeNames.Br) {
          messageText += '\n';
          mentionTemplate += '\n';
        } else {
          // other nodes including text node
          const {
            textContent = ''
          } = node;
          messageText += textContent;
          mentionTemplate += textContent;
        }
      });
      const params = {
        message: messageText,
        mentionTemplate
      };
      onSendMessage(params);
      document.getElementById(TEXT_FIELD_ID).innerHTML = '';
      setIsInput(false);
      setHeight();
    }
  };

  const editMessage = () => {
    const textField = ref === null || ref === void 0 ? void 0 : ref.current;
    const messageId = message === null || message === void 0 ? void 0 : message.messageId;

    if (isEdit && messageId) {
      let messageText = '';
      let mentionTemplate = '';
      textField.childNodes.forEach(node => {
        if (node.nodeType === NodeTypes.ElementNode && node.nodeName === NodeNames.Span) {
          const {
            innerText,
            dataset = {}
          } = node;
          const {
            userid = ''
          } = dataset;
          messageText += innerText;
          mentionTemplate += `${USER_MENTION_TEMP_CHAR}{${userid}}`;
        } else if (node.nodeType === NodeTypes.ElementNode && node.nodeName === NodeNames.Span) {
          messageText += '\n';
          mentionTemplate += '\n';
        } else {
          // other nodes including text node
          const {
            textContent = ''
          } = node;
          messageText += textContent;
          mentionTemplate += textContent;
        }
      });
      const params = {
        messageId,
        message: messageText,
        mentionTemplate
      };
      onUpdateMessage(params);
      document.getElementById(TEXT_FIELD_ID).innerHTML = '';
    }
  };

  return /*#__PURE__*/React__default.createElement("form", {
    className: getClassName([className, isEdit ? 'sendbird-message-input__edit' : '', disabled ? 'sendbird-message-input-form__disabled' : ''])
  }, /*#__PURE__*/React__default.createElement("div", {
    className: getClassName(['sendbird-message-input', disabled ? 'sendbird-message-input__disabled' : ''])
  }, /*#__PURE__*/React__default.createElement("div", {
    id: `${TEXT_FIELD_ID}${isEdit ? message === null || message === void 0 ? void 0 : message.messageId : ''}`,
    className: `sendbird-message-input--textarea ${TEXT_FIELD_ID}`,
    contentEditable: !disabled,
    role: "textbox",
    "aria-label": "Text Input",
    disabled: disabled,
    ref: ref,
    maxLength: maxLength,
    onKeyDown: e => {
      const preventEvent = onKeyDown(e);

      if (preventEvent) {
        e.preventDefault();
      } else {
        var _e$nativeEvent, _ref$current, _ref$current$childNod, _ref$current2, _ref$current2$childNo, _ref$current2$childNo2, _ref$current$childNod2, _ref$current$childNod3;

        if (!e.shiftKey && e.key === MessageInputKeys.Enter && (e === null || e === void 0 ? void 0 : (_e$nativeEvent = e.nativeEvent) === null || _e$nativeEvent === void 0 ? void 0 : _e$nativeEvent.isComposing) !== true) {
          e.preventDefault();
          sendMessage();
        }

        if (e.key === MessageInputKeys.Backspace && (ref === null || ref === void 0 ? void 0 : (_ref$current = ref.current) === null || _ref$current === void 0 ? void 0 : (_ref$current$childNod = _ref$current.childNodes) === null || _ref$current$childNod === void 0 ? void 0 : _ref$current$childNod.length) === 2 && !(ref !== null && ref !== void 0 && (_ref$current2 = ref.current) !== null && _ref$current2 !== void 0 && (_ref$current2$childNo = _ref$current2.childNodes) !== null && _ref$current2$childNo !== void 0 && (_ref$current2$childNo2 = _ref$current2$childNo[0]) !== null && _ref$current2$childNo2 !== void 0 && _ref$current2$childNo2.textContent) && (ref === null || ref === void 0 ? void 0 : (_ref$current$childNod2 = ref.current.childNodes) === null || _ref$current$childNod2 === void 0 ? void 0 : (_ref$current$childNod3 = _ref$current$childNod2[1]) === null || _ref$current$childNod3 === void 0 ? void 0 : _ref$current$childNod3.nodeType) === NodeTypes.ElementNode) {
          ref === null || ref === void 0 ? void 0 : ref.current.removeChild(ref === null || ref === void 0 ? void 0 : ref.current.childNodes[1]);
        }
      }
    },
    onKeyUp: e => {
      const preventEvent = onKeyUp(e);

      if (preventEvent) {
        e.preventDefault();
      } else {
        useMentionInputDetection();
      }
    },
    onClick: () => {
      useMentionInputDetection();
    },
    onInput: () => {
      var _document4, _document4$getElement, _document4$getElement2, _document4$getElement3;

      setHeight();
      onStartTyping();
      setIsInput(((_document4 = document) === null || _document4 === void 0 ? void 0 : (_document4$getElement = _document4.getElementById) === null || _document4$getElement === void 0 ? void 0 : (_document4$getElement2 = _document4$getElement.call(_document4, TEXT_FIELD_ID)) === null || _document4$getElement2 === void 0 ? void 0 : (_document4$getElement3 = _document4$getElement2.innerText) === null || _document4$getElement3 === void 0 ? void 0 : _document4$getElement3.length) > 0);
      useMentionedLabelDetection();
    },
    onPaste: e => {
      e.preventDefault();
      document.execCommand("insertHTML", false, e === null || e === void 0 ? void 0 : e.clipboardData.getData('text'));
    }
  }), !isInput && /*#__PURE__*/React__default.createElement(Label, {
    className: "sendbird-message-input--placeholder",
    type: LabelTypography.BODY_1,
    color: LabelColors.ONBACKGROUND_3
  }, placeholder || stringSet.MESSAGE_INPUT__PLACE_HOLDER), !isEdit && isInput && /*#__PURE__*/React__default.createElement(IconButton, {
    className: "sendbird-message-input--send",
    height: "32px",
    width: "32px",
    onClick: () => sendMessage()
  }, /*#__PURE__*/React__default.createElement(Icon, {
    type: IconTypes.SEND,
    fillColor: IconColors.PRIMARY,
    width: "20px",
    height: "20px"
  })), !isEdit && !isInput && /*#__PURE__*/React__default.createElement(IconButton, {
    className: "sendbird-message-input--attach",
    height: "32px",
    width: "32px",
    onClick: () => {
      var _fileInputRef$current, _fileInputRef$current2;

      // todo: clear previous input
      fileInputRef === null || fileInputRef === void 0 ? void 0 : (_fileInputRef$current = fileInputRef.current) === null || _fileInputRef$current === void 0 ? void 0 : (_fileInputRef$current2 = _fileInputRef$current.click) === null || _fileInputRef$current2 === void 0 ? void 0 : _fileInputRef$current2.call(_fileInputRef$current);
    }
  }, /*#__PURE__*/React__default.createElement(Icon, {
    type: IconTypes.ATTACH,
    fillColor: IconColors.CONTENT_INVERSE,
    width: "20px",
    height: "20px"
  }), /*#__PURE__*/React__default.createElement("input", {
    className: "sendbird-message-input--attach-input",
    type: "file",
    ref: fileInputRef,
    onChange: handleUploadFile(onFileUpload)
  }))), isEdit && /*#__PURE__*/React__default.createElement("div", {
    className: "sendbird-message-input--edit-action"
  }, /*#__PURE__*/React__default.createElement(Button, {
    className: "sendbird-message-input--edit-action__cancel",
    type: ButtonTypes.SECONDARY,
    size: ButtonSizes.SMALL,
    onClick: onCancelEdit
  }, stringSet.BUTTON__CANCEL), /*#__PURE__*/React__default.createElement(Button, {
    className: "sendbird-message-input--edit-action__save",
    type: ButtonTypes.PRIMARY,
    size: ButtonSizes.SMALL,
    onClick: () => editMessage()
  }, stringSet.BUTTON__SAVE)));
});
MessageInput.propTypes = {
  className: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]),
  placeholder: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
  value: PropTypes.string,
  isEdit: PropTypes.bool,
  isMentionEnabled: PropTypes.bool,
  message: PropTypes.shape({
    messageId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
    message: PropTypes.string,
    mentionedMessageTemplate: PropTypes.string,
    mentionedUsers: PropTypes.arrayOf(PropTypes.shape({}))
  }),
  disabled: PropTypes.bool,
  maxLength: PropTypes.number,
  onFileUpload: PropTypes.func,
  onSendMessage: PropTypes.func,
  onUpdateMessage: PropTypes.func,
  onStartTyping: PropTypes.func,
  onCancelEdit: PropTypes.func,
  channelUrl: PropTypes.string,
  mentionSelectedUser: PropTypes.shape({
    userId: PropTypes.string,
    nickname: PropTypes.string
  }),
  onUserMentioned: PropTypes.func,
  onMentionStringChange: PropTypes.func,
  onMentionedUserIdsUpdated: PropTypes.func,
  onKeyUp: PropTypes.func,
  onKeyDown: PropTypes.func
};
MessageInput.defaultProps = {
  className: '',
  channelUrl: '',
  onSendMessage: noop,
  onUpdateMessage: noop,
  value: null,
  message: null,
  isEdit: false,
  isMentionEnabled: false,
  disabled: false,
  placeholder: '',
  maxLength: 5000,
  onFileUpload: noop,
  onCancelEdit: noop,
  onStartTyping: noop,
  mentionSelectedUser: null,
  onUserMentioned: noop,
  onMentionStringChange: noop,
  onMentionedUserIdsUpdated: noop,
  onKeyUp: noop,
  onKeyDown: noop
};

export { MessageInput as default };
//# sourceMappingURL=MessageInput.js.map
