import h, { D as x } from "../../../../quill-delta@5.1.0/node_modules/quill-delta/dist/Delta.mjs";
import { EmbedBlot as U, TextBlot as E, Scope as B } from "../../../../parchment@3.0.0/node_modules/parchment/dist/parchment.mjs";
import r from "../core/quill.mjs";
import K from "../core/logger.mjs";
import T from "../core/module.mjs";
import A from "../../../../lodash-es@4.17.21/node_modules/lodash-es/isEqual.mjs";
import D from "../../../../lodash-es@4.17.21/node_modules/lodash-es/cloneDeep.mjs";
const F = K("quill:keyboard"), C = /Mac/i.test(navigator.platform) ? "metaKey" : "ctrlKey";
class S extends T {
  static match(e, l) {
    return ["altKey", "ctrlKey", "metaKey", "shiftKey"].some((s) => !!l[s] !== e[s] && l[s] !== null) ? !1 : l.key === e.key || l.key === e.which;
  }
  constructor(e, l) {
    super(e, l), this.bindings = {}, Object.keys(this.options.bindings).forEach((s) => {
      this.options.bindings[s] && this.addBinding(this.options.bindings[s]);
    }), this.addBinding({
      key: "Enter",
      shiftKey: null
    }, this.handleEnter), this.addBinding({
      key: "Enter",
      metaKey: null,
      ctrlKey: null,
      altKey: null
    }, () => {
    }), /Firefox/i.test(navigator.userAgent) ? (this.addBinding({
      key: "Backspace"
    }, {
      collapsed: !0
    }, this.handleBackspace), this.addBinding({
      key: "Delete"
    }, {
      collapsed: !0
    }, this.handleDelete)) : (this.addBinding({
      key: "Backspace"
    }, {
      collapsed: !0,
      prefix: /^.?$/
    }, this.handleBackspace), this.addBinding({
      key: "Delete"
    }, {
      collapsed: !0,
      suffix: /^.?$/
    }, this.handleDelete)), this.addBinding({
      key: "Backspace"
    }, {
      collapsed: !1
    }, this.handleDeleteRange), this.addBinding({
      key: "Delete"
    }, {
      collapsed: !1
    }, this.handleDeleteRange), this.addBinding({
      key: "Backspace",
      altKey: null,
      ctrlKey: null,
      metaKey: null,
      shiftKey: null
    }, {
      collapsed: !0,
      offset: 0
    }, this.handleBackspace), this.listen();
  }
  addBinding(e) {
    let l = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {}, s = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : {};
    const i = N(e);
    if (i == null) {
      F.warn("Attempted to add invalid keyboard binding", i);
      return;
    }
    typeof l == "function" && (l = {
      handler: l
    }), typeof s == "function" && (s = {
      handler: s
    }), (Array.isArray(i.key) ? i.key : [i.key]).forEach((n) => {
      const u = {
        ...i,
        key: n,
        ...l,
        ...s
      };
      this.bindings[u.key] = this.bindings[u.key] || [], this.bindings[u.key].push(u);
    });
  }
  listen() {
    this.quill.root.addEventListener("keydown", (e) => {
      if (e.defaultPrevented || e.isComposing || e.keyCode === 229 && (e.key === "Enter" || e.key === "Backspace"))
        return;
      const i = (this.bindings[e.key] || []).concat(this.bindings[e.which] || []).filter((a) => S.match(e, a));
      if (i.length === 0)
        return;
      const o = r.find(e.target, !0);
      if (o && o.scroll !== this.quill.scroll)
        return;
      const n = this.quill.getSelection();
      if (n == null || !this.quill.hasFocus())
        return;
      const [u, f] = this.quill.getLine(n.index), [c, p] = this.quill.getLeaf(n.index), [y, R] = n.length === 0 ? [c, p] : this.quill.getLeaf(n.index + n.length), L = c instanceof E ? c.value().slice(0, p) : "", w = y instanceof E ? y.value().slice(R) : "", d = {
        collapsed: n.length === 0,
        // @ts-expect-error Fix me later
        empty: n.length === 0 && u.length() <= 1,
        format: this.quill.getFormat(n),
        line: u,
        offset: f,
        prefix: L,
        suffix: w,
        event: e
      };
      i.some((a) => {
        if (a.collapsed != null && a.collapsed !== d.collapsed || a.empty != null && a.empty !== d.empty || a.offset != null && a.offset !== d.offset)
          return !1;
        if (Array.isArray(a.format)) {
          if (a.format.every((m) => d.format[m] == null))
            return !1;
        } else if (typeof a.format == "object" && !Object.keys(a.format).every((m) => a.format[m] === !0 ? d.format[m] != null : a.format[m] === !1 ? d.format[m] == null : A(a.format[m], d.format[m])))
          return !1;
        return a.prefix != null && !a.prefix.test(d.prefix) || a.suffix != null && !a.suffix.test(d.suffix) ? !1 : a.handler.call(this, n, d, a) !== !0;
      }) && e.preventDefault();
    });
  }
  handleBackspace(e, l) {
    const s = /[\uD800-\uDBFF][\uDC00-\uDFFF]$/.test(l.prefix) ? 2 : 1;
    if (e.index === 0 || this.quill.getLength() <= 1)
      return;
    let i = {};
    const [o] = this.quill.getLine(e.index);
    let n = new h().retain(e.index - s).delete(s);
    if (l.offset === 0) {
      const [u] = this.quill.getLine(e.index - 1);
      if (u && !(u.statics.blotName === "block" && u.length() <= 1)) {
        const c = o.formats(), p = this.quill.getFormat(e.index - 1, 1);
        if (i = x.AttributeMap.diff(c, p) || {}, Object.keys(i).length > 0) {
          const y = new h().retain(e.index + o.length() - 2).retain(1, i);
          n = n.compose(y);
        }
      }
    }
    this.quill.updateContents(n, r.sources.USER), this.quill.focus();
  }
  handleDelete(e, l) {
    const s = /^[\uD800-\uDBFF][\uDC00-\uDFFF]/.test(l.suffix) ? 2 : 1;
    if (e.index >= this.quill.getLength() - s)
      return;
    let i = {};
    const [o] = this.quill.getLine(e.index);
    let n = new h().retain(e.index).delete(s);
    if (l.offset >= o.length() - 1) {
      const [u] = this.quill.getLine(e.index + 1);
      if (u) {
        const f = o.formats(), c = this.quill.getFormat(e.index, 1);
        i = x.AttributeMap.diff(f, c) || {}, Object.keys(i).length > 0 && (n = n.retain(u.length() - 1).retain(1, i));
      }
    }
    this.quill.updateContents(n, r.sources.USER), this.quill.focus();
  }
  handleDeleteRange(e) {
    I({
      range: e,
      quill: this.quill
    }), this.quill.focus();
  }
  handleEnter(e, l) {
    const s = Object.keys(l.format).reduce((o, n) => (this.quill.scroll.query(n, B.BLOCK) && !Array.isArray(l.format[n]) && (o[n] = l.format[n]), o), {}), i = new h().retain(e.index).delete(e.length).insert(`
`, s);
    this.quill.updateContents(i, r.sources.USER), this.quill.setSelection(e.index + 1, r.sources.SILENT), this.quill.focus();
  }
}
const v = {
  bindings: {
    bold: k("bold"),
    italic: k("italic"),
    underline: k("underline"),
    indent: {
      // highlight tab or tab at beginning of list, indent or blockquote
      key: "Tab",
      format: ["blockquote", "indent", "list"],
      handler(t, e) {
        return e.collapsed && e.offset !== 0 ? !0 : (this.quill.format("indent", "+1", r.sources.USER), !1);
      }
    },
    outdent: {
      key: "Tab",
      shiftKey: !0,
      format: ["blockquote", "indent", "list"],
      // highlight tab or tab at beginning of list, indent or blockquote
      handler(t, e) {
        return e.collapsed && e.offset !== 0 ? !0 : (this.quill.format("indent", "-1", r.sources.USER), !1);
      }
    },
    "outdent backspace": {
      key: "Backspace",
      collapsed: !0,
      shiftKey: null,
      metaKey: null,
      ctrlKey: null,
      altKey: null,
      format: ["indent", "list"],
      offset: 0,
      handler(t, e) {
        e.format.indent != null ? this.quill.format("indent", "-1", r.sources.USER) : e.format.list != null && this.quill.format("list", !1, r.sources.USER);
      }
    },
    "indent code-block": g(!0),
    "outdent code-block": g(!1),
    "remove tab": {
      key: "Tab",
      shiftKey: !0,
      collapsed: !0,
      prefix: /\t$/,
      handler(t) {
        this.quill.deleteText(t.index - 1, 1, r.sources.USER);
      }
    },
    tab: {
      key: "Tab",
      handler(t, e) {
        if (e.format.table)
          return !0;
        this.quill.history.cutoff();
        const l = new h().retain(t.index).delete(t.length).insert("	");
        return this.quill.updateContents(l, r.sources.USER), this.quill.history.cutoff(), this.quill.setSelection(t.index + 1, r.sources.SILENT), !1;
      }
    },
    "blockquote empty enter": {
      key: "Enter",
      collapsed: !0,
      format: ["blockquote"],
      empty: !0,
      handler() {
        this.quill.format("blockquote", !1, r.sources.USER);
      }
    },
    "list empty enter": {
      key: "Enter",
      collapsed: !0,
      format: ["list"],
      empty: !0,
      handler(t, e) {
        const l = {
          list: !1
        };
        e.format.indent && (l.indent = !1), this.quill.formatLine(t.index, t.length, l, r.sources.USER);
      }
    },
    "checklist enter": {
      key: "Enter",
      collapsed: !0,
      format: {
        list: "checked"
      },
      handler(t) {
        const [e, l] = this.quill.getLine(t.index), s = {
          // @ts-expect-error Fix me later
          ...e.formats(),
          list: "checked"
        }, i = new h().retain(t.index).insert(`
`, s).retain(e.length() - l - 1).retain(1, {
          list: "unchecked"
        });
        this.quill.updateContents(i, r.sources.USER), this.quill.setSelection(t.index + 1, r.sources.SILENT), this.quill.scrollSelectionIntoView();
      }
    },
    "header enter": {
      key: "Enter",
      collapsed: !0,
      format: ["header"],
      suffix: /^$/,
      handler(t, e) {
        const [l, s] = this.quill.getLine(t.index), i = new h().retain(t.index).insert(`
`, e.format).retain(l.length() - s - 1).retain(1, {
          header: null
        });
        this.quill.updateContents(i, r.sources.USER), this.quill.setSelection(t.index + 1, r.sources.SILENT), this.quill.scrollSelectionIntoView();
      }
    },
    "table backspace": {
      key: "Backspace",
      format: ["table"],
      collapsed: !0,
      offset: 0,
      handler() {
      }
    },
    "table delete": {
      key: "Delete",
      format: ["table"],
      collapsed: !0,
      suffix: /^$/,
      handler() {
      }
    },
    "table enter": {
      key: "Enter",
      shiftKey: null,
      format: ["table"],
      handler(t) {
        const e = this.quill.getModule("table");
        if (e) {
          const [l, s, i, o] = e.getTable(t), n = $(l, s, i, o);
          if (n == null)
            return;
          let u = l.offset();
          if (n < 0) {
            const f = new h().retain(u).insert(`
`);
            this.quill.updateContents(f, r.sources.USER), this.quill.setSelection(t.index + 1, t.length, r.sources.SILENT);
          } else if (n > 0) {
            u += l.length();
            const f = new h().retain(u).insert(`
`);
            this.quill.updateContents(f, r.sources.USER), this.quill.setSelection(u, r.sources.USER);
          }
        }
      }
    },
    "table tab": {
      key: "Tab",
      shiftKey: null,
      format: ["table"],
      handler(t, e) {
        const {
          event: l,
          line: s
        } = e, i = s.offset(this.quill.scroll);
        l.shiftKey ? this.quill.setSelection(i - 1, r.sources.USER) : this.quill.setSelection(i + s.length(), r.sources.USER);
      }
    },
    "list autofill": {
      key: " ",
      shiftKey: null,
      collapsed: !0,
      format: {
        "code-block": !1,
        blockquote: !1,
        table: !1
      },
      prefix: /^\s*?(\d+\.|-|\*|\[ ?\]|\[x\])$/,
      handler(t, e) {
        if (this.quill.scroll.query("list") == null)
          return !0;
        const {
          length: l
        } = e.prefix, [s, i] = this.quill.getLine(t.index);
        if (i > l)
          return !0;
        let o;
        switch (e.prefix.trim()) {
          case "[]":
          case "[ ]":
            o = "unchecked";
            break;
          case "[x]":
            o = "checked";
            break;
          case "-":
          case "*":
            o = "bullet";
            break;
          default:
            o = "ordered";
        }
        this.quill.insertText(t.index, " ", r.sources.USER), this.quill.history.cutoff();
        const n = new h().retain(t.index - i).delete(l + 1).retain(s.length() - 2 - i).retain(1, {
          list: o
        });
        return this.quill.updateContents(n, r.sources.USER), this.quill.history.cutoff(), this.quill.setSelection(t.index - l, r.sources.SILENT), !1;
      }
    },
    "code exit": {
      key: "Enter",
      collapsed: !0,
      format: ["code-block"],
      prefix: /^$/,
      suffix: /^\s*$/,
      handler(t) {
        const [e, l] = this.quill.getLine(t.index);
        let s = 2, i = e;
        for (; i != null && i.length() <= 1 && i.formats()["code-block"]; )
          if (i = i.prev, s -= 1, s <= 0) {
            const o = new h().retain(t.index + e.length() - l - 2).retain(1, {
              "code-block": null
            }).delete(1);
            return this.quill.updateContents(o, r.sources.USER), this.quill.setSelection(t.index - 1, r.sources.SILENT), !1;
          }
        return !0;
      }
    },
    "embed left": q("ArrowLeft", !1),
    "embed left shift": q("ArrowLeft", !0),
    "embed right": q("ArrowRight", !1),
    "embed right shift": q("ArrowRight", !0),
    "table down": b(!1),
    "table up": b(!0)
  }
};
S.DEFAULTS = v;
function g(t) {
  return {
    key: "Tab",
    shiftKey: !t,
    format: {
      "code-block": !0
    },
    handler(e, l) {
      let {
        event: s
      } = l;
      const i = this.quill.scroll.query("code-block"), {
        TAB: o
      } = i;
      if (e.length === 0 && !s.shiftKey) {
        this.quill.insertText(e.index, o, r.sources.USER), this.quill.setSelection(e.index + o.length, r.sources.SILENT);
        return;
      }
      const n = e.length === 0 ? this.quill.getLines(e.index, 1) : this.quill.getLines(e);
      let {
        index: u,
        length: f
      } = e;
      n.forEach((c, p) => {
        t ? (c.insertAt(0, o), p === 0 ? u += o.length : f += o.length) : c.domNode.textContent.startsWith(o) && (c.deleteAt(0, o.length), p === 0 ? u -= o.length : f -= o.length);
      }), this.quill.update(r.sources.USER), this.quill.setSelection(u, f, r.sources.SILENT);
    }
  };
}
function q(t, e) {
  return {
    key: t,
    shiftKey: e,
    altKey: null,
    [t === "ArrowLeft" ? "prefix" : "suffix"]: /^$/,
    handler(s) {
      let {
        index: i
      } = s;
      t === "ArrowRight" && (i += s.length + 1);
      const [o] = this.quill.getLeaf(i);
      return o instanceof U ? (t === "ArrowLeft" ? e ? this.quill.setSelection(s.index - 1, s.length + 1, r.sources.USER) : this.quill.setSelection(s.index - 1, r.sources.USER) : e ? this.quill.setSelection(s.index, s.length + 1, r.sources.USER) : this.quill.setSelection(s.index + s.length + 1, r.sources.USER), !1) : !0;
    }
  };
}
function k(t) {
  return {
    key: t[0],
    shortKey: !0,
    handler(e, l) {
      this.quill.format(t, !l.format[t], r.sources.USER);
    }
  };
}
function b(t) {
  return {
    key: t ? "ArrowUp" : "ArrowDown",
    collapsed: !0,
    format: ["table"],
    handler(e, l) {
      const s = t ? "prev" : "next", i = l.line, o = i.parent[s];
      if (o != null) {
        if (o.statics.blotName === "table-row") {
          let n = o.children.head, u = i;
          for (; u.prev != null; )
            u = u.prev, n = n.next;
          const f = n.offset(this.quill.scroll) + Math.min(l.offset, n.length() - 1);
          this.quill.setSelection(f, 0, r.sources.USER);
        }
      } else {
        const n = i.table()[s];
        n != null && (t ? this.quill.setSelection(n.offset(this.quill.scroll) + n.length() - 1, 0, r.sources.USER) : this.quill.setSelection(n.offset(this.quill.scroll), 0, r.sources.USER));
      }
      return !1;
    }
  };
}
function N(t) {
  if (typeof t == "string" || typeof t == "number")
    t = {
      key: t
    };
  else if (typeof t == "object")
    t = D(t);
  else
    return null;
  return t.shortKey && (t[C] = t.shortKey, delete t.shortKey), t;
}
function I(t) {
  let {
    quill: e,
    range: l
  } = t;
  const s = e.getLines(l);
  let i = {};
  if (s.length > 1) {
    const o = s[0].formats(), n = s[s.length - 1].formats();
    i = x.AttributeMap.diff(n, o) || {};
  }
  e.deleteText(l, r.sources.USER), Object.keys(i).length > 0 && e.formatLine(l.index, 1, i, r.sources.USER), e.setSelection(l.index, r.sources.SILENT);
}
function $(t, e, l, s) {
  return e.prev == null && e.next == null ? l.prev == null && l.next == null ? s === 0 ? -1 : 1 : l.prev == null ? -1 : 1 : e.prev == null ? -1 : e.next == null ? 1 : null;
}
export {
  C as SHORTKEY,
  S as default,
  I as deleteRange,
  N as normalize
};
