"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var banner_drop_prevention_plugin_exports = {};
__export(banner_drop_prevention_plugin_exports, {
  createBannerDropPreventionPlugin: () => createBannerDropPreventionPlugin,
  isAfterLastFooterCell: () => isAfterLastFooterCell,
  isBeforeFirstBannerCell: () => isBeforeFirstBannerCell
});
module.exports = __toCommonJS(banner_drop_prevention_plugin_exports);
var import_ricos_content = require("./../../ricos-content/index.js");
var import_tiptap = require("./../../tiptap/index.js");
var import_state = require("./../../tiptap/pm/state.js");
const bannerDropPreventionPluginKey = new import_state.PluginKey("banner-drop-prevention");
const isBannerLayout = (node) => node.type.name === import_ricos_content.TIPTAP_LAYOUT_TYPE && !!node.attrs?.banner;
const isValidBannerLocation = (newNode, $pos, position) => {
  const effective = position ?? "TOP";
  const parentType = $pos.parent.type.name;
  if (effective === "TOP") {
    if (parentType === import_ricos_content.TIPTAP_CARD_HEADER_TYPE) {
      return true;
    }
    if ($pos.depth === 0 && $pos.doc.firstChild === newNode) {
      return true;
    }
    return false;
  }
  if (parentType === import_ricos_content.TIPTAP_CARD_FOOTER_TYPE) {
    return true;
  }
  return true;
};
const isBeforeFirstBannerCell = ($pos) => {
  const nodeAfter = $pos.nodeAfter;
  return nodeAfter?.type.name === import_ricos_content.TIPTAP_LAYOUT_CELL_TYPE && $pos.parent.attrs?.banner?.position === "TOP" && $pos.index() === 0;
};
const isAfterLastFooterCell = ($pos) => {
  const nodeBefore = $pos.nodeBefore;
  return nodeBefore?.type.name === import_ricos_content.TIPTAP_LAYOUT_CELL_TYPE && $pos.parent.attrs?.banner?.position === "BOTTOM" && $pos.index() === $pos.parent.childCount;
};
const isDropBeforeTopBanner = ($pos) => {
  const doc = $pos.doc;
  const firstChild = doc.firstChild;
  if (firstChild?.type.name === import_ricos_content.TIPTAP_LAYOUT_TYPE && firstChild.attrs?.banner?.position === "TOP") {
    if ($pos.pos <= 1) {
      return true;
    }
  }
  return false;
};
const isDropAfterBottomBanner = ($pos) => {
  const doc = $pos.doc;
  const lastChild = doc.lastChild;
  if (lastChild?.type.name === import_ricos_content.TIPTAP_LAYOUT_TYPE && lastChild.attrs?.banner?.position === "BOTTOM") {
    if ($pos.pos >= doc.content.size - 1) {
      return true;
    }
  }
  return false;
};
const createBannerDropPreventionPlugin = () => {
  return new import_state.Plugin({
    key: bannerDropPreventionPluginKey,
    props: {
      handleDrop: (view, event) => {
        if (!event) {
          return false;
        }
        const coordinates = view.posAtCoords({
          left: event.clientX,
          top: event.clientY
        });
        if (!coordinates) {
          return false;
        }
        try {
          const $pos = view.state.doc.resolve(coordinates.pos);
          if (isBeforeFirstBannerCell($pos)) {
            event.preventDefault();
            return true;
          }
          if (isAfterLastFooterCell($pos)) {
            event.preventDefault();
            return true;
          }
          if (isDropBeforeTopBanner($pos)) {
            event.preventDefault();
            return true;
          }
          if (isDropAfterBottomBanner($pos)) {
            event.preventDefault();
            return true;
          }
        } catch {
          return false;
        }
        return false;
      },
      // Block dragstart on banner layout chrome and cell shells/handles; allow
      // prose and inner nodes inside [data-layout-cell-content]. #text targets
      // are resolved via parentElement (see cell-node-view.ts DOM structure).
      handleDOMEvents: {
        dragstart: (_view, event) => {
          const raw = event.target;
          const element = raw instanceof Element ? raw : raw instanceof Text ? raw.parentElement : null;
          if (!element?.closest("[data-layout-banner]")) {
            return false;
          }
          if (element.closest("[data-layout-cell-content]")) {
            return false;
          }
          event.preventDefault();
          return true;
        }
      }
    },
    // Filter transactions to prevent banner movement (but allow deletion).
    //
    // Walks the original doc's descendants for all banner LAYOUTs (not just
    // doc.firstChild / doc.lastChild) so banners nested inside CARD_HEADER /
    // CARD_FOOTER are protected symmetrically with legacy doc-level banners.
    //
    // For each banner that still exists in the new doc with its banner attr
    // intact, the new location must be one of:
    //   - inside `CARD_HEADER` (TOP) or `CARD_FOOTER` (BOTTOM) — the schema
    //     pins these slots at the card's first/last child;
    //   - the doc-level first child (legacy doc-level TOP banner).
    // Demoted banners (banner attr cleared) are allowed anywhere — the
    // demote-then-re-insert flow used by `/banner` and `setLayoutBanner`
    // relies on this.
    filterTransaction: (tr, state) => {
      if (!tr.docChanged) {
        return true;
      }
      const originalBanners = (0, import_tiptap.findChildren)(state.doc, isBannerLayout).map(
        ({ node }) => ({
          id: node.attrs.id,
          position: node.attrs.banner?.position
        })
      );
      for (const original of originalBanners) {
        const inNewDoc = (0, import_tiptap.findChildren)(tr.doc, (n) => n.attrs?.id === original.id)[0];
        if (!inNewDoc) {
          continue;
        }
        if (!isBannerLayout(inNewDoc.node)) {
          continue;
        }
        const $newPos = tr.doc.resolve(inNewDoc.pos);
        if (!isValidBannerLocation(inNewDoc.node, $newPos, original.position)) {
          return false;
        }
      }
      return true;
    }
  });
};
//# sourceMappingURL=banner-drop-prevention-plugin.js.map
