export const MINDSPACE_PAGE_CONTENT_MESSAGE = 'mindspace:page-content';

const EDITOR_STYLE = `<style id="mindspace-visual-editor-style">
  [data-mindspace-editing="true"] [data-mindspace-edit-kind] {
    position: relative;
  }
  [data-mindspace-editing="true"][data-mindspace-highlights="off"] [data-mindspace-edit-kind] {
    outline: none !important;
    box-shadow: none !important;
  }
  [data-mindspace-editing="true"][data-mindspace-highlights="off"] [data-mindspace-edit-kind]::after,
  [data-mindspace-editing="true"][data-mindspace-highlights="off"] [data-mindspace-edit-kind]::before {
    display: none !important;
  }
  [data-mindspace-editing="true"] [data-mindspace-edit-kind="text"] {
    outline: 1px dashed rgba(61, 139, 253, 0.72);
    outline-offset: 2px;
    box-shadow: inset 0 0 0 1px rgba(61, 139, 253, 0.12);
    cursor: text;
  }
  [data-mindspace-editing="true"] [data-mindspace-edit-kind="text"]:focus {
    outline: 2px solid rgba(61, 139, 253, 0.95);
    background: rgba(61, 139, 253, 0.08);
  }
  [data-mindspace-editing="true"] [data-mindspace-edit-kind="media"] {
    outline: 2px dashed rgba(238, 176, 78, 0.82);
    outline-offset: 3px;
    cursor: pointer;
    box-shadow: 0 0 0 1px rgba(238, 176, 78, 0.18);
  }
  [data-mindspace-editing="true"] [data-mindspace-edit-kind="media"]:hover {
    outline-color: rgba(238, 176, 78, 1);
    box-shadow: 0 0 0 4px rgba(238, 176, 78, 0.16);
  }
  [data-mindspace-editing="true"] [data-mindspace-edit-kind="link"] {
    outline: 1px dotted rgba(124, 92, 255, 0.72);
    outline-offset: 2px;
    text-decoration: underline dotted rgba(124, 92, 255, 0.55);
    cursor: text;
  }
  [data-mindspace-editing="true"] [data-mindspace-edit-kind="link"]:hover {
    outline-color: rgba(124, 92, 255, 0.95);
    background: rgba(124, 92, 255, 0.08);
  }
  [data-mindspace-editing="true"] [data-mindspace-edit-kind="background"] {
    outline: 1px dashed rgba(47, 111, 87, 0.55);
    outline-offset: -2px;
    cursor: copy;
    box-shadow: inset 0 0 0 9999px rgba(47, 111, 87, 0.04);
  }
  [data-mindspace-editing="true"] [data-mindspace-edit-kind="background"]:hover {
    outline-color: rgba(47, 111, 87, 0.95);
    box-shadow: inset 0 0 0 9999px rgba(47, 111, 87, 0.1);
  }
  [data-mindspace-editing="true"] [data-mindspace-edit-kind]::after {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 2147483640;
    max-width: calc(100% - 8px);
    padding: 2px 7px;
    border-radius: 0 0 8px 0;
    color: #fffaf0;
    font: 10px/1.35 -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    letter-spacing: 0.02em;
    white-space: nowrap;
    pointer-events: none;
    opacity: 0.92;
    content: attr(data-mindspace-edit-label);
  }
  [data-mindspace-editing="true"] [data-mindspace-edit-kind="text"]::after {
    background: rgba(61, 139, 253, 0.92);
  }
  [data-mindspace-editing="true"] [data-mindspace-edit-kind="media"]::after {
    background: rgba(201, 132, 24, 0.94);
  }
  [data-mindspace-editing="true"] [data-mindspace-edit-kind="link"]::after {
    background: rgba(124, 92, 255, 0.92);
  }
  [data-mindspace-editing="true"] [data-mindspace-edit-kind="background"]::after {
    background: rgba(47, 111, 87, 0.92);
  }
  [data-mindspace-editing="true"] [data-mindspace-edit-kind="background"][data-mindspace-bg-large="true"]::before {
    content: '';
    position: absolute;
    inset: 10px;
    border: 1px dashed rgba(47, 111, 87, 0.35);
    border-radius: 8px;
    pointer-events: none;
  }
  .mindspace-editor-popover {
    position: fixed;
    z-index: 2147483646;
    width: min(300px, calc(100vw - 24px));
    padding: 12px;
    border: 1px solid rgba(24, 33, 29, 0.14);
    border-radius: 12px;
    background: rgba(255, 252, 244, 0.98);
    color: #18211d;
    box-shadow: 0 18px 48px rgba(24, 33, 29, 0.18);
    font: 12px/1.45 -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  }
  .mindspace-editor-popover p {
    margin: 0 0 8px;
    font-size: 13px;
    font-weight: 700;
  }
  .mindspace-editor-popover-hint {
    margin: 0 0 10px;
    color: #6d7771;
    font-size: 11px;
  }
  .mindspace-editor-popover label {
    display: grid;
    gap: 4px;
    margin-bottom: 8px;
  }
  .mindspace-editor-popover label[data-inline="true"] {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 10px;
  }
  .mindspace-editor-popover input[type='url'],
  .mindspace-editor-popover input[type='text'],
  .mindspace-editor-popover input[type='color'],
  .mindspace-editor-popover input[type='file'] {
    width: 100%;
    padding: 7px 8px;
    border: 1px solid rgba(24, 33, 29, 0.14);
    border-radius: 8px;
    background: #fff;
    color: inherit;
    font: inherit;
  }
  .mindspace-editor-popover-actions {
    display: flex;
    justify-content: flex-end;
    flex-wrap: wrap;
    gap: 8px;
  }
  .mindspace-editor-popover-actions button {
    border: 0;
    border-radius: 999px;
    padding: 6px 12px;
    cursor: pointer;
    font: inherit;
  }
  .mindspace-editor-popover-actions button[data-action='apply'] {
    color: #fffaf0;
    background: #18211d;
  }
  .mindspace-editor-popover-actions button[data-action='cancel'],
  .mindspace-editor-popover-actions button[data-action='clear'] {
    color: #52605a;
    background: rgba(24, 33, 29, 0.08);
  }
  .mindspace-editor-guide {
    position: fixed;
    z-index: 2147483645;
    left: 50%;
    bottom: 14px;
    transform: translateX(-50%);
    max-width: min(720px, calc(100vw - 24px));
    padding: 8px 14px;
    border-radius: 999px;
    color: #52605a;
    font: 11px/1.4 -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    background: rgba(255, 252, 244, 0.94);
    box-shadow: 0 8px 28px rgba(24, 33, 29, 0.12);
    pointer-events: none;
  }
  .mindspace-editor-legend {
    position: fixed;
    z-index: 2147483645;
    top: 12px;
    left: 12px;
    display: grid;
    gap: 8px;
    width: min(280px, calc(100vw - 24px));
    padding: 10px 12px;
    border: 1px solid rgba(24, 33, 29, 0.12);
    border-radius: 12px;
    background: rgba(255, 252, 244, 0.96);
    color: #18211d;
    box-shadow: 0 10px 28px rgba(24, 33, 29, 0.12);
    font: 11px/1.45 -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  }
  .mindspace-editor-legend strong {
    font-size: 12px;
  }
  .mindspace-editor-legend-items {
    display: grid;
    gap: 6px;
  }
  .mindspace-editor-legend-item {
    display: flex;
    align-items: center;
    gap: 8px;
  }
  .mindspace-editor-legend-swatch {
    width: 12px;
    height: 12px;
    border-radius: 3px;
    flex-shrink: 0;
  }
  .mindspace-editor-legend-swatch[data-kind="text"] { background: rgba(61, 139, 253, 0.92); }
  .mindspace-editor-legend-swatch[data-kind="media"] { background: rgba(201, 132, 24, 0.94); }
  .mindspace-editor-legend-swatch[data-kind="link"] { background: rgba(124, 92, 255, 0.92); }
  .mindspace-editor-legend-swatch[data-kind="background"] { background: rgba(47, 111, 87, 0.92); }
  .mindspace-editor-legend-toggle {
    justify-self: start;
    border: 0;
    border-radius: 999px;
    padding: 5px 10px;
    color: #52605a;
    font: inherit;
    background: rgba(24, 33, 29, 0.08);
    cursor: pointer;
  }
</style>`;

const EDITOR_SCRIPT = `<script id="mindspace-visual-editor-script">
(function () {
  var MESSAGE = ${JSON.stringify(MINDSPACE_PAGE_CONTENT_MESSAGE)};
  var TEXT_SELECTOR = 'h1,h2,h3,h4,h5,h6,p,li,td,th,figcaption,blockquote,span,a,label,small,strong,em,b,i,u,sub,sup,cite,time,address,dt,dd,button,.sub,.tagline,[class*="title"],[class*="subtitle"],[class*="desc"],[class*="text"]';
  var BLOCK_CHILD_SELECTOR = 'div,section,article,header,footer,main,p,h1,h2,h3,h4,h5,h6,ul,ol,table,form,video,audio,iframe,svg,canvas';
  var MEDIA_BLOCK_SELECTOR = 'img,video,iframe,svg,canvas,table,ul,ol,form';
  var popover = null;
  var emitTimer = null;

  function debounceEmit() {
    if (emitTimer) window.clearTimeout(emitTimer);
    emitTimer = window.setTimeout(emitChange, 350);
  }

  function escapeAttr(value) {
    return String(value || '').replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/</g, '&lt;');
  }

  function stripEditorArtifacts(root) {
    root.querySelectorAll('#mindspace-visual-editor-style,#mindspace-visual-editor-script,.mindspace-editor-popover,.mindspace-editor-guide,.mindspace-editor-legend').forEach(function (node) {
      node.remove();
    });
    root.querySelectorAll('[contenteditable]').forEach(function (node) {
      node.removeAttribute('contenteditable');
      node.removeAttribute('spellcheck');
    });
    root.querySelectorAll('[data-mindspace-bg-target],[data-mindspace-link-target],[data-mindspace-media-target],[data-mindspace-edit-kind],[data-mindspace-edit-label],[data-mindspace-bg-large]').forEach(function (node) {
      node.removeAttribute('data-mindspace-bg-target');
      node.removeAttribute('data-mindspace-link-target');
      node.removeAttribute('data-mindspace-media-target');
      node.removeAttribute('data-mindspace-edit-kind');
      node.removeAttribute('data-mindspace-edit-label');
      node.removeAttribute('data-mindspace-bg-large');
    });
    if (root.body) {
      root.body.removeAttribute('data-mindspace-editing');
      root.body.removeAttribute('data-mindspace-highlights');
    }
  }

  function markEditable(el, kind, label) {
    el.setAttribute('data-mindspace-edit-kind', kind);
    el.setAttribute('data-mindspace-edit-label', label);
  }

  function serializeDocument() {
    var clone = document.documentElement.cloneNode(true);
    stripEditorArtifacts(clone);
    var doctype = document.doctype;
    var prefix = doctype
      ? '<!DOCTYPE ' + doctype.name + (doctype.publicId ? ' PUBLIC "' + doctype.publicId + '"' : '') + (doctype.systemId ? ' "' + doctype.systemId + '"' : '') + '>'
      : '<!DOCTYPE html>';
    return prefix + '\\n' + clone.outerHTML;
  }

  function emitChange() {
    parent.postMessage({ type: MESSAGE, html: serializeDocument() }, '*');
  }

  function closePopover() {
    if (popover && popover.parentNode) popover.parentNode.removeChild(popover);
    popover = null;
  }

  function openPopover(title, fieldsHtml, onApply, anchor, hint) {
    closePopover();
    popover = document.createElement('div');
    popover.className = 'mindspace-editor-popover';
    popover.innerHTML =
      '<p>' + title + '</p>' +
      (hint ? '<p class="mindspace-editor-popover-hint">' + hint + '</p>' : '') +
      fieldsHtml +
      '<div class="mindspace-editor-popover-actions">' +
      '<button type="button" data-action="cancel">取消</button>' +
      '<button type="button" data-action="apply">应用</button>' +
      '</div>';
    document.body.appendChild(popover);
    var rect = anchor.getBoundingClientRect();
    var top = Math.min(rect.bottom + 8, window.innerHeight - popover.offsetHeight - 8);
    var left = Math.min(rect.left, window.innerWidth - popover.offsetWidth - 8);
    popover.style.top = Math.max(8, top) + 'px';
    popover.style.left = Math.max(8, left) + 'px';
    popover.querySelector('[data-action="cancel"]').addEventListener('click', closePopover);
    popover.querySelector('[data-action="apply"]').addEventListener('click', function () {
      var pending = onApply(popover);
      closePopover();
      if (pending !== 'async') emitChange();
    });
    var clearBtn = popover.querySelector('[data-action="clear"]');
    if (clearBtn) {
      clearBtn.addEventListener('click', function () {
        var pending = onApply(popover, 'clear');
        closePopover();
        if (pending !== 'async') emitChange();
      });
    }
  }

  function readFileAsDataUrl(file, callback) {
    var reader = new FileReader();
    reader.onload = function () { callback(String(reader.result || '')); };
    reader.readAsDataURL(file);
  }

  function openImageEditor(img) {
    openPopover(
      '替换图片',
      '<label>图片链接<input type="url" data-role="url" value="' + (img.src.indexOf('data:') === 0 ? '' : escapeAttr(img.src)) + '" placeholder="https://..." /></label>' +
      '<label>替代文字（Alt）<input type="text" data-role="alt" value="' + escapeAttr(img.alt || '') + '" placeholder="图片描述" /></label>' +
      '<label>本地图片<input type="file" accept="image/*" data-role="file" /></label>',
      function (panel) {
        var fileInput = panel.querySelector('[data-role="file"]');
        var urlInput = panel.querySelector('[data-role="url"]');
        var altInput = panel.querySelector('[data-role="alt"]');
        img.alt = String(altInput.value || '');
        if (fileInput.files && fileInput.files[0]) {
          readFileAsDataUrl(fileInput.files[0], function (dataUrl) {
            img.src = dataUrl;
            emitChange();
          });
          return 'async';
        }
        var next = String(urlInput.value || '').trim();
        if (next) img.src = next;
      },
      img,
    );
  }

  function openMediaEditor(el, label) {
    var src = el.getAttribute('src') || '';
    var poster = el.getAttribute('poster') || '';
    openPopover(
      label,
      '<label>资源链接<input type="url" data-role="url" value="' + escapeAttr(src) + '" placeholder="https://..." /></label>' +
      (el.tagName === 'VIDEO'
        ? '<label>封面图（Poster）<input type="url" data-role="poster" value="' + escapeAttr(poster) + '" placeholder="可选" /></label>'
        : '') +
      '<label>本地文件<input type="file" data-role="file" accept="' + (el.tagName === 'AUDIO' ? 'audio/*' : 'video/*,image/*') + '" /></label>',
      function (panel) {
        var fileInput = panel.querySelector('[data-role="file"]');
        var urlInput = panel.querySelector('[data-role="url"]');
        var posterInput = panel.querySelector('[data-role="poster"]');
        if (fileInput.files && fileInput.files[0]) {
          readFileAsDataUrl(fileInput.files[0], function (dataUrl) {
            el.setAttribute('src', dataUrl);
            if (el.tagName === 'VIDEO' && fileInput.files[0].type.startsWith('image/')) {
              el.setAttribute('poster', dataUrl);
            }
            emitChange();
          });
          return 'async';
        }
        var next = String(urlInput.value || '').trim();
        if (next) el.setAttribute('src', next);
        if (posterInput) {
          var posterNext = String(posterInput.value || '').trim();
          if (posterNext) el.setAttribute('poster', posterNext);
        }
      },
      el,
    );
  }

  function openIframeEditor(iframe) {
    var src = iframe.getAttribute('src') || '';
    openPopover(
      '替换嵌入内容',
      '<label>嵌入链接<input type="url" data-role="url" value="' + escapeAttr(src) + '" placeholder="https://..." /></label>',
      function (panel) {
        var next = String(panel.querySelector('[data-role="url"]').value || '').trim();
        if (next) iframe.setAttribute('src', next);
      },
      iframe,
      '适用于地图、视频嵌入等 iframe 内容',
    );
  }

  function openLinkEditor(anchor) {
    openPopover(
      '编辑链接',
      '<label>显示文字<input type="text" data-role="text" value="' + escapeAttr(anchor.textContent || '') + '" /></label>' +
      '<label>链接地址<input type="url" data-role="href" value="' + escapeAttr(anchor.getAttribute('href') || '') + '" placeholder="https://..." /></label>' +
      '<label data-inline="true"><input type="checkbox" data-role="blank" ' + (anchor.target === '_blank' ? 'checked' : '') + ' /> 新窗口打开</label>',
      function (panel) {
        var text = String(panel.querySelector('[data-role="text"]').value || '');
        var href = String(panel.querySelector('[data-role="href"]').value || '').trim();
        var blank = panel.querySelector('[data-role="blank"]').checked;
        anchor.textContent = text;
        if (href) anchor.setAttribute('href', href);
        else anchor.removeAttribute('href');
        if (blank) anchor.setAttribute('target', '_blank');
        else anchor.removeAttribute('target');
      },
      anchor,
      '单击链接可改文字，双击打开此面板改地址',
    );
  }

  function rgbToHex(color) {
    var match = String(color || '').match(/rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)/i);
    if (!match) return '#ffffff';
    function hex(n) { return Number(n).toString(16).padStart(2, '0'); }
    return '#' + hex(match[1]) + hex(match[2]) + hex(match[3]);
  }

  function extractBackgroundUrl(style) {
    var bg = style.backgroundImage;
    if (!bg || bg === 'none') return '';
    var match = bg.match(/url\\(["']?([^"')]+)["']?\\)/);
    return match ? match[1] : '';
  }

  function openBackgroundEditor(el) {
    var style = window.getComputedStyle(el);
    var currentUrl = extractBackgroundUrl(style);
    openPopover(
      '替换背景',
      '<label>背景颜色<input type="color" data-role="color" value="' + rgbToHex(style.backgroundColor) + '" /></label>' +
      '<label>背景图片链接<input type="url" data-role="bg-url" value="' + escapeAttr(currentUrl) + '" placeholder="留空则仅使用颜色" /></label>' +
      '<label>本地背景图<input type="file" accept="image/*" data-role="bg-file" /></label>' +
      '<button type="button" data-action="clear">清除背景图</button>',
      function (panel, mode) {
        var color = panel.querySelector('[data-role="color"]').value;
        var bgUrl = String(panel.querySelector('[data-role="bg-url"]').value || '').trim();
        var bgFile = panel.querySelector('[data-role="bg-file"]');
        function applyBackground(url) {
          if (mode === 'clear' || !url) {
            el.style.backgroundImage = 'none';
          } else {
            el.style.backgroundImage = 'url("' + url.replace(/"/g, '\\"') + '")';
            el.style.backgroundSize = el.style.backgroundSize || 'cover';
            el.style.backgroundPosition = el.style.backgroundPosition || 'center';
            el.style.backgroundRepeat = el.style.backgroundRepeat || 'no-repeat';
          }
          if (color) el.style.backgroundColor = color;
        }
        if (mode === 'clear') {
          applyBackground('');
          return;
        }
        if (bgFile.files && bgFile.files[0]) {
          readFileAsDataUrl(bgFile.files[0], function (url) {
            applyBackground(url);
            emitChange();
          });
          return 'async';
        }
        applyBackground(bgUrl);
      },
      el,
      '点击大面积空白或有色区块即可替换背景',
    );
  }

  function markBackgroundTargets() {
    var nodes = document.querySelectorAll('body, main, section, article, header, footer, div');
    nodes.forEach(function (el) {
      if (el.closest('.mindspace-editor-popover,.mindspace-editor-guide,.mindspace-editor-legend')) return;
      if (el.isContentEditable) return;
      var style = window.getComputedStyle(el);
      var cls = String(el.className || '');
      var structural = /\\b(page|hero|cover|banner|bg|background|section|card|panel|wrap|container|shell|stage|canvas|frame|viewport)\\b/i.test(cls);
      var painted = style.backgroundImage !== 'none' || (style.backgroundColor && style.backgroundColor !== 'rgba(0, 0, 0, 0)' && style.backgroundColor !== 'transparent');
      if (el.tagName === 'BODY' || structural || (painted && el.offsetWidth > 64 && el.offsetHeight > 64)) {
        el.setAttribute('data-mindspace-bg-target', 'true');
        markEditable(el, 'background', '点击换背景');
        if (el.offsetWidth > 180 && el.offsetHeight > 120) {
          el.setAttribute('data-mindspace-bg-large', 'true');
        }
      }
    });
  }

  function markMediaTargets() {
    document.querySelectorAll('img').forEach(function (img) {
      if (img.closest('.mindspace-editor-popover,.mindspace-editor-guide,.mindspace-editor-legend')) return;
      markEditable(img, 'media', '点击换图片');
    });
    document.querySelectorAll('video').forEach(function (video) {
      if (video.closest('.mindspace-editor-popover,.mindspace-editor-guide,.mindspace-editor-legend')) return;
      markEditable(video, 'media', '点击换视频');
    });
    document.querySelectorAll('audio').forEach(function (audio) {
      if (audio.closest('.mindspace-editor-popover,.mindspace-editor-guide,.mindspace-editor-legend')) return;
      markEditable(audio, 'media', '点击换音频');
    });
    document.querySelectorAll('iframe').forEach(function (iframe) {
      if (iframe.closest('.mindspace-editor-popover,.mindspace-editor-guide,.mindspace-editor-legend')) return;
      iframe.setAttribute('data-mindspace-media-target', 'true');
      markEditable(iframe, 'media', '点击换嵌入');
    });
  }

  function markLinkTargets() {
    document.querySelectorAll('a[href]').forEach(function (anchor) {
      if (anchor.closest('.mindspace-editor-popover,.mindspace-editor-guide,.mindspace-editor-legend')) return;
      anchor.setAttribute('data-mindspace-link-target', 'true');
      markEditable(anchor, 'link', '双击改链接');
    });
  }

  function enableTextEditing() {
    document.querySelectorAll(TEXT_SELECTOR).forEach(function (el) {
      if (el.closest('.mindspace-editor-popover,.mindspace-editor-guide,.mindspace-editor-legend')) return;
      if (el.querySelector && el.querySelector(MEDIA_BLOCK_SELECTOR)) return;
      if (el.matches('a[data-mindspace-link-target="true"]')) return;
      var textParent = el.closest('[data-mindspace-edit-kind="text"]');
      if (textParent && textParent !== el) return;
      el.setAttribute('contenteditable', 'true');
      el.setAttribute('spellcheck', 'true');
      markEditable(el, 'text', '点击改文字');
    });

    document.querySelectorAll('div').forEach(function (el) {
      if (el.closest('.mindspace-editor-popover,.mindspace-editor-guide,.mindspace-editor-legend')) return;
      if (el.hasAttribute('contenteditable')) return;
      if (el.querySelector(BLOCK_CHILD_SELECTOR)) return;
      if (el.querySelector(MEDIA_BLOCK_SELECTOR)) return;
      if (!String(el.textContent || '').trim()) return;
      el.setAttribute('contenteditable', 'true');
      el.setAttribute('spellcheck', 'true');
      markEditable(el, 'text', '点击改文字');
    });
  }

  function addEditLegend() {
    var legend = document.createElement('div');
    legend.className = 'mindspace-editor-legend';
    legend.innerHTML =
      '<strong>编辑模式 · 可修改区域</strong>' +
      '<div class="mindspace-editor-legend-items">' +
      '<div class="mindspace-editor-legend-item"><span class="mindspace-editor-legend-swatch" data-kind="text"></span><span>蓝色虚线 = 文字，直接点击修改</span></div>' +
      '<div class="mindspace-editor-legend-item"><span class="mindspace-editor-legend-swatch" data-kind="media"></span><span>橙色虚线 = 图片/音视频，点击替换</span></div>' +
      '<div class="mindspace-editor-legend-item"><span class="mindspace-editor-legend-swatch" data-kind="link"></span><span>紫色虚线 = 链接，双击改地址</span></div>' +
      '<div class="mindspace-editor-legend-item"><span class="mindspace-editor-legend-swatch" data-kind="background"></span><span>绿色虚线 = 背景区域，点击换背景</span></div>' +
      '</div>' +
      '<button type="button" class="mindspace-editor-legend-toggle" data-action="toggle-highlights">隐藏标记</button>';
    document.body.appendChild(legend);
    legend.querySelector('[data-action="toggle-highlights"]').addEventListener('click', function () {
      var hidden = document.body.getAttribute('data-mindspace-highlights') === 'off';
      if (hidden) {
        document.body.removeAttribute('data-mindspace-highlights');
        this.textContent = '隐藏标记';
      } else {
        document.body.setAttribute('data-mindspace-highlights', 'off');
        this.textContent = '显示标记';
      }
    });
  }

  function onClick(event) {
    var target = event.target;
    if (!(target instanceof Element)) return;
    if (target.closest('.mindspace-editor-popover,.mindspace-editor-guide,.mindspace-editor-legend')) return;

    if (target.tagName === 'IMG') {
      event.preventDefault();
      openImageEditor(target);
      return;
    }
    if (target.tagName === 'VIDEO' || target.tagName === 'AUDIO') {
      event.preventDefault();
      openMediaEditor(target, target.tagName === 'VIDEO' ? '替换视频' : '替换音频');
      return;
    }
    if (target.tagName === 'IFRAME' && target.getAttribute('data-mindspace-media-target') === 'true') {
      event.preventDefault();
      openIframeEditor(target);
      return;
    }
    if (target.isContentEditable) return;
    if (target.matches('[data-mindspace-bg-target="true"]') || target.tagName === 'BODY') {
      event.preventDefault();
      openBackgroundEditor(target.tagName === 'BODY' ? document.body : target);
    }
  }

  function onDblClick(event) {
    var target = event.target;
    if (!(target instanceof Element)) return;
    var anchor = target.closest('a[data-mindspace-link-target="true"]');
    if (!anchor) return;
    event.preventDefault();
    openLinkEditor(anchor);
  }

  function init() {
    document.body.setAttribute('data-mindspace-editing', 'true');
    enableTextEditing();
    markBackgroundTargets();
    markMediaTargets();
    markLinkTargets();
    addEditLegend();
    document.addEventListener('input', debounceEmit);
    document.addEventListener('blur', debounceEmit, true);
    document.addEventListener('click', onClick, true);
    document.addEventListener('dblclick', onDblClick, true);
    document.addEventListener('click', function (event) {
      var target = event.target;
      if (target instanceof HTMLAnchorElement) event.preventDefault();
    }, true);
    document.addEventListener('keydown', function (event) {
      if (event.key === 'Escape') closePopover();
    });
  }

  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', init);
  } else {
    init();
  }
})();
</script>`;

/** Remove inline CSP meta tags so preview-edit bootstrap can run inside srcdoc iframes. */
export function stripPreviewEditCspMeta(html: string): string {
  return String(html ?? '').replace(
    /<meta\s+http-equiv\s*=\s*["']Content-Security-Policy["'][^>]*>/gi,
    '',
  );
}

export function buildEditablePreviewDocument(html: string): string {
  const source = String(html ?? '').trim();
  const cleaned = stripPreviewEditCspMeta(source)
    .replace(/<style id="mindspace-visual-editor-style">[\s\S]*?<\/style>/gi, '')
    .replace(/<script id="mindspace-visual-editor-script">[\s\S]*?<\/script>/gi, '');
  const injection = `${EDITOR_STYLE}${EDITOR_SCRIPT}`;

  if (!cleaned) {
    return buildEditablePreviewDocument(
      '<!doctype html><html lang="zh-CN"><head><meta charset="utf-8"></head><body><p>空白页面</p></body></html>',
    );
  }

  if (/<\/body>/i.test(cleaned)) {
    return cleaned.replace(/<\/body>/i, `${injection}</body>`);
  }
  if (/<\/html>/i.test(cleaned)) {
    return cleaned.replace(/<\/html>/i, `${injection}</html>`);
  }
  return `<!doctype html><html lang="zh-CN"><head><meta charset="utf-8"></head><body>${cleaned}${injection}</body></html>`;
}
