import React from "react";
import {
  isBetweenFloatedNodes,
  isBetweenFullWidthNodes,
  isCollapsedBetween,
  isListContainer,
  isNodeSpaced,
  needsTopMargin
} from "./../../ricos-common-plugins/gap-spacer/gap-spacer-nodes.js";
import { Node_Type } from "./../../ricos-schema/legacy/wix/rich_content/v1/index.js";
import { GapSpacer } from "./../../ricos-viewer-next/ContentViewer/components/gap-spacer.js";
const getPrevSiblingNode = (node, map) => {
  if (node.index === 0) {
    return void 0;
  }
  if (node.parent) {
    return node.parent.children[node.index - 1];
  }
  const rootNodes = Object.values(map).filter((n) => n.depth === 0);
  return rootNodes.find((n) => n.index === node.index - 1);
};
const findNodeWithMetadata = (node, map, refMap) => {
  if (node.id) {
    return map[node.id];
  }
  return refMap.get(node);
};
const nodeMetaKey = (meta) => meta.node.id || `${meta.depth}-${meta.index}`;
const renderGapSpacerBeforeNodeIfNeeded = (node, index, nodeTreeMap, nodeRefMap) => {
  if (node.type === Node_Type.LAYOUT && node.layoutData?.banner?.position === "TOP") {
    return [];
  }
  const currentNode = findNodeWithMetadata(node, nodeTreeMap, nodeRefMap);
  if (!currentNode || !shouldPlaceGapSpacerBefore(nodeMetaKey(currentNode), nodeTreeMap)) {
    return [];
  }
  const prevNode = getPrevSiblingNode(currentNode, nodeTreeMap);
  const isCollapsed = shouldCollapseGapSpacer(prevNode, currentNode);
  const betweenFloated = isBetweenFloatedNodes(prevNode?.node, currentNode.node);
  const isFirstPosition = !prevNode && currentNode.depth === 0;
  const hasTopOverflow = needsTopMargin(currentNode.node.type);
  return [
    /* @__PURE__ */ React.createElement(
      GapSpacer,
      {
        key: `gap-spacer-${currentNode.node?.id || currentNode.index}`,
        collapsed: isCollapsed,
        betweenFloated,
        needsTopMargin: isFirstPosition && hasTopOverflow
      }
    )
  ];
};
const renderGapSpacerAfterLastNodeIfNeeded = (nodes, nodeTreeMap, nodeRefMap) => {
  if (nodes.length === 0) {
    return null;
  }
  const lastNode = nodes[nodes.length - 1];
  if (lastNode.type === Node_Type.LAYOUT && lastNode.layoutData?.banner?.position === "BOTTOM") {
    return null;
  }
  const lastNodeData = findNodeWithMetadata(lastNode, nodeTreeMap, nodeRefMap);
  if (!lastNodeData || !shouldPlaceGapSpacerAfter(nodeMetaKey(lastNodeData), nodeTreeMap)) {
    return null;
  }
  const isCollapsed = shouldCollapseGapSpacer(lastNodeData, void 0);
  return /* @__PURE__ */ React.createElement(
    GapSpacer,
    {
      key: `gap-spacer-${lastNodeData.node?.id || lastNodeData.index + 1}`,
      collapsed: isCollapsed
    }
  );
};
const isBetweenTwoLists = (currentNode, map) => {
  if (!isListContainer(currentNode.node.type)) {
    return false;
  }
  const prev = getPrevSiblingNode(currentNode, map);
  return !!prev && isListContainer(prev.node.type);
};
const shouldPlaceGapSpacerBefore = (nodeId, map) => {
  const currentNode = map[nodeId];
  const node = currentNode?.node;
  if (!currentNode || !node || isInlineContent(node)) {
    return false;
  }
  if (isBetweenTwoLists(currentNode, map)) {
    return false;
  }
  if (isInsideListItemContent(currentNode)) {
    return false;
  }
  if (currentNode.parent && shouldAvoidSpacingBetweenSiblings(currentNode)) {
    return false;
  }
  if (!currentNode.parent) {
    if (currentNode.index === 0) {
      return isNodeSpaced(node.type);
    }
    const rootNodes = Object.values(map).filter((n) => n.depth === 0);
    const prevSibling = rootNodes.find((n) => n.index === currentNode.index - 1);
    return prevSibling ? isNodeSpaced(prevSibling.node.type) && isNodeSpaced(node.type) : false;
  }
  if (!closedBefore(nodeId, map) || !closedAfter(nodeId, map)) {
    return false;
  }
  return true;
};
const shouldPlaceGapSpacerAfter = (nodeId, map) => {
  const currentNode = map[nodeId];
  const node = currentNode?.node;
  if (!currentNode || !node || isInlineContent(node)) {
    return false;
  }
  if (isInsideListItemContent(currentNode)) {
    return false;
  }
  if (isTextBlock(node)) {
    return false;
  }
  if (currentNode.parent && shouldAvoidSpacingBetweenSiblings(currentNode)) {
    return false;
  }
  return closedAfter(nodeId, map);
};
const isInsideListItemContent = (currentNode) => currentNode.parent?.node.type === Node_Type.LIST_ITEM;
const isInlineContent = (node) => {
  return node.type === Node_Type.TEXT;
};
const isTextBlock = (node) => {
  return [
    Node_Type.PARAGRAPH,
    Node_Type.HEADING,
    Node_Type.BLOCKQUOTE,
    Node_Type.CODE_BLOCK
  ].includes(node.type);
};
const shouldAvoidSpacingBetweenSiblings = (currentNode) => {
  const parent = currentNode.parent;
  if (!parent) {
    return false;
  }
  if (parent.node.type === Node_Type.TABLE_ROW && currentNode.node.type === Node_Type.TABLE_CELL) {
    return true;
  }
  if (parent.node.type === Node_Type.TABLE && currentNode.node.type === Node_Type.TABLE_ROW) {
    return true;
  }
  if (parent.node.type === Node_Type.LAYOUT && currentNode.node.type === Node_Type.LAYOUT_CELL) {
    return true;
  }
  if (parent.node.type === Node_Type.COLLAPSIBLE_LIST && currentNode.node.type === Node_Type.COLLAPSIBLE_ITEM) {
    return true;
  }
  if (parent.node.type === Node_Type.COLLAPSIBLE_ITEM && (currentNode.node.type === Node_Type.COLLAPSIBLE_ITEM_TITLE || currentNode.node.type === Node_Type.COLLAPSIBLE_ITEM_BODY)) {
    return true;
  }
  if (isListContainer(parent.node.type) && currentNode.node.type === Node_Type.LIST_ITEM) {
    return true;
  }
  if (parent.node.type === Node_Type.LIST_ITEM && isListContainer(currentNode.node.type)) {
    return true;
  }
  return false;
};
const closedBefore = (nodeId, map) => {
  const startNode = map[nodeId];
  if (!startNode) {
    return false;
  }
  if (startNode.depth === 0) {
    if (startNode.index === 0) {
      return isNodeSpaced(startNode.node.type);
    }
    const rootNodes = Object.values(map).filter((n) => n.depth === 0);
    const prevSibling = rootNodes.find((n) => n.index === startNode.index - 1);
    return prevSibling ? isNodeSpaced(prevSibling.node.type) : false;
  }
  if (isTextBlock(startNode.node)) {
    return false;
  }
  for (let d = startNode.depth; d >= 0; d--) {
    let nodeAtDepth = startNode;
    while (nodeAtDepth && nodeAtDepth.depth > d) {
      nodeAtDepth = nodeAtDepth.parent;
    }
    if (!nodeAtDepth || nodeAtDepth.depth !== d) {
      continue;
    }
    const index = nodeAtDepth.index;
    const parent = nodeAtDepth.parent;
    if (index === 0) {
      if (parent && isNodeSpaced(parent.node.type)) {
        return true;
      }
      continue;
    }
    if (parent && parent.children[index - 1]) {
      let before = parent.children[index - 1];
      while (before.children.length > 0) {
        before = before.children[before.children.length - 1];
      }
      if (before.children.length === 0 && !isInlineContent(before.node)) {
        return isNodeSpaced(before.node.type);
      }
      if (isNodeSpaced(before.node.type)) {
        return true;
      }
      if (isInlineContent(before.node)) {
        return false;
      }
    }
  }
  return false;
};
const closedAfter = (nodeId, map) => {
  const startNode = map[nodeId];
  if (!startNode) {
    return false;
  }
  let currentNode = startNode;
  for (let d = startNode.depth; d >= 0; d--) {
    const parent = currentNode.parent;
    const indexAfter = currentNode.index + 1;
    if (!parent || indexAfter >= parent.children.length) {
      if (d === 0) {
        return isNodeSpaced(currentNode.node.type);
      }
      if (parent && isNodeSpaced(parent.node.type)) {
        return true;
      }
      if (!parent) {
        break;
      }
      currentNode = parent;
      continue;
    }
    let after = parent.children[indexAfter];
    while (after.children.length > 0) {
      after = after.children[0];
    }
    if (after.children.length === 0 && !isInlineContent(after.node)) {
      return isNodeSpaced(after.node.type);
    }
    if (isNodeSpaced(after.node.type)) {
      return true;
    }
    if (isInlineContent(after.node)) {
      return false;
    }
    if (!parent) {
      break;
    }
    currentNode = parent;
  }
  return false;
};
const shouldCollapseGapSpacer = (prevNode, nextNode) => {
  const parentNode = prevNode?.parent || nextNode?.parent;
  const bothFullWidth = isBetweenFullWidthNodes(prevNode?.node, nextNode?.node);
  return isCollapsedBetween(prevNode?.node.type, nextNode?.node.type, parentNode?.node.type, {
    bothFullWidth
  });
};
export {
  renderGapSpacerAfterLastNodeIfNeeded,
  renderGapSpacerBeforeNodeIfNeeded
};
//# sourceMappingURL=gap-spacer-viewer.js.map
