

(function () {
 /*
  if (window.__hmQuillInitialized) {
    console.log("Quill already initialized, skipping.");
    return;
  }
 */
  window.__hmQuillInitialized = true;

  console.log("Quilljs laden...");

  window.outlookImg = null; 
  let savedRange = null;

  function isWhitespace(ch) {
    return ch === " " || ch === "\t" || ch === "\n";
  }

  function base64ToBlob(base64, mime) {
    mime = mime || "";
    const sliceSize = 1024;
    try {
      const byteChars = window.atob(base64);
      const byteArrays = [];
      for (let offset = 0; offset < byteChars.length; offset += sliceSize) {
        const slice = byteChars.slice(offset, offset + sliceSize);
        const byteNumbers = new Array(slice.length);
        for (let i = 0; i < slice.length; i++) byteNumbers[i] = slice.charCodeAt(i);
        byteArrays.push(new Uint8Array(byteNumbers));
      }
      return new Blob(byteArrays, { type: mime });
    } catch (e) {
      return null;
    }
  }

  function getInsertIndex(quill) {
    let index = (quill.getSelection() || {}).index;
    if (index === undefined || index < 0) index = quill.getLength();
    return index;
  }

  function isKnowledgebaseMode() {
    try {
      return typeof moduleVar !== "undefined" && moduleVar === "knowledgebase";
    } catch (_) {
      return false;
    }
  }

  function eventIsFromThisEditor(quill, e) {
    const t = e.target;
    return t && (t === quill.root || quill.root.contains(t));
  }

  function getImageFilesFromClipboard(dt) {
    const out = [];

    if (dt.files && dt.files.length) {
      for (const f of Array.from(dt.files)) {
        if (f && f.type && f.type.startsWith("image/")) out.push(f);
      }
      if (out.length) return out;
    }

    if (dt.items && dt.items.length) {
      for (const it of Array.from(dt.items)) {
        if (it && it.type && it.type.startsWith("image/")) {
          const f = it.getAsFile();
          if (f) out.push(f);
        }
      }
    }

    return out;
  }

  async function extractImageFilesFromPasteEvent(e) {
    const dt = e.clipboardData;
    if (!dt) return [];

    const direct = getImageFilesFromClipboard(dt);
    if (direct.length) return direct;

    if (navigator.clipboard?.read) {
      try {
        const items = await navigator.clipboard.read();
        for (const ci of items) {
          const type = ci.types.find((t) => t.startsWith("image/"));
          if (!type) continue;
          const blob = await ci.getType(type);
          const ext = type.split("/")[1] || "png";
          const file = new File([blob], "pasted-image." + ext, { type });
          return [file];
        }
      } catch (err) {
        console.warn("navigator.clipboard.read() failed:", err);
      }
    }

    return [];
  }

  function uploadImageFileAndInsert(quill, fileOrBlob, kb) {
    const formData = new FormData();
    formData.append("file", fileOrBlob);

    return $.ajax({
      url: "index.php?module=upload&event=uploadImageDirectly&kb=" + (kb ? 1 : 0),
      type: "POST",
      data: formData,
      cache: false,
      contentType: false,
      processData: false
    }).done(function (data) {
      if (!data || data === "Nofile") return;

      const index = getInsertIndex(quill);
      const url = "index.php?module=upload&event=ShowImage&name=" + data;

      quill.insertEmbed(index, "image", url, "user");

      try {
        quill.formatText(index, 1, "max-width", "100%");
      } catch (_) {}

      setTimeout(() => {
        const r = quill.getSelection(true);
        if (r) quill.setSelection(r.index + 1, 0, "silent");
      }, 0);
    });
  }

  const Delta = Quill.import("delta");

  const Image = Quill.import("formats/image");
  Image.className = "hm-img-fluid";
  Image.sanitize = function (url) { return url; };
  Quill.register(Image, true);

  const BlockEmbed = Quill.import("blots/block/embed");

  class IframeBlot extends BlockEmbed {
    static blotName = "iframe";
    static tagName = "iframe";

    static create(value) {
      const node = super.create();

      const src = (typeof value === "string") ? value : (value?.src || "");
      node.setAttribute("src", src);

      node.setAttribute("frameborder", "0");
      node.setAttribute("allowfullscreen", "true");

      node.setAttribute("sandbox", "allow-scripts allow-same-origin allow-popups allow-forms");

      const width = (typeof value === "object" && value?.width) ? value.width : "100%";
      const height = (typeof value === "object" && value?.height) ? value.height : "400";

      node.setAttribute("width", width);
      node.setAttribute("height", height);

      node.style.width = width;
      node.style.minHeight = height + "px";

      return node;
    }

    static value(node) {
      return {
        src: node.getAttribute("src"),
        width: node.getAttribute("width"),
        height: node.getAttribute("height")
      };
    }
  }

  Quill.register(IframeBlot, true);

  function isAllowedIframeUrl(url) {
    try {
      const u = new URL(url, window.location.origin);
      // your whitelist; expand as needed
      const allowed = ["localhost"];
      return allowed.includes(u.hostname);
    } catch {
      return false;
    }
  }



  const quill = new Quill("#editor", {
    theme: "snow",
    placeholder: "Hier bitte Beschreibung eingeben",
    modules: {
      toolbar: "#toolbar-container",
      clipboard: { matchVisual: false },
      "emoji-toolbar": true,
      "emoji-textarea": false,
      "emoji-shortname": true
    }
  });

  window.__hmQuill = quill;
  console.log("Quill:", quill);

  quill.on("selection-change", (range) => {
    if (range) savedRange = range;
  });

  const sizePicker = document.querySelector(".ql-size");
  sizePicker?.addEventListener("mousedown", (e) => e.preventDefault());

  const sizeSelect = document.querySelector("#FontSizeSelect");
  sizeSelect?.addEventListener("mousedown", (e) => e.preventDefault());

  $(".ql-picker-item").on("click", function (event) {
    event.preventDefault();
  });

  const toolbar = quill.getModule("toolbar");
  if (toolbar) {
    toolbar.addHandler("iframe", function () {
      const url = prompt("iframe URL eingeben");
      if (!url) return;
      insertIframe(url);
    });
  }

  function insertIframe(url, opts = { width: "100%", height: "400" }) {
    if (!isAllowedIframeUrl(url)) {
      alert("Iframe domain not allowed.");
      return;
    }
    const index = getInsertIndex(quill);
    quill.insertEmbed(index, "iframe", { src: url, width: opts.width, height: opts.height }, "user");
    quill.setSelection(index + 1, 0, "silent");
  }

  quill.clipboard.addMatcher(Node.TEXT_NODE, function (node, delta) {
    const regex = /((http|https|ftp|ftps)\:\/\/(\S*)?)/g;
    if (typeof node.data !== "string") return delta;

    const matches = node.data.match(regex);
    if (matches && matches.length > 0) {
      const ops = [];
      let str = node.data;

      matches.forEach(function (match) {
        const split = str.split(match);
        const beforeLink = split.shift();
        ops.push({ insert: beforeLink });
        ops.push({ insert: match, attributes: { link: match } });
        str = split.join(match);
      });

      ops.push({ insert: str });
      delta.ops = ops;
    }
    return delta;
  });


  quill.clipboard.addMatcher("img", (node, delta) => {
    const src = node.getAttribute("src") || "";

    if (src.startsWith("data:image/") || src.startsWith("file:")) {
      return new Delta();
    }

    if (src.startsWith("http://") || src.startsWith("https://") ||  src.startsWith("index.php")) {
      return new Delta().insert({ image: src });
    }

    return new Delta();
  });


  quill.root.addEventListener(
    "paste",
    function (e) {
      const dt = e.clipboardData;
      if (!dt) return;

      if (dt.items) {
        for (const item of Array.from(dt.items)) {
          if (item.type && item.type.startsWith("image/")) {
            const f = item.getAsFile();
            if (f) {
              window.outlookImg = f;
            }
          }
        }
      }
    },
    true
  );

  document.addEventListener(
    "paste",
    function (e) {
      if (!eventIsFromThisEditor(quill, e)) return;

      const dt = e.clipboardData;
      if (!dt) return;

      const hasImage =
        (dt.files && Array.from(dt.files).some((f) => f && f.type && f.type.startsWith("image/"))) ||
        (dt.items && Array.from(dt.items).some((it) => it && it.type && it.type.startsWith("image/")));

      if (!hasImage) return;

      e.preventDefault();
      e.stopPropagation();

      (async () => {
        const imageFiles = await extractImageFilesFromPasteEvent(e);
        const kb = isKnowledgebaseMode();

        if (imageFiles.length) {
          for (const file of imageFiles) {
            window.outlookImg = file;
            await uploadImageFileAndInsert(quill, file, kb);
          }
          return;
        }

        if (window.outlookImg) {
          await uploadImageFileAndInsert(quill, window.outlookImg, kb);
        }
      })().catch(console.error);
    },
    true
  );

  quill.on("text-change", function () {
    $("#LongDescr").val(quill.root.innerHTML);
    if (typeof newTicket !== "undefined" && typeof saveAsDraft !== "undefined") {
      if (newTicket === 1 && saveAsDraft === 1) {
        submitTemp("LongDescr");
      }
    }
  });

  quill.on("text-change", function (delta, oldDelta, source) {
    const regex = /https?:\/\/[^\s]+$/;

    if (
      delta.ops.length === 2 &&
      delta.ops[0].retain &&
      isWhitespace(delta.ops[1].insert)
    ) {
      const endRetain = delta.ops[0].retain;
      const text = quill.getText().substr(0, endRetain);
      const match = text.match(regex);

      if (match !== null) {
        const url = match[0];

        let ops = [];
        if (endRetain > url.length) ops.push({ retain: endRetain - url.length });

        ops = ops.concat([
          { delete: url.length },
          { insert: url, attributes: { link: url } }
        ]);

        quill.updateContents({ ops });
      }
    }
  });

  let applyingDefaultFont = false;

  if(editorStandardFont){
      quill.on("text-change", function (delta, oldDelta, source) {
        if (applyingDefaultFont || source !== "user") return;

        let index = 0;
        const fixes = [];

        delta.ops.forEach(op => {
          if (op.retain) {
            index += op.retain;
            return;
          }

          if (typeof op.insert === "string") {
            const len = op.insert.length;

            if (!op.attributes || !op.attributes.font) {
              fixes.push({ index, len });
            }

            index += len;
            return;
          }

          if (op.insert) {
            index += 1;
          }
        });
        console.log(fixes);

        if (!fixes.length) return;

        applyingDefaultFont = true;
        fixes.forEach(f => {
          quill.formatText(f.index, f.len, "font", editorStandardFont, "api");
        });

        applyingDefaultFont = false;

        const longDescr = document.getElementById("LongDescr");
        if (longDescr) {
          longDescr.value = quill.root.innerHTML;
        }
      });
    }

  if (quill.keyboard?.bindings?.[9]) {
    quill.keyboard.bindings[9].unshift({
      key: 9,
      handler: function () {
        $("#IndentMinus1").click();
        return false;
      }
    });
  }

  function checkTabPress(e) {
    e = e || event;
    if (e.keyCode == 9 && $("#ShortDescr").is(":focus")) {
      quill.focus();
      e.preventDefault();
    }
  }
  $(window).keydown(function (e) {
    checkTabPress(e);
  });



  window.insertSnippet = function insertSnippet(id) {
    $.get("index.php?module=ticket&class=snippets&event=getSnippetContent&id=" + id, function (data) {
      const index = getInsertIndex(quill);
      quill.clipboard.dangerouslyPasteHTML(index, data);
      $("#myBigIFrameModal").modal("hide");
      try {
        if ($(".fancybox-close")[0]) $(".fancybox-close")[0].click();
      } catch (_) {}
    });
  };

  window.insertTab = function insertTab() {
    const index = getInsertIndex(quill);
    quill.insertText(index, "    ");
  };

  window.editHTML = function editHTML() {
    const color = $("#editHTMLBtn").css("color");

    if (color === "rgb(0, 0, 255)") {
      $("#editor").show();
      const editor = document.getElementsByClassName("ql-editor");
      if (editor && editor[0]) editor[0].innerHTML = $("#LongDescr").val();
      $("#LongDescr").css({ visibility: "hidden", height: "0px" });
      $("#editHTMLBtn").css({ color: "#333333" });
    } else {
      $("#editor").hide();
      $("#LongDescr").css({ visibility: "visible", height: "200px" });
      $("#editHTMLBtn").css({ color: "#0000ff" });
    }
  };

  window.imageHandler = function imageHandler(imageDataUrl, type, imageData) {
    const filename = "my_cool_image.png";
    const blob = imageData.toBlob();
    const file = imageData.toFile(filename);

    const formData = new FormData();
    formData.append("filename", filename);
    formData.append("fileBlob", blob);
    formData.append("file", file);

    let kb = 0;
    if (typeof moduleVar !== "undefined" && moduleVar === "knowledgebase") kb = 1;

    $.ajax({
      url: "index.php?module=upload&event=uploadImageDirectly&kb=" + kb,
      type: "POST",
      data: formData,
      success: function (data) {
        if (data && data !== "Nofile") {
          const index = getInsertIndex(quill);
          quill.insertEmbed(index, "image", "index.php?module=upload&event=ShowImage&name=" + data, "user");
          try {
            quill.formatText(index, 1, "max-width", "100%");
          } catch (_) {}
        }
      },
      cache: false,
      contentType: false,
      processData: false
    });
  };

  window.selectLocalImage = function selectLocalImage() {
    const input = document.createElement("input");
    input.setAttribute("type", "file");
    input.click();

    input.onchange = () => {
      const file = input.files[0];
      if (/^image\//.test(file.type)) {
        if (typeof saveToServer === "function") {
          saveToServer(file);
        } else {
          const kb = isKnowledgebaseMode();
          uploadImageFileAndInsert(quill, file, kb);
        }
      } else {
        console.warn("You could only upload images.");
      }
    };
  };

function loadHtmlIntoQuill(html) {
  const delta = quill.clipboard.convert({ html });
  quill.setContents(delta, 'silent');
}

  $(document).ready(function(){
    if (document.getElementById("LongDescr")) {
      loadHtmlIntoQuill($("#LongDescr").val());
     
    }


  });



})();
