import { Extension as A } from "@tiptap/core";
import { DecorationSet as p, Decoration as I } from "@tiptap/pm/view";
import { PluginKey as S, Plugin as T } from "@tiptap/pm/state";
const v = (e, t, n) => RegExp(t ? e.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") : e, n ? "gu" : "gui");
function y(e, t, n, r) {
  const l = [], o = [];
  let s = [], i = 0;
  if (!t)
    return {
      decorationsToReturn: p.empty,
      results: []
    };
  e == null || e.descendants((a, c) => {
    a.isText ? s[i] ? s[i] = {
      text: s[i].text + a.text,
      pos: s[i].pos
    } : s[i] = {
      text: `${a.text}`,
      pos: c
    } : i += 1;
  }), s = s.filter(Boolean);
  for (const a of s) {
    const { text: c, pos: u } = a, f = Array.from(c.matchAll(t));
    for (const d of f) {
      if (d[0] === "") break;
      d.index !== void 0 && o.push({
        from: u + d.index,
        to: u + d.index + d[0].length
      });
    }
  }
  for (let a = 0; a < o.length; a += 1) {
    const c = o[a], u = a === r ? `${n} ${n}-current` : n, f = I.inline(c.from, c.to, {
      class: u
    });
    l.push(f);
  }
  return {
    decorationsToReturn: p.create(e, l),
    results: o
  };
}
const C = (e, t, { state: n, dispatch: r }) => {
  if (!t[0]) return;
  const o = n.selection.from, s = t.findIndex((c) => o >= c.from && o <= c.to), { from: i, to: a } = t[s >= 0 ? s : 0];
  r && r(n.tr.insertText(e, i, a));
}, P = (e, t, n, r) => {
  const l = t + 1;
  if (!r[l]) return null;
  const { from: o, to: s } = r[t], i = s - o - e.length + n, { from: a, to: c } = r[l];
  return r[l] = {
    to: c - i,
    from: a - i
  }, [i, r];
}, b = (e, t, { tr: n, dispatch: r }) => {
  let l = 0, o = t.slice();
  if (o.length) {
    for (let s = 0; s < o.length; s += 1) {
      const { from: i, to: a } = o[s];
      n.insertText(e, i, a);
      const c = P(e, s, l, o);
      c && (l = c[0], o = c[1]);
    }
    r && r(n);
  }
}, $ = new S("searchAndReplacePlugin"), k = A.create({
  name: "searchAndReplace",
  addOptions() {
    return {
      searchResultClass: "html-editor-search-result",
      disableRegex: !0
    };
  },
  addStorage() {
    return {
      searchTerm: "",
      replaceTerm: "",
      results: [],
      lastSearchTerm: "",
      caseSensitive: !1,
      lastCaseSensitive: !1,
      resultIndex: 0,
      lastResultIndex: 0
    };
  },
  addCommands() {
    return {
      setSearchTerm: (e) => ({ editor: t }) => (t.storage.searchAndReplace.searchTerm = e, !1),
      setReplaceTerm: (e) => ({ editor: t }) => (t.storage.searchAndReplace.replaceTerm = e, !1),
      setCaseSensitive: (e) => ({ editor: t }) => (t.storage.searchAndReplace.caseSensitive = e, !1),
      resetIndex: () => ({ editor: e }) => (e.storage.searchAndReplace.resultIndex = 0, !1),
      nextSearchResult: () => ({ editor: e }) => {
        const { results: t, resultIndex: n } = e.storage.searchAndReplace, r = n + 1;
        return t[r] ? e.storage.searchAndReplace.resultIndex = r : e.storage.searchAndReplace.resultIndex = 0, !1;
      },
      previousSearchResult: () => ({ editor: e }) => {
        const { results: t, resultIndex: n } = e.storage.searchAndReplace, r = n - 1;
        return t[r] ? e.storage.searchAndReplace.resultIndex = r : e.storage.searchAndReplace.resultIndex = t.length - 1, !1;
      },
      replace: () => ({ editor: e, state: t, dispatch: n }) => {
        const { replaceTerm: r, results: l } = e.storage.searchAndReplace;
        return C(r, l, { state: t, dispatch: n }), !1;
      },
      replaceAll: () => ({ editor: e, tr: t, dispatch: n }) => {
        const { replaceTerm: r, results: l } = e.storage.searchAndReplace;
        return b(r, l, { tr: t, dispatch: n }), !1;
      }
    };
  },
  addProseMirrorPlugins() {
    const e = this.editor, { searchResultClass: t, disableRegex: n } = this.options, r = (s) => e.storage.searchAndReplace.lastSearchTerm = s, l = (s) => e.storage.searchAndReplace.lastCaseSensitive = s, o = (s) => e.storage.searchAndReplace.lastResultIndex = s;
    return [
      new T({
        key: $,
        state: {
          init: () => p.empty,
          apply(s, i) {
            const { doc: a, docChanged: c } = s, { searchTerm: u, lastSearchTerm: f, caseSensitive: d, lastCaseSensitive: x, resultIndex: h, lastResultIndex: m } = e.storage.searchAndReplace;
            if (!c && f === u && x === d && m === h)
              return i;
            if (r(u), l(d), o(h), !u)
              return e.storage.searchAndReplace.results = [], p.empty;
            const { decorationsToReturn: R, results: g } = y(
              a,
              v(u, n, d),
              t,
              h
            );
            return e.storage.searchAndReplace.results = g, R;
          }
        },
        props: {
          decorations(s) {
            return this.getState(s) ?? null;
          }
        }
      })
    ];
  }
});
export {
  k as SearchAndReplaceExtension,
  k as default,
  $ as searchAndReplacePluginKey
};
//# sourceMappingURL=searchAndReplaceExtension.js.map
