import { uuid } from '@atlaskit/adf-schema';
import { Slice } from '@atlaskit/editor-prosemirror/model';
import { mapFragment, mapSlice } from '../utils/slice';

/**
 * Lift content out of "open" top-level bodiedExtensions.
 * Will not work if bodiedExtensions are nested, or when bodiedExtensions are not in the top level
 */
export var transformSliceToRemoveOpenBodiedExtension = function transformSliceToRemoveOpenBodiedExtension(slice, schema) {
  var bodiedExtension = schema.nodes.bodiedExtension;
  var fragment = mapFragment(slice.content, function (node, parent, index) {
    if (node.type === bodiedExtension && !parent) {
      var currentNodeIsAtStartAndIsOpen = slice.openStart && index === 0;
      var currentNodeIsAtEndAndIsOpen = slice.openEnd && index + 1 === slice.content.childCount;
      if (currentNodeIsAtStartAndIsOpen || currentNodeIsAtEndAndIsOpen) {
        return node.content;
      }
    }
    return node;
  });

  // If the first/last child has changed - then we know we've removed a bodied extension & to decrement the open depth
  return new Slice(fragment,
  // Ignored via go/ees005
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
  fragment.firstChild && fragment.firstChild.type !== slice.content.firstChild.type ? slice.openStart - 1 : slice.openStart,
  // Ignored via go/ees005
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
  fragment.lastChild && fragment.lastChild.type !== slice.content.lastChild.type ? slice.openEnd - 1 : slice.openEnd);
};

/**
 * Lift content out of "open" top-level multiBodiedExtensions.
 * Will not work if multiBodiedExtensions are nested, or when multiBodiedExtensions are not in the top level, which should never happen
 */
// eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
export var transformSliceToRemoveOpenMultiBodiedExtension = function transformSliceToRemoveOpenMultiBodiedExtension(slice, schema) {
  var _slice$content$firstC, _slice$content$firstC2;
  var _schema$nodes = schema.nodes,
    multiBodiedExtension = _schema$nodes.multiBodiedExtension,
    extensionFrame = _schema$nodes.extensionFrame;
  var depthToReduce = 2; // Removing MBE and extensionFrame

  // Edge case where the slice does not contain extensionFrames under MBE, happens when multiple block nodes get copied from a frame
  if (((_slice$content$firstC = slice.content.firstChild) === null || _slice$content$firstC === void 0 ? void 0 : _slice$content$firstC.type) === multiBodiedExtension && ((_slice$content$firstC2 = slice.content.firstChild) === null || _slice$content$firstC2 === void 0 || (_slice$content$firstC2 = _slice$content$firstC2.firstChild) === null || _slice$content$firstC2 === void 0 ? void 0 : _slice$content$firstC2.type) !== extensionFrame) {
    depthToReduce = 1;
  }
  var fragment = mapFragment(slice.content, function (node, parent, index) {
    if (node.type === multiBodiedExtension && !parent || node.type === extensionFrame) {
      var currentNodeIsAtStartAndIsOpen = slice.openStart >= depthToReduce && index === 0;
      var currentNodeIsAtEndAndIsOpen = slice.openEnd >= depthToReduce && index + 1 === slice.content.childCount;
      if (currentNodeIsAtStartAndIsOpen || currentNodeIsAtEndAndIsOpen) {
        return node.content;
      }
    }
    if (node.type === multiBodiedExtension) {
      var _node$attrs$parameter;
      /* While pasting on the same page, macroId does not change until the page is published and causes collision with the existing macroId
       *  where switching tabs of one node changes the tabs for the other node, so we put a random macroId at paste to avoid collision
       */
      if ((_node$attrs$parameter = node.attrs.parameters) !== null && _node$attrs$parameter !== void 0 && (_node$attrs$parameter = _node$attrs$parameter.macroMetadata) !== null && _node$attrs$parameter !== void 0 && (_node$attrs$parameter = _node$attrs$parameter.macroId) !== null && _node$attrs$parameter !== void 0 && _node$attrs$parameter.value) {
        node.attrs.parameters.macroMetadata.macroId.value = uuid.generate();
      }
    }
    return node;
  });

  // If the first/last child has changed - then we know we've removed MBE and extensionFrame and need to decrement the open depth
  return new Slice(fragment,
  // Ignored via go/ees005
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
  fragment.firstChild && fragment.firstChild.type !== slice.content.firstChild.type ? slice.openStart - depthToReduce : slice.openStart,
  // Ignored via go/ees005
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
  fragment.lastChild && fragment.lastChild.type !== slice.content.lastChild.type ? slice.openEnd - depthToReduce : slice.openEnd);
};
var LEGACY_CONTENT_MACRO_EXTENSION_TYPE = 'com.atlassian.confluence.migration',
  LEGACY_CONTENT_MACRO_EXTENSION_KEY = 'legacy-content';
var isLegacyContentMacroExtension = function isLegacyContentMacroExtension(extensionNode) {
  var _extensionNode$attrs, _extensionNode$attrs2;
  return ((_extensionNode$attrs = extensionNode.attrs) === null || _extensionNode$attrs === void 0 ? void 0 : _extensionNode$attrs.extensionType) === LEGACY_CONTENT_MACRO_EXTENSION_TYPE && ((_extensionNode$attrs2 = extensionNode.attrs) === null || _extensionNode$attrs2 === void 0 ? void 0 : _extensionNode$attrs2.extensionKey) === LEGACY_CONTENT_MACRO_EXTENSION_KEY;
};

// eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
export var transformSliceToRemoveLegacyContentMacro = function transformSliceToRemoveLegacyContentMacro(slice, schema) {
  var extension = schema.nodes.extension;
  return mapSlice(slice, function (node) {
    if (node.type === extension && isLegacyContentMacroExtension(node)) {
      // Strip the node
      return null;
    }
    return node;
  });
};
// eslint-disable-next-line @atlaskit/editor/no-re-export
export { transformSliceToRemoveMacroId } from './transformSliceToRemoveMacroId';