export function createSidebarPageSettingsRuntime(context) {
  const {
    currentDocumentId,
    currentPageAggregate,
    currentRootUri,
    currentSourceKind,
    currentWorkspaceSourcePayload,
    escapeHtml,
    pageUiState,
    resolveWorkspaceId,
    searchText,
  } = context;
  const MNOTE_GLOBAL_SHOW_HEADING_NUMBERS_KEY = context.globalShowHeadingNumbersKey || 'mnote.global.showHeadingNumbers';

  function defaultPageOptions() {
    return {
      wideLayout: false,
      smallText: false,
      layoutDensity: 'normal',
      showHeadingNumbers: false,
      showToc: false,
      showStructure: false,
      protectEditing: false,
      showWordCount: true,
      collapseBacklinks: false,
      pageFont: 'default',
      hideChildPages: false,
      showBlockRefCount: false,
      hideTitleHeader: false,
      embedDefaultBlockId: null
    };
  }

  function currentPageOptions() {
    if (pageUiState.pageOptions) return pageUiState.pageOptions;
    var aggregate = currentPageAggregate();
    var current = aggregate && aggregate.layout && aggregate.layout.pageOptions && typeof aggregate.layout.pageOptions === 'object'
      ? aggregate.layout.pageOptions
      : null;
    if (!current) {
      return defaultPageOptions();
    }
    pageUiState.pageOptions = Object.assign(defaultPageOptions(), current);
    return pageUiState.pageOptions;
  }

  function readGlobalShowHeadingNumbers() {
    return Boolean(currentPageOptions().showHeadingNumbers);
  }

  function writeGlobalShowHeadingNumbers(value) {
    void persistPageOptionsPatch({ showHeadingNumbers: Boolean(value) });
  }

  function effectiveShowHeadingNumbers(options) {
    return Boolean(options && options.showHeadingNumbers);
  }

  function pageOptionIsSupported(name) {
    return name === 'wideLayout'
      || name === 'smallText'
      || name === 'layoutDensity'
      || name === 'pageFont'
      || name === 'showHeadingNumbers'
      || (name === 'hideTitleHeader' && currentSourceKind() === 'local_folder');
  }

  function pageOptionDescription(name) {
    if (name === 'wideLayout') return '自适应宽度';
    if (name === 'smallText') return '小字体';
    if (name === 'hideTitleHeader') return '隐藏本地 Markdown 文件标题';
    if (name === 'showToc') return '标题目录';
    if (name === 'showHeadingNumbers') return '标题自动编号';
    if (name === 'protectEditing') return '编辑保护';
    if (name === 'collapseBacklinks') return '折叠反向引用';
    if (name === 'hideChildPages') return '隐藏子页面';
    if (name === 'showBlockRefCount') return '显示块引用数字';
    return name;
  }

  function pageOptionHint(name) {
    if (name === 'wideLayout') return '已接通：主内容列宽度立即变化';
    if (name === 'smallText') return '已接通：正文排版会更紧凑';
    if (name === 'showHeadingNumbers') return '已接通：标题前显示顺序编号';
    if (name === 'hideTitleHeader') return '已接通：本地 Markdown 页头标题立即隐藏或显示';
    if (name === 'layoutDensity') return '已接通：段落与列表间距会变化';
    if (name === 'pageFont') return '已接通：当前页面字体会切换';
    if (name === 'showToc') return '待接线：当前 Rust 壳还没有正式目录面板';
    if (name === 'protectEditing') return '待接线：当前主编辑器只显示降级说明';
    if (name === 'collapseBacklinks') return '待接线：当前 Rust 壳未挂回链面板';
    if (name === 'hideChildPages') return '待接线：当前页面壳还没有子页面块显隐';
    if (name === 'showBlockRefCount') return '待接线：当前页面壳未显示块引用计数';
    return '待接线';
  }

  function ensureHistorySnapshotsSeeded() {
    if (pageUiState.historySnapshots.length > 0) return;
    var aggregate = currentPageAggregate();
    var stats = aggregate && aggregate.stats && typeof aggregate.stats === 'object' ? aggregate.stats : {};
    pageUiState.historySnapshots = [{
      id: 'snapshot-initial',
      timestamp: Date.now(),
      stats: {
        wordCount: Number(stats.wordCount || 0),
        characterCount: Number(stats.characterCount || 0),
        blockCount: Number(stats.blockCount || 0),
        todoTotal: Number(stats.todoTotal || 0),
        todoDone: Number(stats.todoDone || 0)
      }
    }];
  }

  function computeLivePageStats() {
    var aggregate = currentPageAggregate();
    var fallbackStats = aggregate && aggregate.stats && typeof aggregate.stats === 'object' ? aggregate.stats : {};
    var editor = document.querySelector('[data-testid="mnote-leptos-tiptap-island-editor-root"] .editor-surface .ProseMirror');
    if (!(editor instanceof HTMLElement)) {
      return {
        wordCount: Number(fallbackStats.wordCount || 0),
        characterCount: Number(fallbackStats.characterCount || 0),
        blockCount: Number(fallbackStats.blockCount || 0),
        todoTotal: Number(fallbackStats.todoTotal || 0),
        todoDone: Number(fallbackStats.todoDone || 0)
      };
    }
    var text = (editor.textContent || '').trim();
    var compact = text.replace(/\s+/g, ' ').trim();
    var wordCount = compact ? compact.split(' ').filter(Boolean).length : 0;
    var characterCount = text.replace(/\s/g, '').length;
    var blockCount = editor.querySelectorAll(':scope > *').length;
    var todos = Array.from(editor.querySelectorAll('input[type="checkbox"]'));
    return {
      wordCount: wordCount || Number(fallbackStats.wordCount || 0),
      characterCount: characterCount || Number(fallbackStats.characterCount || 0),
      blockCount: blockCount || Number(fallbackStats.blockCount || 0),
      todoTotal: todos.length || Number(fallbackStats.todoTotal || 0),
      todoDone: todos.filter(function(node){ return node.checked; }).length || Number(fallbackStats.todoDone || 0)
    };
  }

  function recordPageHistorySnapshot(reason, stats) {
    ensureHistorySnapshotsSeeded();
    pageUiState.historySnapshots = [{
      id: 'snapshot-' + Date.now(),
      timestamp: Date.now(),
      reason: reason || 'save',
      stats: stats || computeLivePageStats()
    }].concat(pageUiState.historySnapshots).slice(0, 15);
    renderPageHistoryDrawer();
  }

  function applyPageOptionsToShell() {
    var options = currentPageOptions();
    var globalShowHeadingNumbers = Boolean(options.showHeadingNumbers);
    var showHeadingNumbers = effectiveShowHeadingNumbers(options);
    var shell = document.querySelector('.document-shell');
    var editorRoot = document.querySelector('[data-testid="mnote-leptos-tiptap-island-editor-root"]');
    var editorSurface = editorRoot && editorRoot.querySelector('.editor-surface');
    if (shell instanceof HTMLElement) {
      shell.setAttribute('data-page-wide-layout', String(Boolean(options.wideLayout)));
      shell.setAttribute('data-page-small-text', String(Boolean(options.smallText)));
      shell.setAttribute('data-layout-density', String(options.layoutDensity || 'normal'));
      shell.setAttribute('data-page-font', String(options.pageFont || 'default'));
      shell.setAttribute('data-page-show-heading-numbers', String(showHeadingNumbers));
      shell.style.width = '100%';
      shell.style.maxWidth = options.wideLayout ? '980px' : '760px';
    }
    if (editorRoot instanceof HTMLElement) {
      editorRoot.setAttribute('data-page-wide-layout', String(Boolean(options.wideLayout)));
      editorRoot.setAttribute('data-page-small-text', String(Boolean(options.smallText)));
      editorRoot.setAttribute('data-page-show-heading-numbers', String(showHeadingNumbers));
      editorRoot.setAttribute('data-page-embed-default-block-id', options.embedDefaultBlockId == null ? '' : String(options.embedDefaultBlockId));
    }
    if (editorSurface instanceof HTMLElement) {
      editorSurface.setAttribute('data-layout-density', String(options.layoutDensity || 'normal'));
      editorSurface.setAttribute('data-page-font', String(options.pageFont || 'default'));
      editorSurface.setAttribute('data-show-heading-numbers', String(showHeadingNumbers));
    }
    document.documentElement.setAttribute('data-page-wide-layout', String(Boolean(options.wideLayout)));
    document.documentElement.setAttribute('data-page-small-text', String(Boolean(options.smallText)));
    document.documentElement.setAttribute('data-layout-density', String(options.layoutDensity || 'normal'));
    document.documentElement.setAttribute('data-page-font', String(options.pageFont || 'default'));
    document.documentElement.setAttribute('data-global-show-heading-numbers', String(globalShowHeadingNumbers));
    document.documentElement.setAttribute('data-page-show-heading-numbers', String(showHeadingNumbers));
    document.documentElement.setAttribute('data-page-hide-title-header', String(Boolean(options.hideTitleHeader)));
    var titleHeader = document.querySelector('.document-pane[data-pane-role="primary"] .document-shell-header') || document.querySelector('.document-shell-header');
    if (titleHeader instanceof HTMLElement) {
      var hidden = Boolean(options.hideTitleHeader);
      titleHeader.hidden = hidden;
      titleHeader.setAttribute('data-page-title-hidden', String(hidden));
    }
  }

  function updatePageSettingsTriggerState() {
    var trigger = document.querySelector('[data-testid="wolai-page-settings-trigger"]');
    if (!(trigger instanceof HTMLElement)) return;
    trigger.setAttribute('data-state', pageUiState.pageSettingsOpen ? 'open' : 'closed');
    trigger.setAttribute('aria-expanded', pageUiState.pageSettingsOpen ? 'true' : 'false');
  }

  function createPageOptionRow(key, type) {
    var inputType = type || 'checkbox';
    var supported = pageOptionIsSupported(key);
    if (inputType === 'checkbox') {
      return '' +
        '<label class="wolai-page-setting-row' + (supported ? '' : ' is-pending') + '" data-page-setting-row="' + key + '">' +
          '<span class="wolai-page-setting-copy">' +
            '<span class="wolai-page-setting-label">' + escapeHtml(pageOptionDescription(key)) + '</span>' +
            '<span class="wolai-page-setting-hint">' + escapeHtml(pageOptionHint(key)) + '</span>' +
          '</span>' +
          '<input type="checkbox" class="wolai-page-setting-checkbox" data-page-option-checkbox="' + key + '"' + (supported ? '' : ' data-setting-pending="true"') + ' />' +
        '</label>';
    }
    return '' +
      '<label class="wolai-page-setting-row" data-page-setting-row="' + key + '">' +
        '<span class="wolai-page-setting-copy">' +
          '<span class="wolai-page-setting-label">' + escapeHtml(pageOptionDescription(key)) + '</span>' +
          '<span class="wolai-page-setting-hint">' + escapeHtml(pageOptionHint(key)) + '</span>' +
        '</span>' +
        '<select class="wolai-page-setting-select" data-page-option-select="' + key + '">' +
          '<option value="compact">紧凑</option>' +
          '<option value="normal">默认</option>' +
          '<option value="spacious">宽松</option>' +
        '</select>' +
      '</label>';
  }

  function createGlobalHeadingNumbersRow() {
    return '' +
      '<label class="wolai-page-setting-row" data-page-setting-row="globalShowHeadingNumbers">' +
        '<span class="wolai-page-setting-copy">' +
          '<span class="wolai-page-setting-label">标题自动编号</span>' +
        '</span>' +
        '<input type="checkbox" class="wolai-page-setting-checkbox" data-global-option-checkbox="showHeadingNumbers" />' +
      '</label>';
  }

  function renderGlobalOptions(popover) {
    var globalHeadingNumbers = readGlobalShowHeadingNumbers();
    popover.querySelectorAll('[data-global-option-checkbox="showHeadingNumbers"]').forEach(function(input) {
      input.checked = globalHeadingNumbers;
    });
  }

  function createPageFontRow() {
    return '' +
      '<label class="wolai-page-setting-row" data-page-setting-row="pageFont">' +
        '<span class="wolai-page-setting-copy">' +
          '<span class="wolai-page-setting-label">页面字体</span>' +
          '<span class="wolai-page-setting-hint">已接通：仅对当前页面生效</span>' +
        '</span>' +
        '<select class="wolai-page-setting-select" data-page-option-select="pageFont">' +
          '<option value="default">默认</option>' +
          '<option value="song">宋体</option>' +
          '<option value="kai">楷体</option>' +
        '</select>' +
      '</label>';
  }

  function ensurePageHistoryDrawer() {
    var existing = document.querySelector('[data-testid="wolai-page-history-drawer"]');
    if (existing instanceof HTMLElement) return existing;
    var drawer = document.createElement('aside');
    drawer.className = 'wolai-page-history-drawer';
    drawer.setAttribute('data-testid', 'wolai-page-history-drawer');
    drawer.setAttribute('data-mnote-surface', 'page-history');
    drawer.hidden = true;
    drawer.innerHTML = '' +
      '<div class="wolai-page-history-panel">' +
        '<div class="wolai-page-history-header">' +
          '<div><div class="wolai-page-history-title">页面历史</div><div class="wolai-page-history-subtitle">当前会话内最近保存的 15 个快照。</div></div>' +
          '<button type="button" class="wolai-surface-close" data-page-history-action="close" aria-label="关闭页面历史">×</button>' +
        '</div>' +
        '<div class="wolai-page-history-list" data-page-history-list></div>' +
      '</div>';
    drawer.addEventListener('click', function(event) {
      if (event.target === drawer) closePageHistoryDrawer();
    });
    document.body.appendChild(drawer);
    return drawer;
  }

  function renderPageHistoryDrawer() {
    var drawer = ensurePageHistoryDrawer();
    var list = drawer.querySelector('[data-page-history-list]');
    if (!(list instanceof HTMLElement)) return;
    ensureHistorySnapshotsSeeded();
    list.innerHTML = pageUiState.historySnapshots.length
      ? pageUiState.historySnapshots.map(function(snapshot) {
          var stats = snapshot.stats || {};
          var label = new Date(snapshot.timestamp).toLocaleString('zh-CN', {
            year: 'numeric',
            month: '2-digit',
            day: '2-digit',
            hour: '2-digit',
            minute: '2-digit'
          });
          return '' +
            '<div class="wolai-page-history-item">' +
              '<div class="wolai-page-history-item-copy">' +
                '<div class="wolai-page-history-item-title">' + escapeHtml(label) + '</div>' +
                '<div class="wolai-page-history-item-meta">字数 ' + Number(stats.wordCount || 0) + ' · 字符 ' + Number(stats.characterCount || 0) + ' · 块数 ' + Number(stats.blockCount || 0) + '</div>' +
              '</div>' +
              '<button type="button" class="wolai-page-history-item-ghost" data-page-history-action="noop">仅查看</button>' +
            '</div>';
        }).join('')
      : '<div class="wolai-page-history-empty">尚未产生历史快照，编辑后会自动生成。</div>';
  }

  function openPageHistoryDrawer() {
    renderPageHistoryDrawer();
    var drawer = ensurePageHistoryDrawer();
    drawer.hidden = false;
    document.documentElement.setAttribute('data-mnote-page-history-open', 'true');
  }

  function closePageHistoryDrawer() {
    var drawer = document.querySelector('[data-testid="wolai-page-history-drawer"]');
    if (drawer instanceof HTMLElement) drawer.hidden = true;
    document.documentElement.removeAttribute('data-mnote-page-history-open');
  }

  function ensurePageShareDialog() {
    var existing = document.querySelector('[data-testid="wolai-page-share-dialog"]');
    if (existing instanceof HTMLElement) return existing;
    var dialog = document.createElement('div');
    dialog.className = 'wolai-page-share-dialog';
    dialog.setAttribute('data-testid', 'wolai-page-share-dialog');
    dialog.setAttribute('data-mnote-surface', 'page-share');
    dialog.hidden = true;
    dialog.innerHTML = '' +
      '<div class="wolai-page-share-card" role="dialog" aria-modal="true">' +
        '<div class="wolai-page-share-header">' +
          '<div><div class="wolai-page-share-title">公开分享页面</div><div class="wolai-page-share-subtitle">当前 3000 公开入口由 mnote-web 持有。</div></div>' +
          '<button type="button" class="wolai-surface-close" data-page-share-action="close" aria-label="关闭公开分享页面">×</button>' +
        '</div>' +
        '<div class="wolai-page-share-state">' +
          '<span class="wolai-public-pill wolai-public-pill--inline">全网公开</span>' +
          '<span class="wolai-page-share-copy">任何拥有链接的人都可以访问当前页面。</span>' +
        '</div>' +
        '<div class="wolai-page-share-url-row">' +
          '<input class="wolai-page-share-url" type="text" readonly data-page-share-url value="" />' +
          '<button type="button" class="wolai-page-share-copy-button" data-page-share-action="copy-link">复制链接</button>' +
        '</div>' +
        '<div class="wolai-page-share-footer">更多共享者、群组公开和权限策略仍待接线。</div>' +
      '</div>';
    dialog.addEventListener('click', function(event) {
      if (event.target === dialog) closePageShareDialog();
    });
    document.body.appendChild(dialog);
    return dialog;
  }

  function openPageShareDialog() {
    var dialog = ensurePageShareDialog();
    var input = dialog.querySelector('[data-page-share-url]');
    if (input instanceof HTMLInputElement) input.value = window.location.href;
    dialog.hidden = false;
    document.documentElement.setAttribute('data-mnote-page-share-open', 'true');
  }

  function closePageShareDialog() {
    var dialog = document.querySelector('[data-testid="wolai-page-share-dialog"]');
    if (dialog instanceof HTMLElement) dialog.hidden = true;
    document.documentElement.removeAttribute('data-mnote-page-share-open');
  }

  function ensurePageSettingsPopover() {
    var existing = document.querySelector('[data-testid="wolai-page-settings-popover"]');
    if (existing instanceof HTMLElement) return existing;
    var popover = document.createElement('div');
    popover.className = 'wolai-page-settings-popover';
    popover.setAttribute('data-testid', 'wolai-page-settings-popover');
    popover.setAttribute('data-mnote-surface', 'page-settings');
    popover.hidden = true;
    popover.innerHTML = '' +
      '<div class="wolai-page-settings-panel" role="dialog" aria-modal="false">' +
        '<div class="wolai-page-settings-tabs" data-testid="wolai-page-settings-tabs" role="tablist" aria-label="页面设置分组">' +
          '<button type="button" class="wolai-page-settings-tab is-active" role="tab" aria-selected="true" data-page-settings-tab="page">页面选项</button>' +
          '<button type="button" class="wolai-page-settings-tab" role="tab" aria-selected="false" data-page-settings-tab="custom">自定义页面</button>' +
          '<button type="button" class="wolai-page-settings-tab" role="tab" aria-selected="false" data-page-settings-tab="index">索引</button>' +
          '<button type="button" class="wolai-page-settings-tab" role="tab" aria-selected="false" data-page-settings-tab="global">全局选项</button>' +
        '</div>' +
        '<div class="wolai-page-settings-section" data-page-settings-panel="page">' +
          createPageOptionRow('wideLayout', 'checkbox') +
          createPageOptionRow('smallText', 'checkbox') +
          createPageOptionRow('showToc', 'checkbox') +
          createPageOptionRow('protectEditing', 'checkbox') +
          createPageOptionRow('hideTitleHeader', 'checkbox') +
        '</div>' +
        '<div class="wolai-page-settings-section" data-page-settings-panel="custom" hidden>' +
          createPageFontRow() +
          createPageOptionRow('layoutDensity', 'select') +
          createPageOptionRow('collapseBacklinks', 'checkbox') +
          createPageOptionRow('hideChildPages', 'checkbox') +
          createPageOptionRow('showBlockRefCount', 'checkbox') +
        '</div>' +
        '<div class="wolai-page-settings-section" data-page-settings-panel="index" hidden>' +
          '<div class="wolai-page-settings-index-panel" data-testid="wolai-page-settings-local-index-panel">' +
            '<div class="wolai-page-settings-index-status" data-testid="wolai-page-settings-local-index-status"></div>' +
            '<section class="wolai-page-settings-index-group">' +
              '<div class="wolai-page-settings-index-title">反链</div>' +
              '<div class="wolai-page-settings-index-list" data-testid="wolai-page-settings-local-index-backlinks"></div>' +
            '</section>' +
            '<section class="wolai-page-settings-index-group">' +
              '<div class="wolai-page-settings-index-title">标签</div>' +
              '<div class="wolai-page-settings-index-list" data-testid="wolai-page-settings-local-index-tags"></div>' +
            '</section>' +
          '</div>' +
        '</div>' +
        '<div class="wolai-page-settings-section" data-page-settings-panel="global" hidden>' +
          createGlobalHeadingNumbersRow() +
        '</div>' +
        '<div class="wolai-page-settings-actions">' +
          '<button type="button" class="wolai-page-settings-action" data-page-settings-action="history">页面历史...</button>' +
          '<button type="button" class="wolai-page-settings-action" data-page-settings-action="share">公开分享页面...</button>' +
          '<button type="button" class="wolai-page-settings-action is-disabled" data-page-settings-action="move" disabled>移动到...</button>' +
          '<button type="button" class="wolai-page-settings-action is-disabled" data-page-settings-action="embed" disabled>嵌入到...</button>' +
          '<button type="button" class="wolai-page-settings-action is-danger is-disabled" data-page-settings-action="delete" disabled>删除页面</button>' +
        '</div>' +
        '<div class="wolai-page-settings-stats" data-testid="wolai-page-settings-stats"></div>' +
      '</div>';
    document.body.appendChild(popover);
    return popover;
  }

  function pageSettingsLocalIndexScopeKey() {
    return [
      currentSourceKind(),
      currentRootUri(),
      resolveWorkspaceId(document.body),
      currentDocumentId()
    ].join('|');
  }

  function pageSettingsLocalIndexIsAvailable() {
    return currentSourceKind() === 'local_folder' && Boolean(currentRootUri()) && Boolean(currentDocumentId());
  }

  function pageSettingsLocalIndexEmpty(message) {
    return '<div class="wolai-page-settings-index-empty">' + escapeHtml(message) + '</div>';
  }

  function renderPageSettingsLocalIndexList(items, kind) {
    var rows = Array.isArray(items) ? items : [];
    if (!rows.length) {
      return pageSettingsLocalIndexEmpty(kind === 'backlinks' ? '暂无反链' : '暂无标签');
    }
    if (kind === 'backlinks') {
      return rows.slice(0, 12).map(function(item) {
        var title = searchText(item && item.title) || searchText(item && item.path) || '未命名页面';
        var path = searchText(item && item.path);
        var snippet = searchText(item && item.snippet);
        return '' +
          '<div class="wolai-page-settings-index-row">' +
            '<div class="wolai-page-settings-index-row-title">' + escapeHtml(title) + '</div>' +
            (path ? '<div class="wolai-page-settings-index-row-meta">' + escapeHtml(path) + '</div>' : '') +
            (snippet ? '<div class="wolai-page-settings-index-row-snippet">' + escapeHtml(snippet) + '</div>' : '') +
          '</div>';
      }).join('');
    }
    return rows.slice(0, 16).map(function(item) {
      var tag = searchText(item && item.tag) || 'untagged';
      var count = Number(item && item.count || 0);
      return '' +
        '<div class="wolai-page-settings-index-row is-tag">' +
          '<div class="wolai-page-settings-index-row-title">#' + escapeHtml(tag) + '</div>' +
          '<div class="wolai-page-settings-index-row-meta">' + count + ' 个页面</div>' +
        '</div>';
    }).join('');
  }

  function renderPageSettingsLocalIndex(popover) {
    popover = popover || ensurePageSettingsPopover();
    var statusNode = popover.querySelector('[data-testid="wolai-page-settings-local-index-status"]');
    var backlinksNode = popover.querySelector('[data-testid="wolai-page-settings-local-index-backlinks"]');
    var tagsNode = popover.querySelector('[data-testid="wolai-page-settings-local-index-tags"]');
    if (!(statusNode instanceof HTMLElement) || !(backlinksNode instanceof HTMLElement) || !(tagsNode instanceof HTMLElement)) return;

    if (!pageSettingsLocalIndexIsAvailable()) {
      statusNode.textContent = '本地索引仅在本地工作区页面可用';
      backlinksNode.innerHTML = pageSettingsLocalIndexEmpty('未连接本地 root');
      tagsNode.innerHTML = pageSettingsLocalIndexEmpty('未连接本地 root');
      return;
    }

    var summary = pageUiState.localIndexSummary || {};
    if (summary.loading) {
      statusNode.textContent = '正在读取本地索引...';
      backlinksNode.innerHTML = pageSettingsLocalIndexEmpty('加载中');
      tagsNode.innerHTML = pageSettingsLocalIndexEmpty('加载中');
      return;
    }
    if (summary.error) {
      statusNode.textContent = '本地索引读取失败';
      backlinksNode.innerHTML = pageSettingsLocalIndexEmpty(summary.error);
      tagsNode.innerHTML = pageSettingsLocalIndexEmpty(summary.error);
      return;
    }
    if (summary.scopeKey !== pageSettingsLocalIndexScopeKey()) {
      statusNode.textContent = '切换到索引页签后读取本地索引';
      backlinksNode.innerHTML = pageSettingsLocalIndexEmpty('等待读取');
      tagsNode.innerHTML = pageSettingsLocalIndexEmpty('等待读取');
      return;
    }

    statusNode.textContent = '来自当前授权 root 的 .mnote/index/search-index.json';
    backlinksNode.innerHTML = renderPageSettingsLocalIndexList(summary.backlinks, 'backlinks');
    tagsNode.innerHTML = renderPageSettingsLocalIndexList(summary.tags, 'tags');
  }

  async function loadPageSettingsLocalIndex(force) {
    if (!pageSettingsLocalIndexIsAvailable()) {
      renderPageSettingsLocalIndex();
      return;
    }
    var scopeKey = pageSettingsLocalIndexScopeKey();
    var current = pageUiState.localIndexSummary || {};
    if (!force && current.scopeKey === scopeKey && !current.error && !current.loading) {
      renderPageSettingsLocalIndex();
      return;
    }
    pageUiState.localIndexSummary = {
      scopeKey: scopeKey,
      loading: true,
      error: '',
      backlinks: null,
      tags: null
    };
    renderPageSettingsLocalIndex();
    try {
      var baseParams = new URLSearchParams();
      baseParams.set('workspaceId', resolveWorkspaceId(document.body));
      baseParams.set('rootUri', currentRootUri());
      var backlinksParams = new URLSearchParams(baseParams);
      backlinksParams.set('documentId', currentDocumentId());
      var backlinksUrl = '/api/search/local-index/backlinks?' + backlinksParams.toString();
      var tagsUrl = '/api/search/local-index/tags?' + baseParams.toString();
      var responses = await Promise.all([
        fetch(backlinksUrl, { headers: { accept: 'application/json' } }),
        fetch(tagsUrl, { headers: { accept: 'application/json' } })
      ]);
      var backlinksPayload = await responses[0].json().catch(function(){ return null; });
      var tagsPayload = await responses[1].json().catch(function(){ return null; });
      if (!responses[0].ok || !backlinksPayload || backlinksPayload.ok !== true) {
        throw new Error('backlinks_' + responses[0].status);
      }
      if (!responses[1].ok || !tagsPayload || tagsPayload.ok !== true) {
        throw new Error('tags_' + responses[1].status);
      }
      pageUiState.localIndexSummary = {
        scopeKey: scopeKey,
        loading: false,
        error: '',
        backlinks: backlinksPayload.result && Array.isArray(backlinksPayload.result.backlinks) ? backlinksPayload.result.backlinks : [],
        tags: tagsPayload.result && Array.isArray(tagsPayload.result.tags) ? tagsPayload.result.tags : []
      };
    } catch (error) {
      pageUiState.localIndexSummary = {
        scopeKey: scopeKey,
        loading: false,
        error: error instanceof Error ? error.message : String(error),
        backlinks: [],
        tags: []
      };
    }
    renderPageSettingsLocalIndex();
  }

  function renderPageSettingsPopover() {
    var popover = ensurePageSettingsPopover();
    var options = currentPageOptions();
    popover.querySelectorAll('[data-page-option-checkbox]').forEach(function(input) {
      var key = input.getAttribute('data-page-option-checkbox');
      input.checked = Boolean(options[key]);
      input.disabled = !pageOptionIsSupported(key);
    });
    popover.querySelectorAll('[data-page-option-select]').forEach(function(select) {
      var key = select.getAttribute('data-page-option-select');
      var value = key === 'layoutDensity' ? String(options.layoutDensity || 'normal') : String(options.pageFont || 'default');
      select.value = value;
    });
    renderGlobalOptions(popover);
    var statsNode = popover.querySelector('[data-testid="wolai-page-settings-stats"]');
    if (statsNode instanceof HTMLElement) {
      var stats = computeLivePageStats();
      statsNode.innerHTML = '' +
        '<span>字数 ' + Number(stats.wordCount || 0) + '</span>' +
        '<span>字符 ' + Number(stats.characterCount || 0) + '</span>' +
        '<span>块数 ' + Number(stats.blockCount || 0) + '</span>' +
        '<span>待办 ' + Number(stats.todoDone || 0) + '/' + Number(stats.todoTotal || 0) + '</span>';
    }
    renderPageSettingsLocalIndex(popover);
  }

  function setActivePageSettingsTab(tabName) {
    var popover = ensurePageSettingsPopover();
    popover.querySelectorAll('[data-page-settings-tab]').forEach(function(tab) {
      var active = tab.getAttribute('data-page-settings-tab') === tabName;
      tab.classList.toggle('is-active', active);
      tab.setAttribute('aria-selected', active ? 'true' : 'false');
    });
    popover.querySelectorAll('[data-page-settings-panel]').forEach(function(panel) {
      panel.hidden = panel.getAttribute('data-page-settings-panel') !== tabName;
    });
    if (tabName === 'index') void loadPageSettingsLocalIndex(false);
  }

  async function persistPageOptionsPatch(patch) {
    var previous = Object.assign({}, currentPageOptions());
    pageUiState.pageOptions = Object.assign({}, previous, patch);
    var nextOptions = Object.assign({}, pageUiState.pageOptions);
    applyPageOptionsToShell();
    renderPageSettingsPopover();
    try {
      var response = await fetch('/api/ui/preferences', {
        method: 'PUT',
        headers: { 'content-type': 'application/json' },
        body: JSON.stringify({
          documentId: currentDocumentId(),
          workspaceId: resolveWorkspaceId(document.body),
          ...currentWorkspaceSourcePayload(),
          updates: nextOptions
        })
      });
      var payload = await response.json().catch(function(){ return null; });
      if (!response.ok || !payload || payload.ok !== true) {
        throw new Error(payload && payload.error && payload.error.message ? payload.error.message : 'page_settings_save_failed_' + response.status);
      }
      var savedOptions = payload && payload.result && payload.result.pageOptions && typeof payload.result.pageOptions === 'object'
        ? Object.assign(defaultPageOptions(), payload.result.pageOptions)
        : nextOptions;
      pageUiState.pageOptions = Object.assign({}, savedOptions);
      nextOptions = Object.assign({}, pageUiState.pageOptions);
      applyPageOptionsToShell();
      renderPageSettingsPopover();
      var script = document.getElementById('__MNOTE_PAGE_AGGREGATE__');
      if (script) {
        try {
          var aggregate = JSON.parse(script.textContent || 'null');
          if (aggregate && typeof aggregate === 'object') {
            aggregate.layout = aggregate.layout && typeof aggregate.layout === 'object' ? aggregate.layout : {};
            aggregate.layout.pageOptions = Object.assign({}, nextOptions);
            aggregate.layout_options = Object.assign({}, nextOptions);
            script.textContent = JSON.stringify(aggregate);
            script.setAttribute('data-mnote-page-options-synced-at', String(Date.now()));
            script.setAttribute('data-mnote-page-options-local-write-at', String(Date.now()));
          }
        } catch (_) {}
      }
      document.documentElement.setAttribute('data-mnote-page-options-saved', 'true');
    } catch (error) {
      pageUiState.pageOptions = previous;
      applyPageOptionsToShell();
      renderPageSettingsPopover();
      document.documentElement.setAttribute('data-mnote-page-options-error', error instanceof Error ? error.message : String(error));
    }
  }

  function isPageSettingsOpen() {
    var popover = document.querySelector('[data-testid="wolai-page-settings-popover"]');
    return popover instanceof HTMLElement && !popover.hidden;
  }

  function openPageSettingsPopover() {
    if (!currentDocumentId()) return;
    var popover = ensurePageSettingsPopover();
    renderPageSettingsPopover();
    setActivePageSettingsTab('page');
    popover.hidden = false;
    pageUiState.pageSettingsOpen = true;
    updatePageSettingsTriggerState();
  }

  function closePageSettingsPopover() {
    var popover = document.querySelector('[data-testid="wolai-page-settings-popover"]');
    if (popover instanceof HTMLElement) popover.hidden = true;
    pageUiState.pageSettingsOpen = false;
    updatePageSettingsTriggerState();
  }

  function togglePageSettingsPopover() {
    if (isPageSettingsOpen()) closePageSettingsPopover();
    else openPageSettingsPopover();
  }

  return {
    applyPageOptionsToShell,
    closePageHistoryDrawer,
    closePageSettingsPopover,
    closePageShareDialog,
    currentPageOptions,
    ensureHistorySnapshotsSeeded,
    ensurePageHistoryDrawer,
    ensurePageSettingsPopover,
    ensurePageShareDialog,
    isPageSettingsOpen,
    openPageHistoryDrawer,
    openPageSettingsPopover,
    openPageShareDialog,
    pageOptionIsSupported,
    persistPageOptionsPatch,
    recordPageHistorySnapshot,
    renderPageSettingsPopover,
    setActivePageSettingsTab,
    togglePageSettingsPopover,
    updatePageSettingsTriggerState,
    writeGlobalShowHeadingNumbers,
  };
}
