(function () {
  var form = document.querySelector("[data-editor-form]");
  var textarea = document.querySelector("[data-document-editor]");
  var statusNodes = document.querySelectorAll("[data-sync-status], [data-sync-status-secondary]");
  var hashEl = document.querySelector("[data-editor-hash]");
  var documentShell = document.querySelector("[data-document-path][data-document-hash]");
  var conflictNotice = document.querySelector("[data-conflict-notice]");
  var conflictHash = document.querySelector("[data-conflict-hash]");
  var conflictStatus = document.querySelector("[data-conflict-status]");
  var conflictDiff = document.querySelector("[data-conflict-diff]");
  var conflictApply = document.querySelector("[data-conflict-apply]");
  var conflictDismiss = document.querySelector("[data-conflict-dismiss]");
  var conflictResolution = document.querySelector("[data-conflict-resolution]");
  var conflictResolutionMount = document.querySelector("[data-conflict-monaco-mount]");
  var conflictUseServer = document.querySelector("[data-conflict-use='server']");
  var conflictUseLocal = document.querySelector("[data-conflict-use='local']");
  var conflictUseBoth = document.querySelector("[data-conflict-use='both']");
  var monacoContainer = document.querySelector("[data-monaco-mount]");
  var monacoLoaded = false;
  var monacoReadyPromise = null;
  var monacoDarkTheme = "cairnquire-dark";
  var monacoLightTheme = "cairnquire-light";

  if (!form || !textarea || statusNodes.length === 0) {
    return;
  }

  var path = form.getAttribute("data-document-path");
  var baseHash = documentShell ? documentShell.getAttribute("data-document-hash") : "";
  var saveTimer = null;
  var lastSavedValue = textarea.value;
  var editor = null;
  var currentConflict = null;
  var currentConflictLocalContent = "";
  var resolvedConflictContent = "";
  var conflictDiffView = null;
  var resolutionEditor = null;
  var suppressResolutionEvents = false;

  function setStatus(nextStatus) {
    statusNodes.forEach(function (node) {
      node.textContent = nextStatus;
      node.dataset.state = nextStatus.toLowerCase();
    });
  }

  function getEditorValue() {
    return editor ? editor.getValue() : textarea.value;
  }

  function setEditorValue(value) {
    textarea.value = value;
    if (editor && editor.getValue() !== value) {
      editor.setValue(value);
    }
  }

  function getResolutionValue() {
    return resolutionEditor ? resolutionEditor.getValue() : resolvedConflictContent;
  }

  function setResolutionEditorValue(value) {
    resolvedConflictContent = value;
    if (conflictResolution) {
      conflictResolution.value = value;
    }
    if (resolutionEditor && resolutionEditor.getValue() !== value) {
      suppressResolutionEvents = true;
      resolutionEditor.setValue(value);
      suppressResolutionEvents = false;
    }
  }

  function ensureTrailingNewline(value) {
    return value.endsWith("\n") ? value : value + "\n";
  }

  function buildCombinedResolution(serverContent, localContent) {
    return ensureTrailingNewline(serverContent) + "\n" + ensureTrailingNewline(localContent);
  }

  function setConflictMessage(message) {
    if (conflictStatus) {
      conflictStatus.textContent = message;
    }
  }

  function setResolutionContent(content, message) {
    setResolutionEditorValue(content);
    if (conflictApply) {
      conflictApply.disabled = false;
    }
    if (message) {
      setConflictMessage(message);
    }
  }

  async function loadDiffs() {
    var modules = await Promise.all([
      import("https://cdn.jsdelivr.net/npm/@pierre/diffs@1.1.22/+esm"),
      import("https://cdn.jsdelivr.net/npm/@pierre/diffs@1.1.22/dist/style.js"),
    ]);
    return {
      renderer: modules[0],
      stylesheet: modules[1].default || "",
    };
  }

  function styleDiffContainer(diffContainer) {
    diffContainer.style.setProperty("--diffs-light-bg", "#fcfaf5");
    diffContainer.style.setProperty("--diffs-light", "#1c2430");
    diffContainer.style.setProperty("--diffs-dark-bg", "#1e1e1e");
    diffContainer.style.setProperty("--diffs-dark", "#e8ecf0");
    diffContainer.style.setProperty("--diffs-addition-color", "#3f8f59");
    diffContainer.style.setProperty("--diffs-deletion-color", "#c8553d");
    diffContainer.style.setProperty("--diffs-modified-color", "#c67a2a");
    diffContainer.style.setProperty("--diffs-font-family", "'Iosevka', 'JetBrains Mono', ui-monospace, SFMono-Regular, monospace");
    diffContainer.style.setProperty("--diffs-header-font-family", "'Inter', system-ui, -apple-system, BlinkMacSystemFont, sans-serif");
  }

  function injectDiffStyles(diffContainer, stylesheet) {
    var root = diffContainer.shadowRoot;
    if (!root || !stylesheet || root.querySelector("[data-cairnquire-diffs-style]")) {
      return;
    }

    var style = document.createElement("style");
    style.setAttribute("data-cairnquire-diffs-style", "");
    style.textContent = stylesheet;
    root.prepend(style);
  }

  function renderConflictResolver(conflict, localContent) {
    if (!conflictDiff) {
      return;
    }

    if (conflictDiffView) {
      conflictDiffView.cleanUp();
      conflictDiffView = null;
    }
    conflictDiff.replaceChildren();
    currentConflictLocalContent = localContent;
    setResolutionEditorValue(localContent);
    if (conflictApply) {
      conflictApply.disabled = false;
    }
    ensureResolutionEditor();
    setConflictMessage("Loading conflict resolver...");

    loadDiffs().then(function (diffsModule) {
      var diffs = diffsModule.renderer;
      var diffContainer = document.createElement("div");
      styleDiffContainer(diffContainer);
      conflictDiff.appendChild(diffContainer);
      var serverFile = {
        name: path,
        contents: conflict.currentContent || "",
        lang: "markdown",
        cacheKey: "server:" + (conflict.currentHash || ""),
      };
      var localFile = {
        name: path,
        contents: localContent,
        lang: "markdown",
        cacheKey: "local:" + (conflict.baseHash || "") + ":" + localContent.length,
      };

      conflictDiffView = new diffs.FileDiff({
        disableFileHeader: false,
        diffStyle: "unified",
        diffIndicators: "classic",
        lineDiffType: "word",
        overflow: "scroll",
        parseDiffOptions: { context: 4 },
      });
      conflictDiffView.render({
        oldFile: serverFile,
        newFile: localFile,
        fileContainer: diffContainer,
      });
      injectDiffStyles(diffContainer, diffsModule.stylesheet);
      setConflictMessage("Red deletions are from the server copy. Green additions are from your queued edit.");
    }).catch(function () {
      setConflictMessage("Could not load the diff renderer. Your edit is still queued locally.");
    });
  }

  function showConflict(conflict, localContent) {
    currentConflict = conflict;
    setStatus("Conflict");
    form.hidden = true;
    if (conflictHash && conflict && conflict.currentHash) {
      conflictHash.textContent = conflict.currentHash;
    }
    if (conflictNotice) {
      conflictNotice.hidden = false;
    }
    renderConflictResolver(conflict, localContent || getEditorValue());
  }

  function hideConflict() {
    form.hidden = false;
    if (conflictNotice) {
      conflictNotice.hidden = true;
    }
    if (conflictDiff) {
      conflictDiff.replaceChildren();
    }
    if (conflictDiffView) {
      conflictDiffView.cleanUp();
      conflictDiffView = null;
    }
    if (conflictApply) {
      conflictApply.disabled = true;
    }
    setResolutionEditorValue("");
    currentConflict = null;
    currentConflictLocalContent = "";
  }

  async function saveNow() {
    var value = getEditorValue();
    if (value === lastSavedValue) {
      setStatus("Saved");
      return;
    }

    hideConflict();
    setStatus("Saving");

    if (!window.MDHubSync) {
      setStatus("Queued");
      return;
    }

    var result = await window.MDHubSync.saveDocument(path, value, baseHash);
    if (result.status === "saved") {
      lastSavedValue = value;
      if (hashEl && result.result && result.result.hash) {
        hashEl.textContent = result.result.hash;
        baseHash = result.result.hash;
        if (documentShell) {
          documentShell.setAttribute("data-document-hash", result.result.hash);
        }
      }
      setStatus("Saved");
      return;
    }

    if (result.status === "conflict") {
      showConflict(result.conflict, value);
      return;
    }

    setStatus("Queued");
  }

  async function applyResolvedConflict() {
    if (!window.MDHubSync || !currentConflict) {
      return;
    }

    var resolutionContent = getResolutionValue();
    resolvedConflictContent = resolutionContent;
    setConflictMessage("Saving resolved document...");
    if (conflictApply) {
      conflictApply.disabled = true;
    }

    var result = await window.MDHubSync.saveDocument(path, resolutionContent, currentConflict.currentHash);
    if (result.status === "saved") {
      setEditorValue(resolutionContent);
      lastSavedValue = resolutionContent;
      if (hashEl && result.result && result.result.hash) {
        hashEl.textContent = result.result.hash;
        baseHash = result.result.hash;
        if (documentShell) {
          documentShell.setAttribute("data-document-hash", result.result.hash);
        }
      }
      hideConflict();
      setStatus("Saved");
      return;
    }

    if (result.status === "conflict") {
      showConflict(result.conflict, resolutionContent);
      return;
    }

    setStatus("Queued");
    setConflictMessage("Resolved document is queued and will retry when the server is reachable.");
  }

  function restorePendingConflict() {
    if (!window.MDHubCache || !window.MDHubCache.getPendingEdit) {
      return;
    }
    var normalizedPath = window.MDHubCache.normalizePath("/docs/" + path.replace(/^\/+/, ""));
    window.MDHubCache.getPendingEdit(normalizedPath).then(function (pending) {
      if (pending && pending.conflict) {
        showConflict(pending.conflict, pending.content || getEditorValue());
      }
    }).catch(function () {});
  }

  function scheduleSave() {
    setStatus("Unsaved");
    if (saveTimer) {
      clearTimeout(saveTimer);
    }
    saveTimer = setTimeout(function () {
      saveNow().catch(function () {
        setStatus("Queued");
      });
    }, 2000);
  }

  function loadMonaco() {
    if (monacoReadyPromise) {
      return monacoReadyPromise;
    }
    if (monacoLoaded && window.monaco) {
      monacoReadyPromise = Promise.resolve();
      return monacoReadyPromise;
    }
    monacoLoaded = true;

    var isDark = window.matchMedia("(prefers-color-scheme: dark)").matches;

    monacoReadyPromise = new Promise(function (resolve) {
      var script = document.createElement("script");
      script.src = "https://cdn.jsdelivr.net/npm/monaco-editor@0.52.2/min/vs/loader.js";
      script.onload = function () {
        require.config({
          paths: { vs: "https://cdn.jsdelivr.net/npm/monaco-editor@0.52.2/min/vs" },
        });
        require(["vs/editor/editor.main"], function () {
          monaco.editor.defineTheme(monacoDarkTheme, {
            base: "vs-dark",
            inherit: true,
            rules: [
              { token: "comment", foreground: "8B9DAF", fontStyle: "italic" },
              { token: "keyword", foreground: "E8943A" },
              { token: "string", foreground: "C9A96E" },
              { token: "number", foreground: "C9A96E" },
              { token: "type", foreground: "E8943A" },
              { token: "tag", foreground: "E8943A" },
              { token: "attribute.name", foreground: "D4A05A" },
              { token: "attribute.value", foreground: "C9A96E" },
              { token: "delimiter", foreground: "B0B8C4" },
              { token: "variable", foreground: "D4D8DE" },
            ],
            colors: {
              "editor.background": "#1E1E1E",
              "editor.foreground": "#E8ECF0",
              "editor.lineHighlightBackground": "#282828",
              "editor.selectionBackground": "#3A3A3A",
              "editorLineNumber.foreground": "#555555",
              "editorLineNumber.activeForeground": "#E8943A",
              "editor.inactiveSelectionBackground": "#333333",
              "editorCursor.foreground": "#E8943A",
              "editorIndentGuide.background": "#2A2A2A",
              "editorIndentGuide.activeBackground": "#3A3A3A",
              "editorWhitespace.foreground": "#2A2A2A",
              "editorGutter.background": "#1E1E1E",
              "editorOverviewRuler.border": "#1E1E1E",
              "scrollbarSlider.background": "#3A3A3A88",
              "scrollbarSlider.hoverBackground": "#4A4A4A88",
              "scrollbarSlider.activeBackground": "#5A5A5A88",
              "minimap.background": "#1E1E1E",
            },
          });

          monaco.editor.defineTheme(monacoLightTheme, {
            base: "vs",
            inherit: true,
            rules: [
              { token: "comment", foreground: "6A7B8C", fontStyle: "italic" },
              { token: "keyword", foreground: "C67A2A" },
              { token: "string", foreground: "8A6D3B" },
              { token: "number", foreground: "8A6D3B" },
              { token: "type", foreground: "C67A2A" },
              { token: "tag", foreground: "C67A2A" },
              { token: "attribute.name", foreground: "A87D3A" },
              { token: "attribute.value", foreground: "8A6D3B" },
            ],
            colors: {
              "editor.background": "#FCFAF5",
              "editor.foreground": "#1C2430",
              "editor.lineHighlightBackground": "#F0EDE5",
              "editor.selectionBackground": "#E8943A33",
              "editorLineNumber.foreground": "#AAAAAA",
              "editorLineNumber.activeForeground": "#C67A2A",
              "editorCursor.foreground": "#C67A2A",
              "editorIndentGuide.background": "#E8E5DD",
              "editorGutter.background": "#FCFAF5",
            },
          });

          if (monacoContainer) {
            editor = monaco.editor.create(monacoContainer, {
              value: textarea.value,
              language: "markdown",
              theme: isDark ? monacoDarkTheme : monacoLightTheme,
              fontFamily: "'Iosevka', 'JetBrains Mono', ui-monospace, SFMono-Regular, monospace",
              fontSize: 14,
              lineHeight: 22,
              minimap: { enabled: false },
              wordWrap: "on",
              scrollBeyondLastLine: false,
              padding: { top: 12 },
              renderLineHighlight: "line",
              smoothScrolling: true,
              cursorBlinking: "smooth",
              cursorSmoothCaretAnimation: "on",
              bracketPairColorization: { enabled: true },
              automaticLayout: true,
            });

            textarea.hidden = true;
            monacoContainer.classList.add("monaco-mounted");

            editor.onDidChangeModelContent(function () {
              textarea.value = editor.getValue();
              scheduleSave();
            });

            if (window.MDHubSync) {
              editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS, function () {
                saveNow().catch(function () {
                  setStatus("Queued");
                });
              });
            }

            var darkMQ = window.matchMedia("(prefers-color-scheme: dark)");
            darkMQ.addEventListener("change", function (e) {
              monaco.editor.setTheme(e.matches ? monacoDarkTheme : monacoLightTheme);
            });

            editor.focus();
          }

          resolve();
        });
      };
      document.head.appendChild(script);
    });
    return monacoReadyPromise;
  }

  function ensureResolutionEditor() {
    if (!conflictResolution || !conflictResolutionMount) {
      return;
    }

    loadMonaco().then(function () {
      if (!window.monaco || resolutionEditor) {
        return;
      }

      var isDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
      resolutionEditor = monaco.editor.create(conflictResolutionMount, {
        value: conflictResolution.value || resolvedConflictContent,
        language: "markdown",
        theme: isDark ? monacoDarkTheme : monacoLightTheme,
        fontFamily: "'Iosevka', 'JetBrains Mono', ui-monospace, SFMono-Regular, monospace",
        fontSize: 14,
        lineHeight: 22,
        minimap: { enabled: false },
        wordWrap: "on",
        scrollBeyondLastLine: false,
        padding: { top: 12 },
        renderLineHighlight: "line",
        smoothScrolling: true,
        cursorBlinking: "smooth",
        cursorSmoothCaretAnimation: "on",
        bracketPairColorization: { enabled: true },
        automaticLayout: true,
      });

      conflictResolution.hidden = true;
      conflictResolutionMount.classList.add("monaco-mounted");

      resolutionEditor.onDidChangeModelContent(function () {
        if (suppressResolutionEvents) {
          return;
        }
        resolvedConflictContent = resolutionEditor.getValue();
        conflictResolution.value = resolvedConflictContent;
        if (conflictApply) {
          conflictApply.disabled = false;
        }
        setConflictMessage("Manual resolution updated. Apply it to save the resolved document.");
      });

      resolutionEditor.focus();
    }).catch(function () {
      conflictResolution.hidden = false;
    });
  }

  if (monacoContainer) {
    loadMonaco().catch(function () {
      textarea.addEventListener("input", scheduleSave);
    });
  } else {
    textarea.addEventListener("input", scheduleSave);
  }

  form.addEventListener("submit", function (event) {
    event.preventDefault();
    saveNow().catch(function () {
      setStatus("Queued");
    });
  });

  if (conflictApply) {
    conflictApply.addEventListener("click", function () {
      applyResolvedConflict().catch(function () {
        setStatus("Queued");
        setConflictMessage("Could not save the resolved document. It remains queued locally.");
      });
    });
  }

  if (conflictDismiss) {
    conflictDismiss.addEventListener("click", function () {
      hideConflict();
    });
  }

  if (conflictResolution) {
    conflictResolution.addEventListener("input", function () {
      resolvedConflictContent = conflictResolution.value;
      if (conflictApply) {
        conflictApply.disabled = false;
      }
      setConflictMessage("Manual resolution updated. Apply it to save the resolved document.");
    });
  }

  if (conflictUseServer) {
    conflictUseServer.addEventListener("click", function () {
      if (!currentConflict) {
        return;
      }
      setResolutionContent(currentConflict.currentContent || "", "Using the server copy as the resolution. You can edit it before applying.");
    });
  }

  if (conflictUseLocal) {
    conflictUseLocal.addEventListener("click", function () {
      setResolutionContent(currentConflictLocalContent, "Using your queued edit as the resolution. You can edit it before applying.");
    });
  }

  if (conflictUseBoth) {
    conflictUseBoth.addEventListener("click", function () {
      if (!currentConflict) {
        return;
      }
      setResolutionContent(
        buildCombinedResolution(currentConflict.currentContent || "", currentConflictLocalContent),
        "Using both versions as the resolution. Edit the combined content before applying."
      );
    });
  }

  restorePendingConflict();

  document.addEventListener("keydown", function (e) {
    if ((e.metaKey || e.ctrlKey) && e.key === "s") {
      e.preventDefault();
    }
  });
})();
