export function createSidebarPageAiMarkdownRuntime(context) {
  const { escapeHtml } = context;

  function textFromUnknown(value) {
    if (value == null) return '';
    if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') return String(value);
    if (Array.isArray(value)) return value.map(textFromUnknown).filter(Boolean).join(' ');
    if (typeof value !== 'object') return '';
    var parts = [];
    ['text', 'title', 'content', 'children', 'blocks', 'body'].forEach(function(key) {
      if (Object.prototype.hasOwnProperty.call(value, key)) {
        var text = textFromUnknown(value[key]);
        if (text) parts.push(text);
      }
    });
    return parts.join(' ');
  }

  function renderPageAiMarkdownInline(text) {
    var html = escapeHtml(String(text || ''));
    var codeSpans = [];
    var htmlSpans = [];
    function stashHtml(value) {
      var key = '\u0000HTML' + htmlSpans.length + '\u0000';
      htmlSpans.push(value);
      return key;
    }
    html = html.replace(/`([^`\n]+)`/g, function(_, code) {
      var key = '\u0000CODE' + codeSpans.length + '\u0000';
      codeSpans.push('<code>' + code + '</code>');
      return key;
    });
    html = html.replace(/\[((?:\\.|[^\]\n])+)\]\(([^)\n]+)\)/g, function(match, label, href) {
      var normalizedHref = normalizePageAiMarkdownHref(href);
      if (!normalizedHref) return match;
      var citationAttr = isMnoteCitationHref(normalizedHref) ? ' data-page-ai-citation-link="true"' : '';
      return stashHtml('<a href="' + escapeHtml(normalizedHref) + '" target="_blank" rel="noopener noreferrer"' + citationAttr + '>' + unescapePageAiMarkdownLabel(label) + '</a>');
    });
    html = html.replace(/(^|[\s(])((?:https?:\/\/|\/documents\/|mnote:\/\/open(?:Resource)?)[^\s<>()]+[^\s<>().,;:!?])/g, function(_, prefix, href) {
      var normalizedHref = normalizePageAiMarkdownHref(href);
      if (!normalizedHref) return prefix + href;
      var citationAttr = isMnoteCitationHref(normalizedHref) ? ' data-page-ai-citation-link="true"' : '';
      return prefix + stashHtml('<a href="' + escapeHtml(normalizedHref) + '" target="_blank" rel="noopener noreferrer"' + citationAttr + '>' + escapeHtml(normalizedHref) + '</a>');
    });
    html = html.replace(/\*\*([^*\n]+)\*\*/g, '<strong>$1</strong>');
    html = html.replace(/(^|[^*])\*([^*\n]+)\*/g, '$1<em>$2</em>');
    codeSpans.forEach(function(value, index) {
      html = html.replace('\u0000CODE' + index + '\u0000', value);
    });
    htmlSpans.forEach(function(value, index) {
      html = html.replace('\u0000HTML' + index + '\u0000', value);
    });
    return html;
  }

  function normalizePageAiMarkdownHref(value) {
    var href = String(value || '').trim()
      .replace(/&lt;/g, '<')
      .replace(/&gt;/g, '>')
      .replace(/&quot;/g, '"')
      .replace(/&#39;/g, "'");
    while (href.includes('&amp;')) href = href.replace(/&amp;/g, '&');
    if (href.startsWith('<') && href.endsWith('>')) href = href.slice(1, -1).trim();
    if (!href || /[\u0000-\u001f<>"']/.test(href)) return '';
    var lower = href.toLowerCase();
    if (lower.startsWith('javascript:') || lower.startsWith('data:') || lower.startsWith('vbscript:')) return '';
    if (lower.startsWith('mnote://open')) href = normalizePageAiMnoteOpenHref(href);
    href = normalizePageAiLegacyCitationHref(href);
    if (href.startsWith('/') || href.startsWith('#')) return href;
    if (/^https?:\/\//i.test(href) || /^mailto:/i.test(href)) return href;
    return '';
  }

  function unescapePageAiMarkdownLabel(value) {
    return String(value || '').replace(/\\([\\\[\]()*_`])/g, '$1');
  }

  function normalizePageAiMnoteOpenHref(href) {
    try {
      var url = new URL(href);
      if (url.protocol !== 'mnote:' || (url.hostname !== 'open' && url.hostname !== 'openResource')) return href;
      var path = String(url.searchParams.get('path') || url.searchParams.get('resourcePath') || '').trim();
      if (!path) return '';
      var params = new URLSearchParams();
      var rootUri = String(url.searchParams.get('rootUri') || '').trim();
      if (!rootUri) {
        try {
          rootUri = new URL(window.location.href).searchParams.get('rootUri') || '';
        } catch (_locationError) {}
      }
      if (rootUri) params.set('rootUri', rootUri);
      params.set('path', path);
      ['page', 'bbox', 'sourceMapPath', 'blockId', 'evidenceText', 'lineRange', 'charRange'].forEach(function(key) {
        var value = String(url.searchParams.get(key) || '').trim();
        if (value) params.set(key, value);
      });
      return '/api/local-folder/files/open?' + params.toString();
    } catch (_error) {
      return href;
    }
  }

  function normalizePageAiLegacyCitationHref(href) {
    try {
      var url = new URL(href, window.location.origin);
      var unwrappedHref = normalizePageAiSearchWrappedCitationHref(url);
      if (unwrappedHref) return normalizePageAiLegacyCitationHref(unwrappedHref);
      if (!isPageAiSameMnoteOrigin(url) && !isPageAiPortableMnoteCitationUrl(url)) return href;
      if (url.pathname === '/api/local-folder/files/open') return url.pathname + url.search;
      if (!url.pathname.startsWith('/documents/')) return href;
      if (isPageAiUnsafeCitationDocumentId(url)) {
        var fileOpenHref = normalizePageAiCitationFileOpenHref(url);
        if (fileOpenHref) return fileOpenHref;
      }
      var decodedHash = '';
      try {
        decodedHash = decodeURIComponent(url.hash || '');
      } catch (_decodeError) {
        decodedHash = url.hash || '';
      }
      var marker = '#resource-tab-';
      var markerIndex = decodedHash.indexOf(marker);
      if (markerIndex < 0 || url.searchParams.get('resourceTab')) {
        return url.pathname + url.search + url.hash;
      }
      var identity = decodedHash.slice(markerIndex + marker.length).replace(/^#+/, '').trim();
      if (!identity.startsWith('resource:file:')) return url.pathname + url.search + url.hash;
      url.searchParams.set('resourceTab', identity);
      if (!url.searchParams.get('sourceKind')) url.searchParams.set('sourceKind', 'local_folder');
      var rootUri = String(url.searchParams.get('rootUri') || '').trim();
      var prefix = 'resource:file:' + rootUri + ':';
      if (rootUri && identity.startsWith(prefix) && !url.searchParams.get('resourcePath')) {
        url.searchParams.set('resourcePath', identity.slice(prefix.length).replace(/^\/+/, ''));
      }
      url.hash = '';
      return url.pathname + url.search;
    } catch (_error) {
      return href;
    }
  }

  function normalizePageAiSearchWrappedCitationHref(url) {
    var raw = '';
    ['wd', 'q', 'query'].some(function(key) {
      raw = String(url.searchParams.get(key) || '').trim();
      return Boolean(raw);
    });
    if (!raw) return '';
    if (/^documents\//i.test(raw)) raw = '/' + raw;
    if (!/^\/documents\//i.test(raw) && !/^https?:\/\/[^/]+\/documents\//i.test(raw) && !/^mnote:\/\/open/i.test(raw)) return '';
    if (/^mnote:\/\/open/i.test(raw)) return normalizePageAiMnoteOpenHref(raw);
    var nested = new URL(raw, window.location.origin);
    if (!nested.pathname.startsWith('/documents/')) return '';
    ['sourceKind', 'rootUri', 'workspaceId', 'resourceTab', 'resourcePath', 'page', 'bbox', 'sourceMapPath', 'blockId', 'evidenceText', 'lineRange', 'charRange'].forEach(function(key) {
      if (nested.searchParams.get(key)) return;
      var value = String(url.searchParams.get(key) || '').trim();
      if (value) nested.searchParams.set(key, value);
    });
    return nested.pathname + nested.search;
  }

  function normalizePageAiCitationFileOpenHref(url) {
    var rootUri = String(url.searchParams.get('rootUri') || '').trim();
    var path = String(url.searchParams.get('resourcePath') || '').trim();
    if (!rootUri || !path) return '';
    var params = new URLSearchParams();
    params.set('rootUri', rootUri);
    params.set('path', path);
    ['page', 'bbox', 'sourceMapPath', 'blockId', 'evidenceText', 'lineRange', 'charRange'].forEach(function(key) {
      var value = String(url.searchParams.get(key) || '').trim();
      if (value) params.set(key, value);
    });
    return '/api/local-folder/files/open?' + params.toString();
  }

  function isPageAiUnsafeCitationDocumentId(url) {
    try {
      var raw = String(url.pathname || '').replace(/^\/documents\//, '').split('/')[0] || '';
      if (!raw) return false;
      var decoded = decodeURIComponent(raw);
      return decoded.indexOf('%') >= 0 || decoded.indexOf('\uFFFD') >= 0;
    } catch (_error) {
      return true;
    }
  }

  function isPageAiPortableMnoteCitationUrl(url) {
    try {
      if (url.pathname === '/api/local-folder/files/open') {
        return Boolean(String(url.searchParams.get('rootUri') || '').trim()) &&
          Boolean(String(url.searchParams.get('path') || '').trim());
      }
      if (!url.pathname.startsWith('/documents/')) return false;
      var resourceTab = String(url.searchParams.get('resourceTab') || '').trim();
      return String(url.searchParams.get('sourceKind') || '').trim() === 'local_folder' ||
        Boolean(String(url.searchParams.get('rootUri') || '').trim()) ||
        Boolean(String(url.searchParams.get('resourcePath') || '').trim()) ||
        resourceTab.startsWith('resource:file:');
    } catch (_error) {
      return false;
    }
  }

  function isPageAiMarkdownTableDivider(line) {
    var cells = splitPageAiMarkdownTableRow(line);
    if (cells.length < 2) return false;
    return cells.every(function(cell) {
      return /^:?-{3,}:?$/.test(cell.trim());
    });
  }

  function splitPageAiMarkdownTableRow(line) {
    var text = String(line || '').trim();
    if (!text.includes('|')) return [];
    if (text.startsWith('|')) text = text.slice(1);
    if (text.endsWith('|')) text = text.slice(0, -1);
    return text.split('|').map(function(cell) { return cell.trim(); });
  }

  function renderPageAiMarkdownTable(lines, startIndex) {
    if (startIndex + 1 >= lines.length || !isPageAiMarkdownTableDivider(lines[startIndex + 1])) return null;
    var header = splitPageAiMarkdownTableRow(lines[startIndex]);
    var divider = splitPageAiMarkdownTableRow(lines[startIndex + 1]);
    if (!header.length || header.length !== divider.length) return null;
    var rows = [];
    var index = startIndex + 2;
    while (index < lines.length && lines[index].trim() && lines[index].includes('|')) {
      var cells = splitPageAiMarkdownTableRow(lines[index]);
      if (!cells.length) break;
      rows.push(cells);
      index += 1;
    }
    function cellHtml(tag, value) {
      return '<' + tag + '>' + renderPageAiMarkdownInline(value) + '</' + tag + '>';
    }
    var head = '<thead><tr>' + header.map(function(cell) { return cellHtml('th', cell); }).join('') + '</tr></thead>';
    var body = rows.length
      ? '<tbody>' + rows.map(function(row) {
          return '<tr>' + header.map(function(_, cellIndex) { return cellHtml('td', row[cellIndex] || ''); }).join('') + '</tr>';
        }).join('') + '</tbody>'
      : '';
    return {
      html: '<div class="wolai-page-ai-markdown-table-wrap"><table>' + head + body + '</table></div>',
      nextIndex: index
    };
  }

  function isMnoteCitationHref(href) {
    try {
      var url = new URL(href, window.location.origin);
      if (!isPageAiSameMnoteOrigin(url)) return false;
      return url.pathname.startsWith('/documents/') || url.pathname === '/api/local-folder/files/open';
    } catch (_error) {
      return false;
    }
  }

  function isPageAiSameMnoteOrigin(url) {
    try {
      var current = new URL(window.location.origin);
      if (url.origin === current.origin) return true;
      if (url.hostname === 'mnote.local') return true;
      var localNames = ['localhost', '127.0.0.1', '::1', 'mnote.local'];
      return localNames.indexOf(url.hostname) >= 0 &&
        localNames.indexOf(current.hostname) >= 0 &&
        String(url.port || defaultPortForProtocol(url.protocol)) === String(current.port || defaultPortForProtocol(current.protocol));
    } catch (_error) {
      return false;
    }
  }

  function defaultPortForProtocol(protocol) {
    return protocol === 'https:' ? '443' : protocol === 'http:' ? '80' : '';
  }

  function renderPageAiMarkdown(content) {
    var lines = String(content || '').replace(/\r\n?/g, '\n').split('\n');
    var blocks = [];
    var index = 0;
    function isBlockBoundary(line) {
      return !line.trim() ||
        /^```/.test(line.trim()) ||
        /^#{1,6}\s+/.test(line) ||
        /^\s*[-*]\s+/.test(line) ||
        /^\s*\d+[.)]\s+/.test(line);
    }
    while (index < lines.length) {
      var line = lines[index];
      if (!line.trim()) {
        index += 1;
        continue;
      }
      if (/^```/.test(line.trim())) {
        index += 1;
        var codeLines = [];
        while (index < lines.length && !/^```/.test(lines[index].trim())) {
          codeLines.push(lines[index]);
          index += 1;
        }
        if (index < lines.length) index += 1;
        blocks.push('<pre><code>' + escapeHtml(codeLines.join('\n')) + '</code></pre>');
        continue;
      }
      if (/^\s*-{3,}\s*$/.test(line)) {
        blocks.push('<hr />');
        index += 1;
        continue;
      }
      var table = renderPageAiMarkdownTable(lines, index);
      if (table) {
        blocks.push(table.html);
        index = table.nextIndex;
        continue;
      }
      var heading = line.match(/^(#{1,6})\s+(.+)$/);
      if (heading) {
        var level = Math.min(6, heading[1].length);
        blocks.push('<h' + level + '>' + renderPageAiMarkdownInline(heading[2]) + '</h' + level + '>');
        index += 1;
        continue;
      }
      if (/^\s*[-*]\s+/.test(line)) {
        var unordered = [];
        while (index < lines.length && /^\s*[-*]\s+/.test(lines[index])) {
          unordered.push('<li>' + renderPageAiMarkdownInline(lines[index].replace(/^\s*[-*]\s+/, '')) + '</li>');
          index += 1;
        }
        blocks.push('<ul>' + unordered.join('') + '</ul>');
        continue;
      }
      if (/^\s*\d+[.)]\s+/.test(line)) {
        var ordered = [];
        while (index < lines.length && /^\s*\d+[.)]\s+/.test(lines[index])) {
          ordered.push('<li>' + renderPageAiMarkdownInline(lines[index].replace(/^\s*\d+[.)]\s+/, '')) + '</li>');
          index += 1;
        }
        blocks.push('<ol>' + ordered.join('') + '</ol>');
        continue;
      }
      var paragraph = [];
      while (index < lines.length && !isBlockBoundary(lines[index])) {
        paragraph.push(renderPageAiMarkdownInline(lines[index]));
        index += 1;
      }
      if (paragraph.length) {
        blocks.push('<p>' + paragraph.join('<br />') + '</p>');
      } else {
        index += 1;
      }
    }
    return blocks.join('') || escapeHtml(String(content || ''));
  }

  return {
    textFromUnknown,
    renderPageAiMarkdown,
    renderPageAiMarkdownInline
  };
}
