import _createClass from "@babel/runtime/helpers/createClass";
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
import _inherits from "@babel/runtime/helpers/inherits";
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
import _toArray from "@babel/runtime/helpers/toArray";
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
import { Plugin } from '@atlaskit/editor-prosemirror/state';
import { fg } from '@atlaskit/platform-feature-flags';
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
import { isSSR } from '../core-utils/is-ssr';
import { getNodeIdProvider } from '../node-anchor/node-anchor-provider';
import { createProseMirrorMetadata } from '../prosemirror-dom-metadata';
import { ANCHOR_VARIABLE_NAME, isCSSAnchorSupported, isCSSAttrAnchorSupported } from '../styles/shared/native-anchor';
/**
 * 🧱 Internal Helper Function: Editor FE Platform
 *
 * Attaches generic ProseMirror metadata attributes to a given DOM element based on the properties of a ProseMirror node.
 * This function is useful for annotating DOM elements with metadata that describes the type and characteristics of the ProseMirror node.
 *
 *
 * @param {object} params - The parameters for the function.
 * @param {PMNode} params.node - The ProseMirror node from which to derive metadata.
 * @param {HTMLElement} params.dom - The DOM element to which the metadata attributes will be attached.
 */
export var attachGenericProseMirrorMetadata = function attachGenericProseMirrorMetadata(_ref) {
  var nodeOrMark = _ref.nodeOrMark,
    dom = _ref.dom,
    options = _ref.options;
  var metadata = createProseMirrorMetadata(nodeOrMark, options);
  Object.entries(metadata).forEach(function (_ref2) {
    var _ref3 = _slicedToArray(_ref2, 2),
      name = _ref3[0],
      value = _ref3[1];
    dom.setAttribute(name, value);
    if (name === 'data-node-anchor' && expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true)) {
      // if browser doesn't support CSS anchor, won't need the style
      // Or if it supports CSS attr() function as the value of anchor-name,
      // We won't need set the style
      if (!isCSSAnchorSupported() || isCSSAttrAnchorSupported()) {
        return;
      }

      // otherwise, we set the CSS variable for anchor-name
      dom.style.setProperty(ANCHOR_VARIABLE_NAME, "".concat(value));
      return;
    }
  });
};

/** Type guard to check if a Node is an HTMLElement in a safe way. */
var isHTMLElement = function isHTMLElement(element) {
  if (element === null || element === undefined) {
    return false;
  }

  // In SSR `HTMLElement` is not defined, so we need to use duck typing here
  return 'innerHTML' in element && 'style' in element && 'classList' in element;
};

// Wraper to avoid any exception during the get pos operation
// See this https://hello.atlassian.net/wiki/spaces/EDITOR/pages/2849713193/ED-19672+Extensions+Regression
// And this https://discuss.prosemirror.net/t/possible-bug-on-viewdesc-posbeforechild/5783
var wrapGetPosExceptions = function wrapGetPosExceptions(spec) {
  var _spec$props;
  if (!(spec !== null && spec !== void 0 && (_spec$props = spec.props) !== null && _spec$props !== void 0 && _spec$props.nodeViews)) {
    return spec;
  }
  var unsafeNodeViews = spec.props.nodeViews;
  var nodeIdProvider;
  var safeNodeViews = new Proxy(unsafeNodeViews, {
    get: function get(target, prop, receiver) {
      var safeNodeView = new Proxy(Reflect.get(target, prop, receiver), {
        apply: function apply(target, thisArg, argumentsList) {
          var _argumentsList = _toArray(argumentsList),
            node = _argumentsList[0],
            view = _argumentsList[1],
            unsafeGetPos = _argumentsList[2],
            more = _arrayLikeToArray(_argumentsList).slice(3);
          if (!nodeIdProvider && expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true)) {
            nodeIdProvider = getNodeIdProvider(view);
          }
          var safeGetPos = function () {
            try {
              return unsafeGetPos();
            } catch (e) {
              return;
            }

            // eslint-disable-next-line no-extra-bind
          }.bind(thisArg);
          var result = Reflect.apply(target, thisArg, [node, view, safeGetPos].concat(_toConsumableArray(more)));
          if ((result === null || result === void 0 ? void 0 : result.dom) instanceof HTMLElement ||
          // SSR result?.dom is not an instance of HTMLElement, but we still want to attach metadata to it
          isSSR() && isHTMLElement(result === null || result === void 0 ? void 0 : result.dom) && fg('platform_editor_native_anchor_patch_3')) {
            var _nodeIdProvider;
            // we only attach metadata to the dom if its position is known
            var pos = safeGetPos();
            var options = pos !== undefined && expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ? {
              anchrorId: (_nodeIdProvider = nodeIdProvider) === null || _nodeIdProvider === void 0 ? void 0 : _nodeIdProvider.getOrGenerateId(node, pos)
            } : undefined;
            attachGenericProseMirrorMetadata({
              nodeOrMark: node,
              dom: result.dom,
              options: options
            });
          }
          return result;
        }
      });
      return safeNodeView;
    }
  });
  spec.props.nodeViews = safeNodeViews;
  return spec;
};

// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export var SafePlugin = /*#__PURE__*/function (_Plugin) {
  // This variable isn't (and shouldn't) be used anywhere. Its purpose is
  // to distinguish Plugin from SafePlugin, thus ensuring that an 'unsafe'
  // Plugin cannot be assigned as an item in EditorPlugin → pmPlugins.

  function SafePlugin(spec) {
    _classCallCheck(this, SafePlugin);
    return _callSuper(this, SafePlugin, [wrapGetPosExceptions(spec)]);
  }
  _inherits(SafePlugin, _Plugin);
  return _createClass(SafePlugin);
}(Plugin);