import { _ as _applyDecoratedDescriptor, a as _initializerDefineProperty, b as _defineProperty } from '../_rollupPluginBabelHelpers-9wjJaosZ.js';
import { setComponentTemplate } from '@ember/component';
import { precompileTemplate } from '@ember/template-compilation';
import { macroCondition, dependencySatisfies, importSync } from '@embroider/macros';
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { hash } from '@ember/helper';
import { on } from '@ember/modifier';
import { action } from '@ember/object';
import { guidFor } from '@ember/object/internals';
import didInsert from '@ember/render-modifiers/modifiers/did-insert';
import didUpdate from '@ember/render-modifiers/modifiers/did-update';
import { scheduleOnce } from '@ember/runloop';
import pick from 'ember-composable-helpers/helpers/pick';
import { modifier } from 'ember-modifier';
import set from 'ember-set-helper/helpers/set';
import style from 'ember-style-modifier/modifiers/style';
import { eq } from 'ember-truth-helpers';
import unified from 'unified';
import { argOrDefaultDecorator } from '../helpers/arg-or-default.js';
import classNames from '../helpers/class-names.js';
import ResizeObserver from '../modifiers/resize-observer.js';
import validatableControl from '../modifiers/validatable-control.js';
import MarkdownActions from '../utils/markdown/markdown-actions.js';
import { MODE_EDITING, MODE_VIEWING } from '../utils/markdown/markdown-modes.js';
import { defaultParsingPlugins } from '../utils/markdown/plugins/markdown-default-plugins/parsing-plugins.js';
import { defaultProcessingPlugins } from '../utils/markdown/plugins/markdown-default-plugins/processing-plugins.js';
import '../utils/markdown/plugins/markdown-default-plugins/ui-plugins.js';
import './eui-markdown-format/markdown-tooltip.js';
import { tooltipPlugin } from '../utils/markdown/plugins/markdown-tooltip/plugin.js';
import EuiMarkdownEditorDropZone from './eui-markdown-editor-drop-zone.js';
import EuiMarkdownEditorTextArea from './eui-markdown-editor-text-area.js';
import EuiMarkdownEditorToolbarComponent from './eui-markdown-editor-toolbar.js';
import EuiMarkdownEditorToolbarComponent$1 from './eui-markdown-format.js';

var _dec, _dec2, _dec3, _dec4, _dec5, _class, _descriptor, _descriptor2, _descriptor3, _descriptor4, _descriptor5, _descriptor6, _descriptor7, _descriptor8, _descriptor9, _descriptor10, _descriptor11, _descriptor12, _descriptor13, _descriptor14;
let cached = macroCondition(dependencySatisfies('ember-source', '>= 4.1.0-alpha.0')) ? importSync('@glimmer/tracking').cached : importSync('ember-cached-decorator-polyfill').cached;
const getCursorNode = (textareaRef, parsed) => {
  const {
    selectionStart
  } = textareaRef;
  let node = parsed.result ?? parsed.contents;

  //eslint-disable-next-line
  outer: while (true) {
    if (node.children) {
      for (let i = 0; i < node.children.length; i++) {
        const child = node.children[i];
        if (child && child.position.start.offset < selectionStart && selectionStart < child.position.end.offset) {
          if (child.type === 'text') break outer; // don't dive into `text` nodes
          node = child;
          continue outer;
        }
      }
    }
    break;
  }
  return node;
};
function wrapper(textarea, parsed, callback) {
  const node = getCursorNode(textarea, parsed);
  callback(node);
}
const getCursorNodeModifier = modifier(function getCursorNodeModifier(textarea, [parsed, onSelectedNode]) {
  const fn = wrapper.bind(null, textarea, parsed, onSelectedNode);
  textarea.addEventListener('keyup', fn);
  textarea.addEventListener('mouseup', fn);
  return () => {
    textarea.removeEventListener('keyup', fn);
    textarea.removeEventListener('mouseup', fn);
  };
});
let EuiMarkdownEditorComponent = setComponentTemplate(precompileTemplate(`
    <div
      class={{classNames
        "euiMarkdownEditor"
        (if (eq this.height "full") "euiMarkdownEditor--fullHeight")
        (if this.isPreviewing "euiMarkdownEditor--isPreviewing")
      }}
      {{didUpdate
        this.updateCurrentHeight
        this.currentHeight
        this.isPreviewing
        this.height
        this.autoExpandPreview
      }}
    >
      <EuiMarkdownEditorToolbar
        @selectedNode={{this.selectedNode}}
        @markdownActions={{this.markdownActions}}
        @onClickPreview={{this.setViewMode}}
        @viewMode={{this.viewMode}}
        @uiPlugins={{this.toolbarPlugins}}
        {{didInsert this.setEditorToolbarRef}}
      />
      {{#if this.isPreviewing}}
        <div
          class="euiMarkdownEditorPreview"
          {{didInsert (set this "previewRef")}}
          {{style (hash height=this.previewHeight)}}
        >
          <EuiMarkdownFormat
            @parsingPluginList={{this.parsingPluginList}}
            @processingPluginList={{this.processingPluginList}}
            @value={{@value}}
            @replaceNode={{this.replaceNode}}
          />
        </div>
      {{/if}}

      <div
        class="euiMarkdownEditor__toggleContainer"
        {{style height=this.editorToggleContainerHeight}}
      >
        <EuiMarkdownEditorDropZone
          @uiPlugins={{this.toolbarPlugins}}
          {{resizeObserver onResize=this.onResize}}
        >
          <EuiMarkdownEditorTextArea
            {{getCursorNodeModifier this.vFile this.setSelectedNode}}
            {{didUpdate this.onParse this.parsed}}
            {{didInsert this.setTextAreaRef}}
            disabled={{@disabled}}
            id={{this.editorId}}
            @height={{this.textAreaHeight}}
            @maxHeight={{this.textAreaMaxHeight}}
            value={{@value}}
            aria-label={{@ariaLabel}}
            aria-labelledby={{@ariaLabelledBy}}
            aria-describedby={{@ariaDescribedBy}}
            {{on "input" (pick "target.value" @onChange)}}
            {{validatableControl @isInvalid}}
            ...attributes
          />
        </EuiMarkdownEditorDropZone>
      </div>
    </div>
  `, {
  strictMode: true,
  scope: () => ({
    classNames,
    eq,
    didUpdate,
    EuiMarkdownEditorToolbar: EuiMarkdownEditorToolbarComponent,
    didInsert,
    set,
    style,
    hash,
    EuiMarkdownFormat: EuiMarkdownEditorToolbarComponent$1,
    EuiMarkdownEditorDropZone,
    resizeObserver: ResizeObserver,
    EuiMarkdownEditorTextArea,
    getCursorNodeModifier,
    on,
    pick,
    validatableControl
  })
}), (_dec = argOrDefaultDecorator(defaultParsingPlugins), _dec2 = argOrDefaultDecorator(250), _dec3 = argOrDefaultDecorator(500), _dec4 = argOrDefaultDecorator(true), _dec5 = argOrDefaultDecorator(defaultProcessingPlugins), (_class = class EuiMarkdownEditorComponent extends Component {
  get toolbarPlugins() {
    return [tooltipPlugin, ...(this.args.uiPlugins || [])];
  }
  constructor(owner, args) {
    super(owner, args);
    // Defaults
    _initializerDefineProperty(this, "parsingPluginList", _descriptor, this);
    _initializerDefineProperty(this, "height", _descriptor2, this);
    _initializerDefineProperty(this, "maxHeight", _descriptor3, this);
    _initializerDefineProperty(this, "autoExpandPreview", _descriptor4, this);
    _initializerDefineProperty(this, "processingPluginList", _descriptor5, this);
    _initializerDefineProperty(this, "selectedNode", _descriptor6, this);
    _initializerDefineProperty(this, "editorId", _descriptor7, this);
    _initializerDefineProperty(this, "viewMode", _descriptor8, this);
    _initializerDefineProperty(this, "textareaRef", _descriptor9, this);
    _initializerDefineProperty(this, "previewRef", _descriptor10, this);
    _initializerDefineProperty(this, "editorToolbarRef", _descriptor11, this);
    _initializerDefineProperty(this, "currentHeight", _descriptor12, this);
    _initializerDefineProperty(this, "editorFooterHeight", _descriptor13, this);
    _initializerDefineProperty(this, "editorToolbarHeight", _descriptor14, this);
    _defineProperty(this, "markdownActions", void 0);
    this.markdownActions = new MarkdownActions(this.editorId,
    // @ts-expect-error
    this.toolbarPlugins);
    this.currentHeight = this.height;
  }
  get previewHeight() {
    if (this.height === 'full') {
      return `calc(100% - ${this.editorFooterHeight}px)`;
    }
    return `${this.currentHeight}px`;
  }
  get textAreaHeight() {
    return this.height === 'full' ? '100%' : `calc(${this.height - this.editorFooterHeight}px)`;
  }
  get textAreaMaxHeight() {
    return this.height !== 'full' ? `${this.maxHeight - this.editorFooterHeight}px` : '';
  }
  get editorToggleContainerHeight() {
    return `calc(100% - ${this.editorToolbarHeight}px)`;
  }
  onResize() {
    if (this.textareaRef && this.isEditing && this.height !== 'full') {
      const resizedTextareaHeight = this.textareaRef.offsetHeight + this.editorFooterHeight;
      const update = () => {
        this.currentHeight = resizedTextareaHeight;
      };
      scheduleOnce('afterRender', this, update);
    }
  }
  updateCurrentHeight() {
    let {
      isPreviewing,
      autoExpandPreview,
      height,
      previewRef,
      currentHeight
    } = this;
    if (isPreviewing && autoExpandPreview && height !== 'full' && previewRef) {
      //@ts-ignore
      if (previewRef.scrollHeight > currentHeight) {
        // scrollHeight does not include the border or margin
        // so we ask for the computed value for those,
        // which is always in pixels because getComputedValue
        // returns the resolved values
        const elementComputedStyle = window.getComputedStyle(previewRef);
        const borderWidth = parseFloat(elementComputedStyle.borderTopWidth) + parseFloat(elementComputedStyle.borderBottomWidth);
        const marginWidth = parseFloat(elementComputedStyle.marginTop) + parseFloat(elementComputedStyle.marginBottom);

        // then add an extra pixel for safety and because the scrollHeight value is rounded
        const extraHeight = borderWidth + marginWidth + 1;
        const update = () => {
          if (previewRef) {
            this.currentHeight = previewRef.scrollHeight + extraHeight;
          }
        };
        scheduleOnce('afterRender', this, update);
      }
    }
  }
  setTextAreaRef(ref) {
    this.textareaRef = ref;
  }
  setEditorToolbarRef(ref) {
    this.editorToolbarRef = ref;
    this.editorToolbarHeight = ref.offsetHeight;
  }
  replaceNode(position, next) {
    let value = this.args.value;
    const leading = value.substr(0, position.start.offset);
    const trailing = value.substr(position.end.offset);
    this.args.onChange?.(`${leading}${next}${trailing}`);
  }
  get isEditing() {
    return this.viewMode === MODE_EDITING;
  }
  get isPreviewing() {
    return this.viewMode === MODE_VIEWING;
  }
  setViewMode() {
    this.viewMode = this.isPreviewing ? MODE_EDITING : MODE_VIEWING;
  }
  get parser() {
    const Compiler = tree => {
      return tree;
    };
    function identityCompiler() {
      //eslint-disable-next-line
      this.Compiler = Compiler;
    }
    return unified().use(this.parsingPluginList).use(identityCompiler);
  }
  get parsed() {
    try {
      const parsed = this.parser.processSync(this.args.value);
      return [parsed, null];
    } catch (e) {
      return [null, e];
    }
  }
  get vFile() {
    return this.parsed[0];
  }
  onParse() {
    if (this.args.onParse) {
      const [parsed, parseError] = this.parsed;
      const onParse = this.args.onParse;
      const messages = parsed ? parsed.messages : [];
      const ast = parsed ? parsed['result'] ?? parsed.contents : null;
      onParse(parseError, {
        messages,
        ast
      });
    }
  }
  setSelectedNode(node) {
    this.selectedNode = node;
  }
}, (_descriptor = _applyDecoratedDescriptor(_class.prototype, "parsingPluginList", [_dec], {
  configurable: true,
  enumerable: true,
  writable: true,
  initializer: null
}), _descriptor2 = _applyDecoratedDescriptor(_class.prototype, "height", [_dec2], {
  configurable: true,
  enumerable: true,
  writable: true,
  initializer: null
}), _descriptor3 = _applyDecoratedDescriptor(_class.prototype, "maxHeight", [_dec3], {
  configurable: true,
  enumerable: true,
  writable: true,
  initializer: null
}), _descriptor4 = _applyDecoratedDescriptor(_class.prototype, "autoExpandPreview", [_dec4], {
  configurable: true,
  enumerable: true,
  writable: true,
  initializer: null
}), _descriptor5 = _applyDecoratedDescriptor(_class.prototype, "processingPluginList", [_dec5], {
  configurable: true,
  enumerable: true,
  writable: true,
  initializer: null
}), _descriptor6 = _applyDecoratedDescriptor(_class.prototype, "selectedNode", [tracked], {
  configurable: true,
  enumerable: true,
  writable: true,
  initializer: function () {
    return null;
  }
}), _descriptor7 = _applyDecoratedDescriptor(_class.prototype, "editorId", [tracked], {
  configurable: true,
  enumerable: true,
  writable: true,
  initializer: function () {
    return this.args.editorId ?? guidFor({});
  }
}), _descriptor8 = _applyDecoratedDescriptor(_class.prototype, "viewMode", [tracked], {
  configurable: true,
  enumerable: true,
  writable: true,
  initializer: function () {
    return this.args.initialViewMode || MODE_EDITING;
  }
}), _descriptor9 = _applyDecoratedDescriptor(_class.prototype, "textareaRef", [tracked], {
  configurable: true,
  enumerable: true,
  writable: true,
  initializer: function () {
    return null;
  }
}), _descriptor10 = _applyDecoratedDescriptor(_class.prototype, "previewRef", [tracked], {
  configurable: true,
  enumerable: true,
  writable: true,
  initializer: function () {
    return null;
  }
}), _descriptor11 = _applyDecoratedDescriptor(_class.prototype, "editorToolbarRef", [tracked], {
  configurable: true,
  enumerable: true,
  writable: true,
  initializer: function () {
    return null;
  }
}), _descriptor12 = _applyDecoratedDescriptor(_class.prototype, "currentHeight", [tracked], {
  configurable: true,
  enumerable: true,
  writable: true,
  initializer: function () {
    return 250;
  }
}), _descriptor13 = _applyDecoratedDescriptor(_class.prototype, "editorFooterHeight", [tracked], {
  configurable: true,
  enumerable: true,
  writable: true,
  initializer: function () {
    return 0;
  }
}), _descriptor14 = _applyDecoratedDescriptor(_class.prototype, "editorToolbarHeight", [tracked], {
  configurable: true,
  enumerable: true,
  writable: true,
  initializer: function () {
    return 0;
  }
}), _applyDecoratedDescriptor(_class.prototype, "onResize", [action], Object.getOwnPropertyDescriptor(_class.prototype, "onResize"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "updateCurrentHeight", [action], Object.getOwnPropertyDescriptor(_class.prototype, "updateCurrentHeight"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "setTextAreaRef", [action], Object.getOwnPropertyDescriptor(_class.prototype, "setTextAreaRef"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "setEditorToolbarRef", [action], Object.getOwnPropertyDescriptor(_class.prototype, "setEditorToolbarRef"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "replaceNode", [action], Object.getOwnPropertyDescriptor(_class.prototype, "replaceNode"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "setViewMode", [action], Object.getOwnPropertyDescriptor(_class.prototype, "setViewMode"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "parser", [cached], Object.getOwnPropertyDescriptor(_class.prototype, "parser"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "parsed", [cached], Object.getOwnPropertyDescriptor(_class.prototype, "parsed"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "onParse", [action], Object.getOwnPropertyDescriptor(_class.prototype, "onParse"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "setSelectedNode", [action], Object.getOwnPropertyDescriptor(_class.prototype, "setSelectedNode"), _class.prototype)), _class)));

export { EuiMarkdownEditorComponent as default, getCursorNode, getCursorNodeModifier };
//# sourceMappingURL=eui-markdown-editor.js.map
