'use strict';

var tslib_es6 = require('./tslib.es6-2c2ed574.js');
var React = require('react');
var index$5 = require('./index-98ac1127.js');
var index$4 = require('./index-968f57c8.js');
var index$1 = require('./index-a31ed3e1.js');
var index$3 = require('./index-3643ff1b.js');
var debounce = require('lodash/debounce');
var miscCookieHelper = require('./miscCookieHelper.js');
var useUniqueId = require('./useUniqueId-18ea5b53.js');
var togetherComponentGlobalContext = require('./utils-302bc65c.js');
var styled = require('@emotion/styled');
var miscTheme = require('./miscTheme.js');
var togetherApiPaths = require('./togetherApiPaths.js');
var constants = require('./constants-762249c4.js');
var post = require('./post-93ff5536.js');
var index = require('./index-17dd60b9.js');
var index$2 = require('./index-2e0b951e.js');

function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }

function _interopNamespace(e) {
  if (e && e.__esModule) return e;
  var n = Object.create(null);
  if (e) {
    Object.keys(e).forEach(function (k) {
      if (k !== 'default') {
        var d = Object.getOwnPropertyDescriptor(e, k);
        Object.defineProperty(n, k, d.get ? d : {
          enumerable: true,
          get: function () { return e[k]; }
        });
      }
    });
  }
  n["default"] = e;
  return Object.freeze(n);
}

var React__default = /*#__PURE__*/_interopDefault(React);
var debounce__default = /*#__PURE__*/_interopDefault(debounce);
var styled__default = /*#__PURE__*/_interopDefault(styled);

const StyledCreatePostDescription = styled__default["default"].div `
  input:focus,
  textarea:focus,
  [contenteditable='true'] {
    outline: none;
  }

  &.has-ask-doctor-option {
    .textarea-control {
      border-bottom: none;
      border-radius: 4px 4px 0 0;
    }
  }

  &.error-description {
    .textarea-control {
      border: 1px solid ${miscTheme.theme.colors.red600};
    }
  }

  .textarea-control {
    position: relative;
    border: 1px solid ${miscTheme.theme.colors.gray200};
    border-radius: ${miscTheme.theme.borderRadius};
    &.--focus {
      border-color: ${miscTheme.theme.colors.primaryBase};
      box-shadow: 0px 0px 2px 2px ${miscTheme.theme.colors.primary200};
    }

    .textarea-wrapper {
      width: 100%;
      height: 200px;
    }

    .control-tool {
      position: absolute;
      bottom: 0;
      left: 0;
      display: flex;
      width: calc(100% - 2rem);
      height: 40px;
      align-items: center;
      justify-content: flex-end;
      border-top: 1px solid ${miscTheme.theme.colors.gray200};
      margin: 0 1rem;

      .tool-button {
        display: flex;
        width: 2rem;
        height: 2rem;
        align-items: center;
        justify-content: center;
        background: transparent;
        cursor: pointer;
      }
      .image-icon {
        vertical-align: middle;
      }
    }
  }

  .link-preview-wrapper {
    position: relative;
    .icon-close {
      position: absolute;
      top: 5px;
      right: 5px;
      width: 24px;
      height: 24px;
      cursor: pointer;
    }
  }

  .image-gallery {
    margin-bottom: 1rem;

    .image-item {
      position: relative;
      overflow: hidden;
      width: 100%;
      height: 0;
      padding-top: 67%;
      margin-top: 1rem;
      border-radius: ${miscTheme.theme.borderRadius};

      & > img {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        object-fit: cover;
      }

      .close-btn {
        position: absolute;
        top: 8px;
        right: 8px;
        left: unset;
        width: 24px;
        height: 24px;
        cursor: pointer;
      }
    }
  }

  .description-label {
    margin-bottom: 5px;
    color: ${miscTheme.theme.colors.gray600};
    /* font-family: 'Open Sans', sans-serif; */
    font-size: 13px;
    font-weight: bold;
  }

  .count-string {
    margin-top: 5px;
    color: ${miscTheme.theme.colors.gray500};
    font-size: 11px;
    text-align: right;
  }

  .input-notification {
    display: flex;

    & > img {
      width: 16px;
      height: 16px;
      margin-top: 1.5px;
      margin-right: 8px;
    }
  }
`;
const StyledEditorContainer = styled__default["default"].div `
  height: 100%;
  position: relative;
  width: 100%;
  display: flex;
  flex-direction: column;
  .ql-toolbar.ql-snow {
    top: 0;
    width: 100%;
    // position: sticky;
    z-index: 3;
    border: none;
    border-bottom: 1px solid #ccc;
    border-radius: 4px 4px 0 0;
    background: white;
    .ql-formats {
      display: inline-flex;
      align-items: center;
      margin-right: 0.5rem;
      .link-tool-wrapper {
        .popover-menu__content {
          padding: 0.5rem;
          transform: translateX(calc(-50% - 1rem));
          max-width: calc(100vw - 4rem);
          ::before {
            right: calc(50% - 8px);
          }
          .link-tool-popover {
            input {
              padding-left: 1rem;
            }
            .link-input-url {
              margin-bottom: 0.5rem;
            }
            .link-input-text {
              margin-bottom: 0.5rem;
            }
            label {
              display: inline-block;
              margin-bottom: 0.2rem;
            }
            .link-input-button-wrapper {
              &[data-is-marrybaby='true'] {
                .link-input-button {
                  border: solid 2px ${miscTheme.theme.mbColors.pink};
                  background-color: ${miscTheme.theme.mbColors.pink};
                  &:hover:not(:disabled) {
                    border: solid 2px ${miscTheme.theme.mbColors.pink};
                    background-color: ${miscTheme.theme.colors.white};
                    color: ${miscTheme.theme.mbColors.pink};
                  }
                }
              }
            }
            .link-input-button {
              width: auto;
              height: auto;
              padding: 0.4rem 1rem;
              background-color: ${miscTheme.theme.colors.primaryBase};

              &:disabled {
                border-color: #bfbfbf;
                background-color: #bfbfbf;
                color: #fff;
                cursor: not-allowed;
              }
              &:hover:not(:disabled) {
                background-color: ${miscTheme.theme.colors.primaryHover};
              }
            }
            .error-text {
              padding: 0;
              margin-bottom: 0.5rem;
              font-weight: 600;
              color: ${miscTheme.theme.colors.red700};
            }
          }
        }
      }
    }
    @media (max-width: 450px) {
      position: relative;
      .ql-formats {
        .link-tool-wrapper {
          position: unset;
          .popover-menu__content {
            left: 0;
            transform: unset;
            max-width: 100%;
          }
        }
      }
    }
  }
  .quill {
    flex: 1;
    overflow-y: hidden;
    .ql-container {
      display: inline-block;
      width: 100%;
      min-height: 100%;
      /* padding: 14px 16px; */
      border: none;
      border-radius: ${miscTheme.theme.borderRadius};
      color: ${miscTheme.theme.colors.gray800};
      font-size: 1rem;
      line-height: 1.5;
      resize: none;
      white-space: break-spaces;
      .ql-editor {
        word-break: break-word;
        overflow-wrap: break-word;
        /* -ms-overflow-style: none;
        scrollbar-width: none;
        &::-webkit-scrollbar {
          display: none;
        } */
      }
      mocka {
        padding: 2px 6px;
        border-radius: 1rem;
        &[data-url='true'] {
          /* background-color: #eeeeff; */
          font-style: italic;
          color: #1890ff;
          cursor: pointer;
          outline: none;
          text-decoration: underline;
        }
        &[data-error='true'] {
          background-color: #ffeeee;
          color: red;
          text-decoration: underline;
          font-style: bold;
        }
      }
      mention {
        padding: 2px 6px;
        border-radius: 1rem;
        background-color: #eeeeff;
        color: #1890ff;
        cursor: pointer;
        outline: none;
        text-decoration: none;
      }
      ol,
      ul {
        padding-left: 1rem;
      }
    }
  }
  .mention-search-container {
    position: absolute;
    background: white;
    border-radius: ${miscTheme.theme.borderRadius};
    filter: drop-shadow(0px 10px 16px rgba(0, 0, 0, 0.04))
      drop-shadow(0px 2px 8px rgba(0, 0, 0, 0.04))
      drop-shadow(0px 0px 1px rgba(0, 0, 0, 0.04));
    overflow-y: scroll;
    z-index: 99;
    ::-webkit-scrollbar {
      -webkit-appearance: none;
    }
    ::-webkit-scrollbar:vertical {
      width: 14px;
    }
    ::-webkit-scrollbar-thumb {
      border-radius: ${miscTheme.theme.borderRadius};
      background-color: #d9d9d9;
      @supports (background-clip: padding-box) {
        border: 3px solid rgba(0, 0, 0, 0);
        background-clip: padding-box;
      }
      @supports not (background-clip: padding-box) {
        border: 3px solid white;
      }
    }
    ::-webkit-scrollbar-track {
      background-color: #fff;
      border-radius: 0 6px 6px 0;
      border-left: 1px solid #f2f2f2;
    }
    .mention-search-item {
      cursor: pointer;
      padding: 12px 1rem;
      display: flex;
      align-items: center;
      &.item-selected {
        background-color: ${miscTheme.theme.colors.gray100};
      }
      .search-avatar {
        width: 40px;
        height: 40px;
        font-size: 20px;
        margin-right: 20px;
      }
    }
  }
`;

var img = "data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none'%3e%3cpath stroke='%23737373' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.75' d='M9.545 16H7.091c-.537 0-1.07-.104-1.566-.305a4.1 4.1 0 0 1-1.327-.867A3.96 3.96 0 0 1 3 12c0-1.06.431-2.078 1.198-2.828A4.14 4.14 0 0 1 7.091 8h2.454m4.38 0h2.984c.537 0 1.07.103 1.566.304a4.1 4.1 0 0 1 1.327.868c.38.371.681.812.887 1.297a3.92 3.92 0 0 1 0 3.062 4 4 0 0 1-.887 1.297c-.38.372-.831.667-1.327.867a4.2 4.2 0 0 1-1.566.305h-2.983M9 12h6'/%3e%3c/svg%3e";
var IconLink = img;

let ReactQuill = null;
(() => tslib_es6.__awaiter(void 0, void 0, void 0, function* () {
    if (typeof window === 'undefined')
        return;
    const QuillRes = yield Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespace(require('react-quill')); });
    ReactQuill = QuillRes.default;
    const Quill = QuillRes.Quill || ReactQuill.Quill;
    class PreserveWhiteSpace {
        constructor(quill, options) {
            this.quill = quill;
            this.options = options;
            quill.container.style.whiteSpace = 'pre-line';
        }
    }
    Quill.register('modules/preserveWhiteSpace', PreserveWhiteSpace);
    const Inline = Quill.import('blots/inline');
    class MockABlot extends Inline {
        static create(options) {
            if (!options)
                return super.create(false);
            const node = super.create(options);
            MockABlot.setNodeConfigurations(node, options);
            return node;
        }
        static formats(node) {
            if (node.innerText &&
                (node.getAttribute('data-href') ||
                    node.getAttribute('data-url') ||
                    node.getAttribute('data-error') ||
                    node.getAttribute('data-bad-word'))) {
                return {
                    'data-bad-word': node.getAttribute('data-bad-word'),
                    'data-error': node.getAttribute('data-error'),
                    'data-href': node.getAttribute('data-href'),
                    'data-url': node.getAttribute('data-url'),
                    'data-text': node.innerText || node.getAttribute('data-href'),
                };
            }
            else {
                return false;
            }
        }
        /* To prevent the node from accidentally being built in different ways. */
        static setNodeConfigurations(node, value) {
            var _a, _b;
            if (!value)
                return;
            if (!((_b = (_a = value === null || value === void 0 ? void 0 : value['data-text']) === null || _a === void 0 ? void 0 : _a.replace(/(\&nbsp;)+/g, ' ')) === null || _b === void 0 ? void 0 : _b.replace(/(\u200c|&zwnj;)+/g, '')))
                return;
            if (value['data-bad-word'])
                node.setAttribute('data-bad-word', value['data-bad-word']);
            if (value['data-href'])
                node.setAttribute('data-href', value['data-href']);
            if (value['data-error'])
                node.setAttribute('data-error', value['data-error']);
            // setTimeout(() => {
            //   if (value['data-text'] !== node.innerText && !node.innerText)
            //     node.innerHTML = value['data-text']
            // }, 200)
            if (value['data-url'])
                node.setAttribute('data-url', value['data-url']);
            // if (value['data-text']) node.innerText = value['data-text']
            // console.log(value, node.outerHTML, node)
        }
    }
    MockABlot.blotName = 'mocka1';
    MockABlot.tagName = 'mocka';
    Quill.register(MockABlot);
    class MentionBlot extends Inline {
        static create(options) {
            if (!options)
                return super.create(false);
            const node = super.create(options);
            MentionBlot.setNodeConfigurations(node, options);
            return node;
        }
        static formats(node) {
            if (node.getAttribute('data-name') && node.getAttribute('data-id')) {
                return {
                    'data-name': node.getAttribute('data-name'),
                    'data-id': node.getAttribute('data-id'),
                };
            }
            else {
                return false;
            }
        }
        /* To prevent the node from accidentally being built in different ways. */
        static setNodeConfigurations(node, value) {
            var _a, _b;
            if (!value)
                return;
            if (!value['data-id'] ||
                !((_b = (_a = value === null || value === void 0 ? void 0 : value['data-name']) === null || _a === void 0 ? void 0 : _a.replace(/(\&nbsp;)+/g, ' ')) === null || _b === void 0 ? void 0 : _b.replace(/(\u200c|&zwnj;)+/g, '')))
                return;
            if (value['data-id'])
                node.setAttribute('data-id', value['data-id']);
            if (value['data-name']) {
                // node.setAttribute('contenteditable', false)
                node.setAttribute('data-name', value['data-name']);
            }
        }
    }
    MentionBlot.blotName = 'mention';
    MentionBlot.tagName = 'mention';
    Quill.register(MentionBlot);
}))();
function getCaretCharacterOffsetWithin(element) {
    var _a, _b;
    let caretOffset = -1;
    if (typeof window.getSelection != 'undefined') {
        const sel = window.getSelection();
        if ((sel === null || sel === void 0 ? void 0 : sel.rangeCount) && (sel === null || sel === void 0 ? void 0 : sel.rangeCount) > 0) {
            const range = (_a = window.getSelection()) === null || _a === void 0 ? void 0 : _a.getRangeAt(0);
            if (range) {
                const preCaretRange = range.cloneRange();
                // preCaretRange.setStart(element, 0)
                preCaretRange.selectNodeContents(element);
                preCaretRange.setEnd(range.endContainer, range.endOffset);
                caretOffset = calculateChildNodeOffset(preCaretRange.cloneContents().childNodes, caretOffset);
                const parentMockAElement = (_b = range.endContainer.parentElement) === null || _b === void 0 ? void 0 : _b.closest('mocka');
                const lastNodeValue = range.endContainer.nodeValue ||
                    range.endContainer.outerHTML;
                if (parentMockAElement && (lastNodeValue === null || lastNodeValue === void 0 ? void 0 : lastNodeValue.length)) {
                    /// set selector to end of <mocka elemt, prevent select in the middle
                    caretOffset =
                        caretOffset -
                            range.endOffset +
                            (parentMockAElement.outerHTML.length -
                                (parentMockAElement === null || parentMockAElement === void 0 ? void 0 : parentMockAElement.outerHTML.lastIndexOf(lastNodeValue)));
                }
            }
        }
    }
    return caretOffset;
}
function calculateChildNodeOffset(childNodes, caretOffset) {
    childNodes.forEach((node, index) => {
        const isLast = index + 1 === childNodes.length;
        if (node.nodeType === Node.ELEMENT_NODE) {
            const outerHTML = node.outerHTML;
            if (!isLast) {
                caretOffset += outerHTML.length;
                return;
            }
            else {
                caretOffset += outerHTML.indexOf('>') + 1;
                caretOffset = calculateChildNodeOffset(node.childNodes, caretOffset);
            }
        }
        else if (node.nodeType === Node.TEXT_NODE) {
            caretOffset += (node.nodeValue || '')
                .replace(/&/g, '&amp;')
                .replace(/</g, '&lt;')
                .replace(/>/g, '&gt;')
                .replace(/"/g, '&quot;')
                .replace(/'/g, '&#039;').length;
        }
    });
    return caretOffset;
}
function getSearchName(root) {
    var _a, _b;
    let res = null;
    if (typeof window.getSelection != 'undefined') {
        const sel = window.getSelection();
        if ((sel === null || sel === void 0 ? void 0 : sel.rangeCount) && (sel === null || sel === void 0 ? void 0 : sel.rangeCount) > 0) {
            const range = (_a = window.getSelection()) === null || _a === void 0 ? void 0 : _a.getRangeAt(0);
            if (range) {
                const preCaretRange = range.cloneRange();
                // preCaretRange.setStart(element, 0)
                preCaretRange.selectNodeContents(root);
                preCaretRange.setEnd(range.endContainer, range.endOffset);
                const endText = (preCaretRange.endContainer.nodeValue || '').substring(0, range.endOffset);
                // only allow @ at start of text or has space before it
                const lastAnchorSymbolIndex = endText.lastIndexOf('@');
                if (lastAnchorSymbolIndex + 1 < endText.length &&
                    (lastAnchorSymbolIndex === 0 ||
                        endText.slice(lastAnchorSymbolIndex - 1, lastAnchorSymbolIndex + 1) === ' @')) {
                    const name = (_b = endText.slice(lastAnchorSymbolIndex + 1)) === null || _b === void 0 ? void 0 : _b.trim();
                    if (name) {
                        preCaretRange.setStart(range.endContainer, lastAnchorSymbolIndex);
                        const replaceRange = preCaretRange.cloneRange();
                        replaceRange.setStart(replaceRange.endContainer, lastAnchorSymbolIndex);
                        res = {
                            name,
                            rect: preCaretRange.getBoundingClientRect(),
                            replaceRange,
                        };
                    }
                }
            }
        }
    }
    return res;
}
const inputModify = (value, opts) => {
    var _a;
    const { formatUrl, bannedWords = [] } = opts || {};
    const removedFormat = post.fixMalformedMention(post.removeFontFormat(value));
    if (!formatUrl)
        return {
            value: post.highlightBadWords(removedFormat, bannedWords),
        };
    let descriptionWithWrappedAnchor = post.removeEdittedBannedWord(post.wrapAnchorAroundUrls(removedFormat));
    const urls = post.getUrlsFromEditorString(removedFormat);
    if (urls) {
        const invalidUrls = [];
        let previewUrl = '';
        urls.forEach((url) => {
            if (!url)
                return;
            try {
                const jsUrl = new URL(url);
                if (post.ALLOW_DOMAIN_URL.some((o) => jsUrl.origin.endsWith(o))) {
                    // is valid
                }
                else {
                    invalidUrls.push(url);
                    // is not valid
                }
            }
            catch (_a) {
                invalidUrls.push(url);
            }
        });
        if (invalidUrls.length > 0) {
            descriptionWithWrappedAnchor = descriptionWithWrappedAnchor
                .replace(new RegExp(`data-url="true">(${invalidUrls.map(post.escapeRegExp).join('|')})<`, 'gi'), 'data-error="true" data-url="true">$1<')
                .replace(new RegExp(`data-href="(${invalidUrls
                .map(post.escapeRegExp)
                .join('|')})" data-url="true">`, 'gi'), 'data-href="$1" data-error="true" data-url="true">');
        }
        previewUrl = (_a = urls.filter((u) => invalidUrls.indexOf(u) === -1)) === null || _a === void 0 ? void 0 : _a[0];
        return {
            invalidUrls,
            previewUrl,
            value: post.highlightBadWords(descriptionWithWrappedAnchor, bannedWords),
        };
    }
    return {
        value: post.highlightBadWords(descriptionWithWrappedAnchor, bannedWords),
    };
};
const RichTextEditor = ({ html, onChange, className, style, onImagePickerClick, bannedWords = [], onInvalidUrlsChange, onPreviewUrlChange, setEditorRef, isReplying, }) => {
    var _a, _b, _c, _d;
    const bannedWordsRef = React.useRef([]);
    bannedWordsRef.current = bannedWords;
    const [invalidUrls, setInvalidUrls] = React.useState([]);
    const [previewUrl, setPreviewUrl] = React.useState(null);
    const { data: { locale }, } = React.useContext(togetherComponentGlobalContext.TogetherComponentGlobalContext);
    const bannedString = (bannedWords === null || bannedWords === void 0 ? void 0 : bannedWords.join(',')) || '';
    React.useEffect(() => {
        var _a, _b;
        const currHTML = (_b = (_a = reactQuillRef.current) === null || _a === void 0 ? void 0 : _a.getEditor()) === null || _b === void 0 ? void 0 : _b.root.innerHTML;
        debounceInputModify(currHTML);
    }, [bannedString]);
    const fetchPreviewData = (url) => {
        if (!previewUrl || previewUrl.url !== url) {
            setPreviewUrl({
                url,
                isFetching: true,
            });
            togetherComponentGlobalContext.callApi(togetherComponentGlobalContext.getApiPath(togetherApiPaths.PATHS.FETCH_PREVIEW, {
                _locale: locale,
            }), 'POST', {
                data: {
                    link: url,
                },
            })
                .then((res) => {
                var _a, _b, _c, _d;
                setPreviewUrl({
                    title: (_a = res === null || res === void 0 ? void 0 : res.data) === null || _a === void 0 ? void 0 : _a.title,
                    description: (_b = res === null || res === void 0 ? void 0 : res.data) === null || _b === void 0 ? void 0 : _b.description,
                    image: ((_c = res === null || res === void 0 ? void 0 : res.data) === null || _c === void 0 ? void 0 : _c.image) || ((_d = res === null || res === void 0 ? void 0 : res.data) === null || _d === void 0 ? void 0 : _d.logo),
                    url,
                });
            })
                .catch(() => {
                setPreviewUrl(null);
            });
        }
    };
    const fetchPreviewDataRef = React.useRef(fetchPreviewData);
    fetchPreviewDataRef.current = fetchPreviewData;
    const debounceInputModify = React.useCallback(debounce__default["default"]((v) => {
        if (v) {
            const processedInput = inputModify(v, {
                bannedWords: bannedWordsRef.current,
                formatUrl: true,
            });
            const { invalidUrls: _invalidUrls, previewUrl: _previewUrl, value, } = processedInput;
            if (_invalidUrls) {
                setInvalidUrls(_invalidUrls);
            }
            if (_previewUrl) {
                fetchPreviewDataRef.current(_previewUrl);
            }
            else
                setPreviewUrl(null);
            if (value !== v) {
                onChange === null || onChange === void 0 ? void 0 : onChange(value);
            }
        }
    }, 500), []);
    React.useEffect(() => {
        onInvalidUrlsChange && onInvalidUrlsChange(invalidUrls);
    }, [invalidUrls]);
    React.useEffect(() => {
        if (onPreviewUrlChange) {
            if (previewUrl === null || previewUrl === void 0 ? void 0 : previewUrl.url)
                onPreviewUrlChange({
                    title: previewUrl.title || '',
                    url: previewUrl.url || '',
                    image: previewUrl.image || '',
                    description: previewUrl.description || '',
                });
            else
                onPreviewUrlChange(null);
        }
    }, [previewUrl]);
    const imageHandlerRef = React.useRef(onImagePickerClick);
    imageHandlerRef.current = onImagePickerClick;
    const toolbarId = useUniqueId.useUniqueId();
    const cachedModules = React.useRef({
        toolbar: {
            handlers: {
                image: () => { var _a; return (_a = imageHandlerRef.current) === null || _a === void 0 ? void 0 : _a.call(imageHandlerRef); },
                link: () => false,
            },
            container: '#toolbar-' + toolbarId,
        },
        // toolbar: [
        //   ['bold', 'italic', 'underline'],
        //   [{ list: 'ordered' }, { list: 'bullet' }],
        // ],
        preserveWhiteSpace: true,
    });
    const contentEditableCaretPos = React.useRef(-1);
    const reactQuillRef = React.useRef(null);
    setEditorRef &&
        ((_b = (_a = reactQuillRef.current) === null || _a === void 0 ? void 0 : _a.getEditor()) === null || _b === void 0 ? void 0 : _b.root) &&
        setEditorRef((_d = (_c = reactQuillRef.current) === null || _c === void 0 ? void 0 : _c.getEditor()) === null || _d === void 0 ? void 0 : _d.root);
    const handleSelectionChange = () => {
        var _a, _b, _c, _d, _e, _f, _g, _h;
        if ((_b = (_a = reactQuillRef.current) === null || _a === void 0 ? void 0 : _a.getEditor()) === null || _b === void 0 ? void 0 : _b.root) {
            const newCaretPos = getCaretCharacterOffsetWithin((_d = (_c = reactQuillRef.current) === null || _c === void 0 ? void 0 : _c.getEditor()) === null || _d === void 0 ? void 0 : _d.root);
            const currHTML = (_f = (_e = reactQuillRef.current) === null || _e === void 0 ? void 0 : _e.getEditor()) === null || _f === void 0 ? void 0 : _f.root.innerHTML;
            // in case of clicking on a div outside editor while focus, we get caret position too large
            if (newCaretPos >= 0 && newCaretPos < currHTML.length) {
                const mentionIds = post.getMentionIdsFromString(currHTML, true);
                if (mentionIds.length < post.LIMIT_MENTION - (isReplying ? 1 : 0)) {
                    const searchData = getSearchName((_h = (_g = reactQuillRef.current) === null || _g === void 0 ? void 0 : _g.getEditor()) === null || _h === void 0 ? void 0 : _h.root);
                    if (searchData) {
                        searchUser(searchData.name, searchData.rect);
                        replaceRangeRef.current = searchData.replaceRange;
                    }
                    else {
                        replaceRangeRef.current = null;
                        // to avoid race condition, we reuse this function to clear foundUsers
                        searchUser('', null);
                    }
                }
                else {
                    replaceRangeRef.current = null;
                    // to avoid race condition, we reuse this function to clear foundUsers
                    searchUser('', null);
                }
                // const insertIndex = newCaretPos + 1
                // const currHTML = reactQuillRef.current?.getEditor()?.root.innerHTML
                // console.log(
                //   currHTML?.substring(0, insertIndex) || '',
                //   '========',
                //   currHTML?.substring(insertIndex) || '',
                // )
                contentEditableCaretPos.current = newCaretPos;
            }
        }
        else {
            setFoundUsers([]);
        }
    };
    const [foundUsers, setFoundUsers] = React.useState([]);
    const [searchUserPosition, setSearchUserPosition] = React.useState({
        top: 0,
        left: 0,
    });
    const searchUser = React.useCallback(debounce__default["default"]((name, rect, excludeIds) => tslib_es6.__awaiter(void 0, void 0, void 0, function* () {
        var _e, _f, _g, _h;
        if (!name || !DOMRect) {
            return setFoundUsers([]);
        }
        const res = yield ((((_e = miscCookieHelper.getCookie(constants.BEARER_TOKEN_COOKIE)) === null || _e === void 0 ? void 0 : _e.length) || 0) > 0
            ? togetherComponentGlobalContext.callApiWithAuth(togetherComponentGlobalContext.getApiPath(togetherApiPaths.PATHS.SEARCH_USER, {
                _locale: locale,
                name: name,
            }), 'get')
            : togetherComponentGlobalContext.callApiWithAdminAuth(togetherComponentGlobalContext.getApiPath(togetherApiPaths.ADMIN_PATHS.SEARCH_USER, {
                _locale: locale,
                name: name,
            }), 'get'));
        setSelectTagUserIndex(0);
        setFoundUsers((_g = (_f = res === null || res === void 0 ? void 0 : res.data) === null || _f === void 0 ? void 0 : _f.users) === null || _g === void 0 ? void 0 : _g.filter((u) => !(excludeIds === null || excludeIds === void 0 ? void 0 : excludeIds.includes(String(u.id)))));
        const textNodeRect = rect;
        const containerRect = (_h = containerRef.current) === null || _h === void 0 ? void 0 : _h.getBoundingClientRect();
        if (textNodeRect && containerRect) {
            const idealWidth = 343;
            const idealHeight = 256;
            const styleConfig = {
                top: textNodeRect.bottom - containerRect.top,
                width: `min(343px, 100%)`,
                maxHeight: idealHeight,
            };
            const tempRightWidth = containerRect.width - (textNodeRect.left - containerRect.left);
            if (tempRightWidth < idealWidth) {
                styleConfig.right = 0;
            }
            else {
                styleConfig.left = textNodeRect.left - containerRect.left;
            }
            setSearchUserPosition(styleConfig);
        }
    }), 500), []);
    const setSelectUser = (id, name) => {
        var _a, _b, _c;
        if (replaceRangeRef.current) {
            replaceRangeRef.current.deleteContents();
            const newMention = document.createElement('mention');
            newMention.setAttribute('data-id', id);
            newMention.setAttribute('data-name', name);
            // newMention.setAttribute('contenteditable', 'false')
            newMention.innerText = name;
            const newPostText = document.createTextNode(' ');
            replaceRangeRef.current.insertNode(newPostText);
            replaceRangeRef.current.insertNode(newMention);
            const editorRoot = (_b = (_a = reactQuillRef.current) === null || _a === void 0 ? void 0 : _a.getEditor()) === null || _b === void 0 ? void 0 : _b.root;
            editorRoot.focus();
            const range = (_c = window.getSelection()) === null || _c === void 0 ? void 0 : _c.getRangeAt(0);
            range === null || range === void 0 ? void 0 : range.setStart(replaceRangeRef.current.endContainer, replaceRangeRef.current.endOffset);
            range === null || range === void 0 ? void 0 : range.setEnd(replaceRangeRef.current.endContainer, replaceRangeRef.current.endOffset);
        }
        setFoundUsers([]);
    };
    const containerRef = React.useRef(null);
    const replaceRangeRef = React.useRef(null);
    const foundUsersListRef = React.useRef(null);
    const [selectTagUserIndex, setSelectTagUserIndex] = React.useState(0);
    React.useEffect(() => {
        // convenient behavior, scroll item into view when select using keyboard
        if (foundUsersListRef.current) {
            const parentElement = foundUsersListRef.current;
            const childElement = parentElement.children.item(selectTagUserIndex);
            if (childElement) {
                const containerRect = parentElement.getBoundingClientRect();
                const childRect = childElement.getBoundingClientRect();
                if (childElement.offsetTop < parentElement.scrollTop)
                    parentElement.scrollTop = childElement.offsetTop;
                else if (childElement.offsetTop + childRect.height >
                    parentElement.scrollTop + containerRect.height) {
                    parentElement.scrollTop =
                        childElement.offsetTop - containerRect.height + childRect.height;
                }
            }
        }
    }, [selectTagUserIndex]);
    React.useEffect(() => {
        const clickHandler = function (e) {
            var _a;
            if (!((_a = containerRef.current) === null || _a === void 0 ? void 0 : _a.contains(e.target))) {
                // Clicked outside the box
                setFoundUsers([]);
            }
        };
        window.addEventListener('click', clickHandler, {
            passive: true,
        });
        return () => {
            window.removeEventListener('click', clickHandler);
        };
    }, []);
    return (React__default["default"].createElement(StyledEditorContainer, { ref: containerRef, className: className, style: style, onKeyDownCapture: (e) => {
            // convenient behavior, use arrow to select tag user and enter to choose
            if (foundUsers === null || foundUsers === void 0 ? void 0 : foundUsers.length) {
                let preventKey = false;
                if (e.key === 'ArrowDown') {
                    preventKey = true;
                    setSelectTagUserIndex((s) => s + 1 >= foundUsers.length ? 0 : s + 1);
                }
                else if (e.key === 'Escape') {
                    preventKey = true;
                    setSelectTagUserIndex(0);
                    setFoundUsers([]);
                }
                else if (e.key === 'ArrowUp') {
                    preventKey = true;
                    setSelectTagUserIndex((s) => s - 1 < 0 ? foundUsers.length - 1 : s - 1);
                }
                else if (e.key === 'Enter' || e.key === 'Tab') {
                    const user = foundUsers[selectTagUserIndex];
                    if (user) {
                        preventKey = true;
                        setSelectUser(user.id, user.name);
                    }
                }
                if (preventKey) {
                    e.preventDefault();
                    return false;
                }
            }
        } },
        React__default["default"].createElement(CustomToolbar, { id: toolbarId, onAddLink: (text, href) => {
                var _a, _b;
                const insertIndex = contentEditableCaretPos.current + 1;
                const currHTML = (_b = (_a = reactQuillRef.current) === null || _a === void 0 ? void 0 : _a.getEditor()) === null || _b === void 0 ? void 0 : _b.root.innerHTML;
                const newHTML = ((currHTML === null || currHTML === void 0 ? void 0 : currHTML.substring(0, insertIndex)) || '') +
                    `<mocka data-href="${href}" data-url="true">${text}</mocka> ` +
                    ((currHTML === null || currHTML === void 0 ? void 0 : currHTML.substring(insertIndex)) || '');
                onChange === null || onChange === void 0 ? void 0 : onChange(newHTML);
                debounceInputModify(newHTML);
            } }),
        ReactQuill && (React__default["default"].createElement(ReactQuill, { ref: reactQuillRef, theme: "snow", value: html, onChange: (t) => {
                onChange === null || onChange === void 0 ? void 0 : onChange(t);
                debounceInputModify(t);
                handleSelectionChange();
            }, onChangeSelection: () => {
                handleSelectionChange();
            }, modules: cachedModules.current, formats: [
                'mocka1',
                'mention',
                'id',
                'key',
                'bold',
                'italic',
                'underline',
                'list',
                'bullet',
            ] })),
        !!(foundUsers === null || foundUsers === void 0 ? void 0 : foundUsers.length) && (React__default["default"].createElement("div", { ref: foundUsersListRef, className: "mention-search-container", style: searchUserPosition }, foundUsers.map((foundUser, index$2) => (React__default["default"].createElement("div", { className: `mention-search-item ${selectTagUserIndex === index$2 ? 'item-selected' : ''}`, key: foundUser.id, onClick: (e) => {
                e.preventDefault();
                e.stopPropagation();
                setSelectUser(foundUser.id, foundUser.name);
            }, onMouseEnter: () => {
                setSelectTagUserIndex(index$2);
            } },
            React__default["default"].createElement(index.UserAvatar, { className: "search-avatar", username: foundUser.name, avatar: foundUser.avatar }),
            React__default["default"].createElement("div", null,
                React__default["default"].createElement(index$1.Text, { size: "p2" }, foundUser.name),
                React__default["default"].createElement(index$1.Text, { size: "p4", color: "#595959" },
                    "@",
                    foundUser.username)))))))));
};
const CustomToolbar = ({ onAddLink, id, }) => {
    return (React__default["default"].createElement("div", { id: 'toolbar-' + id, onClick: (e) => {
            e.preventDefault();
            e.stopPropagation();
        } },
        React__default["default"].createElement("span", { className: "ql-formats" },
            React__default["default"].createElement("button", { className: "ql-bold", type: "button" }),
            React__default["default"].createElement("button", { className: "ql-italic", type: "button" }),
            React__default["default"].createElement("button", { className: "ql-underline", type: "button" })),
        React__default["default"].createElement("span", { className: "ql-formats" },
            React__default["default"].createElement("button", { className: "ql-list", value: "ordered", type: "button" }),
            React__default["default"].createElement("button", { className: "ql-list", value: "bullet", type: "button" })),
        React__default["default"].createElement("span", { className: "ql-formats" }, onAddLink && (React__default["default"].createElement(index$2.PopoverMenu, { className: "link-tool-wrapper", toggleButtonContent: React__default["default"].createElement("img", { className: "link-icon", src: IconLink, loading: "lazy" }), buttonProps: {
                size: 'md',
                color: 'transparent',
            }, align: "end" }, ({ setShow }) => (React__default["default"].createElement(LinkToolInputPopover, { onAddUrl: onAddLink, setShow: setShow })))))));
};
const URL_WARN_MAP = [
    'notification.limitUrlDomain',
    'notification.urlWrongFormat',
];
const LinkToolInputPopover = ({ onAddUrl, setShow }) => {
    const { data: { env: { isMarryBaby }, }, } = React.useContext(togetherComponentGlobalContext.TogetherComponentGlobalContext);
    const { t } = index$3.useTranslations();
    const [urlValue, setUrlValue] = React.useState('');
    const [textValue, setTextValue] = React.useState('');
    const [urlWarnType, setUrlWarnType] = React.useState(-1);
    const checkUrlValid = (v) => {
        const trimmedUrl = post.reformatUrl(v.trim());
        try {
            const jsUrl = new URL(trimmedUrl);
            if (!jsUrl.protocol.startsWith('http')) {
                setUrlWarnType(1);
                return false;
            }
            if (!post.ALLOW_DOMAIN_URL.some((o) => jsUrl.origin.endsWith('/' + o) || jsUrl.origin.endsWith('.' + o))) {
                setUrlWarnType(0);
                return false;
            }
            setUrlWarnType(-1);
            return true;
        }
        catch (_a) {
            setUrlWarnType(1);
            return false;
        }
    };
    const isValid = urlValue.trim() && textValue.trim() && urlWarnType < 0;
    return (React__default["default"].createElement("div", { className: "link-tool-popover" },
        React__default["default"].createElement(index$4.Input, { name: "url", value: urlValue, size: "md", label: "URL", placeholder: t('placeholder.enterUrlHere'), type: "text", className: "link-input-url", onChange: (v) => {
                setUrlValue(v);
                checkUrlValid(v);
            } }),
        urlWarnType >= 0 && (React__default["default"].createElement(index$1.Text, { size: "c2", className: "error-text" }, t(URL_WARN_MAP[urlWarnType]))),
        React__default["default"].createElement(index$4.Input, { name: "text", value: textValue, size: "md", label: t('createPost.urlText'), placeholder: t('placeholder.enterUrlTextHere'), type: "text", className: "link-input-text", onChange: (v) => setTextValue(v) }),
        React__default["default"].createElement("div", { "data-is-marrybaby": isMarryBaby, className: "link-input-button-wrapper" },
            React__default["default"].createElement(index$5.Button, { theme: isMarryBaby ? 'marryBaby' : 'helloSites', size: "sm", color: "primary", className: "link-input-button", onClick: () => {
                    if (!isValid)
                        return;
                    onAddUrl(textValue.trim(), post.reformatUrl(urlValue.trim()));
                    setShow && setShow(false);
                }, isDisabled: !isValid }, t('insert')))));
};

exports.IconLink = IconLink;
exports.RichTextEditor = RichTextEditor;
exports.StyledCreatePostDescription = StyledCreatePostDescription;
