import { featureTips } from './feature-tips.js';
import { initGestureNavigation } from './gesture-navigation.js';
import { setSyncedData, getDataSyncEnabled } from './data-sync.js';
import { 
  SearchEngineManager, 
  updateSearchEngineIcon,
  setSearchEngineIcon,
  createSearchEngineDropdown, 
  initializeSearchEngineDialog,
  getSearchUrl,
  createTemporarySearchTabs,
  getSearchEngineIconPath
} from './search-engine-dropdown.js';

let bookmarkTreeNodes = [];
let defaultSearchEngine = 'google';
let contextMenu = null;
let currentBookmark = null;

// 使用单一的状态变量
let itemToDelete = null;

// Define and initialize the variables
let bookmarkFolderContextMenu = null;
let currentBookmarkFolder = null;
let lastStorageWrite = 0;
let pendingWrite = null;
const STORAGE_WRITE_INTERVAL = 1000; // 1秒的节流间隔
// 在文件顶部添加导入语句
import { ICONS } from './icons.js';
import {
  chromeFaviconURL as bookmarkFaviconURL,
  applyFaviconWithFallback,
  isChromeInternalUrl,
  CHROME_BROWSER_ICON
} from './favicon-utils.js';
import {
  exportFolderAsHtml,
  pickAndImportBookmarkHtml
} from './bookmark-html-io.js';
import {
  isHostedAiProvider,
  canRunAiOrganize,
  loadAiOrganizeSettings,
  ensureAiHostPermission,
  runAiOrganizeFolder,
  getAiOrganizeErrorMessage,
  hasAiOrganizeSnapshot,
  loadAiOrganizeSnapshot,
  restoreAiOrganizeSnapshot,
  showAiOrganizeRestoreConfirm
} from './ai-bookmark-organize.js';
import {
  ensureScanHostPermission,
  findBrokenBookmarks,
  deleteBrokenBookmarks,
  showClear404Preview,
  showClear404Progress,
  getClear404ErrorMessage
} from './clear-404-bookmarks.js';
import {
  showAiRecommendDialog,
  getAiRecommendErrorMessage
} from './ai-bookmark-recommend.js';
import {
  showWebsiteIntroduceDialog
} from './ai-website-introduce.js';
import {
  PRO_FEATURES,
  requireProFeature,
  requireAiIntroduceFeature,
  refreshMembershipStatus,
  isFeatureEntitled,
  getCachedMembershipStatus,
  fetchProductCatalog,
  getClear404ScanSpeedMultiplier
} from './membership.js';

// 解决函数未定义错误，将这些函数提升到全局范围
// 创建二维码函数
function createQRCode(url, bookmarkName) {
  // 创建一个模态来显示二维码
  const modal = document.createElement('div');
  modal.style.position = 'fixed';
  modal.style.left = '0';
  modal.style.top = '0';
  modal.style.width = '100%';
  modal.style.height = '100%';
  modal.style.backgroundColor = 'rgba(0,0,0,0.5)';
  modal.style.display = 'flex';
  modal.style.justifyContent = 'center';
  modal.style.alignItems = 'center';
  modal.style.zIndex = '1000';

  const qrContainer = document.createElement('div');
  qrContainer.style.backgroundColor = 'white';
  qrContainer.style.padding = '1.5rem 3rem';
  qrContainer.style.width = '320px';
  qrContainer.style.borderRadius = '10px';
  qrContainer.style.display = 'flex';
  qrContainer.style.flexDirection = 'column';
  qrContainer.style.alignItems = 'center';
  qrContainer.style.position = 'relative';

  // 添加关闭按钮
  const closeButton = document.createElement('span');
  closeButton.textContent = '×';
  closeButton.style.position = 'absolute';
  closeButton.style.right = '10px';
  closeButton.style.top = '10px';
  closeButton.style.fontSize = '20px';
  closeButton.style.cursor = 'pointer';
  closeButton.onclick = () => document.body.removeChild(modal);
  qrContainer.appendChild(closeButton);

  // 添加标题
  const title = document.createElement('h2');
  title.textContent = getLocalizedMessage('scanQRCode');
  title.style.marginBottom = '20px';
  title.style.fontWeight = '600';
  title.style.fontSize = '0.875rem';
  qrContainer.appendChild(title);

  // 创建 QR 码容器
  const qrCodeElement = document.createElement('div');
  qrContainer.appendChild(qrCodeElement);

  // 添加 URL 显示
  const urlDisplay = document.createElement('div');
  urlDisplay.textContent = url;
  urlDisplay.style.marginTop = '20px';
  urlDisplay.style.wordBreak = 'break-all';
  urlDisplay.style.maxWidth = '300px';
  urlDisplay.style.textAlign = 'center';
  qrContainer.appendChild(urlDisplay);

  // 添加按钮容器
  const buttonContainer = document.createElement('div');
  buttonContainer.style.display = 'flex';
  buttonContainer.style.justifyContent = 'space-between';
  buttonContainer.style.width = '100%';
  buttonContainer.style.marginTop = '20px';

  // 添加复制按钮
  const copyButton = document.createElement('button');
  copyButton.textContent = getLocalizedMessage('copyLink');
  copyButton.onclick = () => {
    navigator.clipboard.writeText(url).then(() => {
      copyButton.textContent = getLocalizedMessage('copied');
      setTimeout(() => copyButton.textContent = getLocalizedMessage('copyLink'), 2000);
    });
  };

  // 添加下载按钮
  const downloadButton = document.createElement('button');
  downloadButton.textContent = getLocalizedMessage('download');
  downloadButton.onclick = () => {
    // 给 QRCode 生成一些时间
    setTimeout(() => {
      const canvas = qrCodeElement.querySelector('canvas');
      if (canvas) {
        const link = document.createElement('a');
        // 使用书签名称作为文件名，并添加 .png 扩展名
        const fileName = `${bookmarkName.replace(/[^a-z0-9]/gi, '_').toLowerCase()}_qrcode.png`;
        link.download = fileName;
        link.href = canvas.toDataURL('image/png');
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
      }
    }, 100); // 给予 100ms 的延迟，确保 QR 码已经生成
  };

  // 设置按钮样式和hover效果
  [copyButton, downloadButton].forEach(button => {
    button.style.padding = '5px 10px';
    button.style.border = 'none';
    button.style.borderRadius = '5px';
    button.style.cursor = 'pointer';
    button.style.backgroundColor = '#f0f0f0';
    button.style.color = '#333';
    button.style.transition = 'all 0.3s ease';

    // 添加hover效果
    button.addEventListener('mouseenter', () => {
      button.style.backgroundColor = '#e0e0e0';
      button.style.color = '#111827';
    });
    button.addEventListener('mouseleave', () => {
      button.style.backgroundColor = '#f0f0f0';
      button.style.color = '#717882';
    });
  });

  buttonContainer.appendChild(copyButton);
  buttonContainer.appendChild(downloadButton);
  qrContainer.appendChild(buttonContainer);

  modal.appendChild(qrContainer);
  document.body.appendChild(modal);

  // 使用 qrcode.js 库生成二维码
  new QRCode(qrCodeElement, {
    text: url,
    width: 200,
    height: 200
  });

  // 点击模态框外部关闭
  modal.addEventListener('click', function (event) {
    if (event.target === modal) {
      document.body.removeChild(modal);
    }
  });
}

const BOOKMARK_FAVICON_EAGER_COUNT = 24;
let bookmarkFaviconRenderIndex = 0;

function createBookmarkFaviconImg(pageUrl, { eager = false } = {}) {
  const img = document.createElement('img');
  img.className = 'w-6 h-6 mr-2 bookmark-favicon';
  img.alt = '';
  img.decoding = 'async';
  img.loading = eager ? 'eager' : 'lazy';
  if (eager) {
    img.fetchPriority = 'high';
  }
  // 外部图标优先：未访问过的网站也能显示，不必先点开链接
  applyFaviconWithFallback(img, pageUrl);
  return img;
}

function updateBookmarkCardColors(bookmarkCard, newUrl, img) {
  if (!bookmarkCard || !img) return;
  applyFaviconWithFallback(img, newUrl);
}

function updateSpecificBookmarkCard(bookmarkId, newTitle, newUrl) {
  const bookmarkCard = document.querySelector(`.bookmark-card[data-id="${bookmarkId}"]`);
  if (!bookmarkCard) {
    const parentId = document.getElementById('bookmarks-list')?.dataset.parentId;
    if (parentId) {
      bookmarksCache.clear();
      updateBookmarksDisplay(parentId);
    }
    return;
  }

  bookmarkCard.href = newUrl;
  const titleEl = bookmarkCard.querySelector('.card-title');
  if (titleEl) {
    titleEl.textContent = newTitle;
  }

  const img = bookmarkCard.querySelector('img');
  if (img) {
    updateBookmarkCardColors(bookmarkCard, newUrl, img);
  }

  // 清除缓存，避免后续刷新仍显示旧数据
  const parentId = bookmarkCard.dataset.parentId || document.getElementById('bookmarks-list')?.dataset.parentId;
  if (parentId) {
    bookmarksCache.delete(parentId);
  }
}

function openEditDialog(bookmark) {
  const bookmarkId = bookmark.id;
  const bookmarkTitle = bookmark.title;
  const bookmarkUrl = bookmark.url;

  document.getElementById('edit-name').value = bookmarkTitle;
  document.getElementById('edit-url').value = bookmarkUrl;

  const editDialog = document.getElementById('edit-dialog');
  const titleEl = editDialog.querySelector('h2');
  if (titleEl) {
    titleEl.textContent = getLocalizedMessage('editDialogTitle') || 'Edit';
  }
  editDialog.style.display = 'block';

  document.getElementById('edit-form').onsubmit = function (event) {
    event.preventDefault();
    const newTitle = document.getElementById('edit-name').value.trim();
    let newUrl = document.getElementById('edit-url').value.trim();
    if (!newTitle || !newUrl) return;

    if (!/^https?:\/\//i.test(newUrl) &&
        !newUrl.startsWith('chrome://') &&
        !newUrl.startsWith('chrome-extension://') &&
        !newUrl.startsWith('edge://') &&
        !newUrl.startsWith('about:')) {
      newUrl = 'https://' + newUrl;
    }

    chrome.bookmarks.update(bookmarkId, { title: newTitle, url: newUrl }, function () {
      if (chrome.runtime.lastError) {
        console.error('Error updating bookmark:', chrome.runtime.lastError);
        return;
      }

      editDialog.style.display = 'none';
      bookmarksCache.clear();
      updateSpecificBookmarkCard(bookmarkId, newTitle, newUrl);

      // 分组视图下再刷新一次，确保标题/图标同步
      const parentId = document.getElementById('bookmarks-list')?.dataset.parentId;
      if (parentId) {
        updateBookmarksDisplay(parentId);
      }
    });
  };

  const cancelButton = editDialog.querySelector('.cancel-button');
  const closeButton = editDialog.querySelector('.close-button');
  const closeDialog = () => { editDialog.style.display = 'none'; };
  if (cancelButton) cancelButton.onclick = closeDialog;
  if (closeButton) closeButton.onclick = closeDialog;
}

/** Duplicate a bookmark link, then open the edit dialog for the new copy. */
function duplicateBookmark(bookmark) {
  if (!bookmark?.id || bookmark.type === 'quickLink' || !bookmark.url) {
    return;
  }

  chrome.bookmarks.get(bookmark.id, (results) => {
    if (chrome.runtime.lastError) {
      console.error('Error reading bookmark for duplicate:', chrome.runtime.lastError);
      return;
    }

    const original = results?.[0];
    if (!original?.url || !original.parentId) {
      console.error('Cannot duplicate bookmark: missing url or parentId', original);
      return;
    }

    const createDetails = {
      parentId: original.parentId,
      title: original.title,
      url: original.url
    };
    if (typeof original.index === 'number') {
      createDetails.index = original.index + 1;
    }

    chrome.bookmarks.create(createDetails, (newBookmark) => {
      if (chrome.runtime.lastError) {
        console.error('Error duplicating bookmark:', chrome.runtime.lastError);
        return;
      }

      bookmarksCache.clear();
      const displayParentId =
        document.getElementById('bookmarks-list')?.dataset.parentId || original.parentId;
      updateBookmarksDisplay(displayParentId);
      openEditDialog(newBookmark);
    });
  });
}

function updateThemeIcon(isDark) {
  const themeToggleBtn = document.getElementById('theme-toggle-btn');
  if (!themeToggleBtn) return;

  themeToggleBtn.innerHTML = isDark ? ICONS.dark_mode : ICONS.light_mode;
}
import { replaceIconsWithSvg, getIconHtml } from './icons.js';

document.addEventListener('DOMContentLoaded', function () {
  // 应用保存的书签卡片高度设置
  chrome.storage.sync.get('bookmarkCardHeight', (result) => {
    const height = result.bookmarkCardHeight || 36;
    document.documentElement.style.setProperty('--bookmark-card-height', `${height}px`);

    let styleElement = document.getElementById('custom-card-height');
    if (!styleElement) {
      styleElement = document.createElement('style');
      styleElement.id = 'custom-card-height';
      document.head.appendChild(styleElement);
    }

    styleElement.textContent = `
      .card,
      .bookmark-add-card,
      .bookmark-tree-action-btn {
        height: ${height}px !important;
      }
    `;
  });

  // 初始化手势导航，传入 updateBookmarksDisplay 函数
  initGestureNavigation(updateBookmarksDisplay);
  refreshMembershipStatus().catch((error) => {
    console.warn('Membership refresh failed:', error);
  });
   // 初始化功能提示
  featureTips.initAllTips();
  // 替换所有图标
  replaceIconsWithSvg();

  // 或者在动态创建元素时使用
  const button = document.createElement('button');
  button.innerHTML = getIconHtml('settings') + ' Settings';

  // 更新这部分代码
  updateSearchEngineIcon(defaultSearchEngine);

  const searchEngineIcon = document.getElementById('search-engine-icon');
  if (searchEngineIcon && searchEngineIcon.src === '') {      
    searchEngineIcon.src = '../images/placeholder-icon.svg';
  }
});

function getLocalizedMessage(messageName) {
  const message = chrome.i18n.getMessage(messageName);
  return message || messageName;
}

/** Escape text for safe insertion into HTML / attributes. */
function escapeHtml(text) {
  return String(text ?? '')
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&#39;');
}

/** 在用户手势中请求可选 tabGroups 权限（后台无法弹权限框） */
function ensureTabGroupsPermission() {
  return new Promise((resolve) => {
    if (!chrome.permissions?.contains || !chrome.permissions?.request) {
      resolve(false);
      return;
    }
    chrome.permissions.contains({ permissions: ['tabGroups'] }, (has) => {
      if (chrome.runtime.lastError) {
        resolve(false);
        return;
      }
      if (has) {
        resolve(true);
        return;
      }
      chrome.permissions.request({ permissions: ['tabGroups'] }, (granted) => {
        resolve(Boolean(granted) && !chrome.runtime.lastError);
      });
    });
  });
}

function openMultipleTabsAndGroup(urls, groupName) {
  return ensureTabGroupsPermission().then(() => new Promise((resolve) => {
    chrome.runtime.sendMessage({
      action: 'openMultipleTabsAndGroup',
      urls,
      groupName
    }, (response) => {
      resolve(response || { success: false, error: 'No response' });
    });
  }));
}

// Define the context menu creation function
function createContextMenu() {
  console.log('Creating context menu');
  
  // 移除任何已存在的上下文菜单
  const existingMenu = document.querySelector('.custom-context-menu');
  if (existingMenu) {
    existingMenu.remove();
  }

  const menu = document.createElement('div');
  menu.className = 'custom-context-menu';
  document.body.appendChild(menu);

  const menuItems = [
    { text: getLocalizedMessage('openInNewTab'), icon: 'open_in_new', action: () => currentBookmark && window.open(currentBookmark.url, '_blank') },
    { text: getLocalizedMessage('openInNewWindow'), icon: 'launch', action: () => currentBookmark && openInNewWindow(currentBookmark.url) },
    { text: getLocalizedMessage('openInIncognito'), icon: 'visibility_off', action: () => currentBookmark && openInIncognito(currentBookmark.url) },
    { text: getLocalizedMessage('editQuickLink'), icon: 'edit', action: () => currentBookmark && openEditDialog(currentBookmark) },
    { text: getLocalizedMessage('aiIntroduceWebsite'), icon: 'auto_awesome', actionKey: 'aiIntroduceWebsite', action: () => currentBookmark && introduceWebsiteWithAi(currentBookmark) },
    { text: getLocalizedMessage('duplicateBookmark'), icon: 'file_copy', actionKey: 'duplicateBookmark', action: () => currentBookmark && duplicateBookmark(currentBookmark) },
    { 
      text: getLocalizedMessage('deleteQuickLink'), 
      icon: 'delete', 
      action: () => {
        console.log('Delete action triggered. Current item:', currentBookmark);
        
        if (!currentBookmark) {
          console.error('No item selected for deletion');
          return;
        }

        itemToDelete = {
          type: currentBookmark.type,
          data: {
            id: currentBookmark.id,
            title: currentBookmark.title,
            url: currentBookmark.url
          }
        };
        
        console.log('Set itemToDelete:', itemToDelete);
        
        const message = itemToDelete.type === 'quickLink' 
          ? chrome.i18n.getMessage("confirmDeleteQuickLink", [`<strong>${itemToDelete.data.title}</strong>`])
          : chrome.i18n.getMessage("confirmDeleteBookmark", [`<strong>${itemToDelete.data.title}</strong>`]);
        
        showConfirmDialog(message, () => {
          if (itemToDelete && itemToDelete.data) {
            if (itemToDelete.type === 'quickLink') {
              deleteQuickLink(itemToDelete.data);
            } else {
              deleteBookmark(itemToDelete.data.id, itemToDelete.data.title);
            }
          }
        });
      }
    },
    { text: getLocalizedMessage('copyLink'), icon: 'content_copy', action: () => currentBookmark && Utilities.copyBookmarkLink(currentBookmark) },
    { text: getLocalizedMessage('createQRCode'), icon: 'qr_code', action: () => currentBookmark && createQRCode(currentBookmark.url, currentBookmark.title) }
  ];

  menuItems.forEach((item, index) => {
    // 在特定位置添加分隔线
    if (index === 3 || index === 7) {
      const divider = document.createElement('div');
      divider.className = 'custom-context-menu-divider';
      menu.appendChild(divider);
    }
    
    const menuItem = document.createElement('div');
    menuItem.className = 'custom-context-menu-item';
    if (item.actionKey) {
      menuItem.dataset.action = item.actionKey;
    }
    
    const icon = document.createElement('span');
    icon.className = 'material-icons';
    icon.innerHTML = ICONS[item.icon];
    icon.style.marginRight = '8px';
    icon.style.fontSize = '18px';
    
    const text = document.createElement('span');
    text.textContent = item.text;

    menuItem.appendChild(icon);
    menuItem.appendChild(text);

    menuItem.addEventListener('click', () => {
      if (typeof item.action === 'function') {
        item.action();
      }
      menu.style.display = 'none';
    });

    menu.appendChild(menuItem);
  });

  return menu;
}

// 在文件顶部添加这个函数
function applyBackgroundColor() {
    if (typeof window.applyThemeAccentFromStorage === 'function') {
      window.applyThemeAccentFromStorage();
    }
    if (typeof window.applyPageBackgroundFromStorage === 'function') {
      window.applyPageBackgroundFromStorage();
      return;
    }

    const savedBg = localStorage.getItem('selectedBackground');
    if (savedBg) {
        const useDefaultBackground = localStorage.getItem('useDefaultBackground');
        
        if (useDefaultBackground !== 'true') {
            document.querySelectorAll('.settings-bg-option, .settings-custom-bg-option').forEach(option => {
                option.classList.remove('active');
            });
            return;
        }
        
        document.documentElement.className = savedBg;
        
        const welcomeElement = document.getElementById('welcome-message');
        if (welcomeElement && window.WelcomeManager) {
            window.WelcomeManager.adjustTextColor(welcomeElement);
        }
    }
}

// 立即调用这个函数
applyBackgroundColor();

// 从 storage 同步背景色 / 自定义主题色偏好（壁纸仍仅存本地）
chrome.storage.sync.get(
  [
    'selectedBackground',
    'useDefaultBackground',
    'theme',
    'customThemeColor',
    'customBackgroundColor',
    'themeAccentMode',
    'themeAccentBackground'
  ],
  (result) => {
  getDataSyncEnabled().then((enabled) => {
    if (!enabled) {
      if (typeof window.restoreThemeAccentFromChromeStorage === 'function') {
        window.restoreThemeAccentFromChromeStorage();
      }
      return;
    }

    if (result.theme) {
      localStorage.setItem('theme', result.theme);
      if (result.theme === 'auto') {
        const isDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
        document.documentElement.setAttribute('data-theme', isDark ? 'dark' : 'light');
      } else {
        document.documentElement.setAttribute('data-theme', result.theme);
      }
      if (typeof updateThemeIcon === 'function') {
        updateThemeIcon(document.documentElement.getAttribute('data-theme') === 'dark');
      }
    }

    if (result.customThemeColor) {
      localStorage.setItem('customThemeColor', result.customThemeColor);
    }
    if (result.customBackgroundColor) {
      localStorage.setItem('customBackgroundColor', result.customBackgroundColor);
    }
    if (result.themeAccentMode) {
      localStorage.setItem('themeAccentMode', result.themeAccentMode);
    }
    if (result.themeAccentBackground) {
      localStorage.setItem('themeAccentBackground', result.themeAccentBackground);
    }

    if (result.selectedBackground) {
      localStorage.setItem('selectedBackground', result.selectedBackground);
    }
    if (result.useDefaultBackground != null) {
      const hasWallpaper = !!localStorage.getItem('originalWallpaper');
      if (hasWallpaper) {
        // Keep wallpaper mode; do not revive stale solid-bg sync flag
        localStorage.setItem('useDefaultBackground', 'false');
        if (typeof window.persistThemePreference === 'function') {
          window.persistThemePreference({ useDefaultBackground: false });
        }
      } else if (result.useDefaultBackground === true || result.useDefaultBackground === 'true') {
        localStorage.setItem('useDefaultBackground', 'true');
      } else {
        localStorage.setItem('useDefaultBackground', 'false');
      }
    }

    if (typeof window.applyThemeAccentFromStorage === 'function') {
      window.applyThemeAccentFromStorage();
    }
    if (typeof window.applyPageBackgroundFromStorage === 'function') {
      window.applyPageBackgroundFromStorage();
    }
  });
});

chrome.storage.onChanged.addListener((changes, area) => {
  if (area !== 'sync') return;
  getDataSyncEnabled().then((enabled) => {
    if (!enabled) return;
    if (
      changes.selectedBackground ||
      changes.useDefaultBackground ||
      changes.customThemeColor ||
      changes.customBackgroundColor ||
      changes.themeAccentMode ||
      changes.themeAccentBackground
    ) {
      const bg = changes.selectedBackground?.newValue ?? localStorage.getItem('selectedBackground');
      const useDefault = changes.useDefaultBackground?.newValue ?? (localStorage.getItem('useDefaultBackground') === 'true');
      const customColor = changes.customThemeColor?.newValue ?? localStorage.getItem('customThemeColor');
      const customBgColor = changes.customBackgroundColor?.newValue ?? localStorage.getItem('customBackgroundColor');
      const accentMode = changes.themeAccentMode?.newValue ?? localStorage.getItem('themeAccentMode');
      const accentKey = changes.themeAccentBackground?.newValue ?? localStorage.getItem('themeAccentBackground');
      if (bg) localStorage.setItem('selectedBackground', bg);
      if (customColor) localStorage.setItem('customThemeColor', customColor);
      if (customBgColor) localStorage.setItem('customBackgroundColor', customBgColor);
      if (accentMode) localStorage.setItem('themeAccentMode', accentMode);
      if (accentKey) localStorage.setItem('themeAccentBackground', accentKey);
      if (changes.useDefaultBackground) {
        if (localStorage.getItem('originalWallpaper') && !useDefault) {
          localStorage.setItem('useDefaultBackground', 'false');
        } else if (useDefault) {
          localStorage.setItem('useDefaultBackground', 'true');
        } else {
          localStorage.setItem('useDefaultBackground', 'false');
        }
      }

      if (accentMode === 'custom' && customColor && typeof window.applyCustomThemeAccent === 'function') {
        window.applyCustomThemeAccent(customColor, { applyBackground: false, persist: false });
      } else if (accentKey && typeof window.applyThemeAccent === 'function') {
        window.applyThemeAccent(accentKey, { persist: false });
      }

      const hasWallpaper = !!localStorage.getItem('originalWallpaper');
      if (useDefault && bg && !hasWallpaper) {
        if (bg === (window.CUSTOM_THEME_BG_CLASS || 'custom-theme-background')) {
          const hex = customBgColor || customColor || '#4A9FE8';
          if (typeof window.applyCustomPageBackground === 'function') {
            window.applyCustomPageBackground(hex, { persist: false, clearWallpaper: false });
          }
        } else if (typeof window.applyPageBackground === 'function') {
          window.applyPageBackground(bg, { persist: false, clearWallpaper: false });
        } else {
          document.documentElement.className = bg;
        }
      }
    }
  });
});

// 添加颜色缓存管理器
const ColorCache = {
  data: new Map(),
  maxSize: 2000, // 最多缓存500个书签的颜色
  maxAge: 7 * 24 * 60 * 60 * 1000, // 7天过期
  storageKey: 'bookmark-colors-v2', // 新的存储键，避免与旧数据冲突

  // 初始化缓存
  init() {
    try {
      // 从 localStorage 加载缓存数据
      const cached = localStorage.getItem(this.storageKey);
      if (cached) {
        const parsedData = JSON.parse(cached);
        Object.entries(parsedData).forEach(([key, value]) => {
          if (Date.now() - value.timestamp < this.maxAge) {
            this.data.set(key, value);
          }
        });
      }
    } catch (error) {
      console.error('Error initializing color cache:', error);
      this.clear();
    }
  },

  // 获取颜色
  get(bookmarkId, url) {
    const cached = this.data.get(bookmarkId);
    if (!cached) return null;

    // 检查URL是否变化和过期时间
    if (cached.url !== url || Date.now() - cached.timestamp > this.maxAge) {
      this.data.delete(bookmarkId);
      return null;
    }

    return cached.colors;
  },

  // 设置颜色
  set(bookmarkId, url, colors) {
    // 如果缓存即将超出限制，清理旧数据
    if (this.data.size >= this.maxSize) {
      this.cleanup();
    }

    this.data.set(bookmarkId, {
      colors,
      url,
      timestamp: Date.now()
    });

    // 异步保存到 localStorage
    this.scheduleSave();
  },

  // 清理过期和多余的缓存
  cleanup() {
    const now = Date.now();
    const entries = Array.from(this.data.entries());

    // 删除过期项
    entries.forEach(([key, value]) => {
      if (now - value.timestamp > this.maxAge) {
        this.data.delete(key);
      }
    });

    // 如果仍然超出限制，删除最旧的项
    if (this.data.size >= this.maxSize) {
      const sortedEntries = Array.from(this.data.entries())
        .sort((a, b) => a[1].timestamp - b[1].timestamp);

      const deleteCount = Math.floor(this.data.size * 0.2);
      sortedEntries.slice(0, deleteCount).forEach(([key]) => {
        this.data.delete(key);
      });
    }
  },

  // 清除所有缓存
  clear() {
    this.data.clear();
    localStorage.removeItem(this.storageKey);
  },

  // 使用防抖保存到 localStorage
  scheduleSave: _.debounce(function () {
    try {
      const dataToSave = Object.fromEntries(this.data);
      localStorage.setItem(this.storageKey, JSON.stringify(dataToSave));
    } catch (error) {
      // 如果存储失败（比如超出配额），清理一半的缓存后重试
      const entries = Array.from(this.data.entries());
      entries.slice(0, Math.floor(entries.length / 2)).forEach(([key]) => {
        this.data.delete(key);
      });
      this.scheduleSave();
    }
  }, 1000)
};



// 页面加载时更新图标
document.addEventListener('DOMContentLoaded', () => {
  const defaultEngine = SearchEngineManager.getDefaultEngine();
  if (defaultEngine) {
    updateSearchEngineIcon(defaultEngine);
  }
});

// 同样，将这个函数也移到全作用域
function setDefaultIcon(iconElement) {
  iconElement.src = '../images/default-search-icon.png';
  iconElement.alt = 'Default Search Engine';
}

// 1. 首先定义全局变量
let bookmarksList;
let itemHeight = 120;
let bufferSize = 5;
let visibleItems;
let allBookmarks = [];
let renderTimeout = null;
let scrollHandler = null;
let resizeObserver = null;

// 2. 定义主要的虚拟滚动函数
function initVirtualScroll() {
  bookmarksList = document.getElementById('bookmarks-list');
  if (!bookmarksList) return;
  
  visibleItems = Math.ceil(window.innerHeight / itemHeight) + 2 * bufferSize;

  // 渲染函数
  function renderVisibleBookmarks() {
    if (!bookmarksList) return;
    // ... 保持原有的 renderVisibleBookmarks 实现 ...
  }

  // 滚动处理函数
  const handleScroll = _.throttle(() => {
    if (renderTimeout) {
      cancelAnimationFrame(renderTimeout);
    }
    renderTimeout = requestAnimationFrame(renderVisibleBookmarks);
  }, 16);

  // 窗口大小变化处理函数
  function handleResize() {
    const newVisibleItems = Math.ceil(window.innerHeight / itemHeight) + 2 * bufferSize;
    if (newVisibleItems !== visibleItems) {
      visibleItems = newVisibleItems;
      renderVisibleBookmarks();
    }
  }

  // 清理函数
  function cleanup() {
    if (scrollHandler) {
      bookmarksList.removeEventListener('scroll', scrollHandler);
    }
    if (resizeObserver) {
      resizeObserver.disconnect();
    }
    if (renderTimeout) {
      cancelAnimationFrame(renderTimeout);
    }
    allBookmarks = [];
  }

  // 初始化事件监听
  function initializeListeners() {
    cleanup(); // 清理旧的监听器

    scrollHandler = handleScroll;
    bookmarksList.addEventListener('scroll', scrollHandler, { passive: true });

    // 确保 handleResize 在正确的作用域内
    const boundHandleResize = handleResize.bind(this);
    resizeObserver = new ResizeObserver(_.debounce(boundHandleResize, 100));
    resizeObserver.observe(bookmarksList);
  }

  // 更新书签显示
  window.updateBookmarksDisplay = function(parentId, movedItemId, newIndex) {
    return new Promise((resolve, reject) => {
      chrome.bookmarks.getSubTree(parentId, (results) => {
        if (chrome.runtime.lastError) {
          reject(chrome.runtime.lastError);
          return;
        }

        const node = results && results[0];
        if (!node) {
          reject(new Error('Folder not found'));
          return;
        }

        cleanup();
        bookmarksCache.set(parentId, node.children || []);
        displayBookmarks(node);

        if (movedItemId) {
          highlightBookmark(movedItemId);
        }

        updateFolderName(parentId);
        bookmarksList.dataset.parentId = parentId;
        initializeListeners();

        resolve();
      });
    });
  };

  // 初始化
  initializeListeners();
}

// 3. 合并 DOMContentLoaded 事件监听器
document.addEventListener('DOMContentLoaded', function() {
  // 初始化虚拟滚动
  initVirtualScroll();
  
  // 初始化滚动指示器
  initScrollIndicator();
  
  // 其他初始化代码...
  startPeriodicSync();
  setupSpecialLinks();
  initLinksIconsOrder();
  console.log('[Init] Starting initialization...');

  // 只调用一次搜索引擎初始化
  createSearchEngineDropdown();
  initializeSearchEngineDialog();

 

  // Accent + page background restore (wallpaper applied by wallpaper.js)
  if (typeof window.applyThemeAccentFromStorage === 'function') {
    window.applyThemeAccentFromStorage();
  }
  if (typeof window.applyPageBackgroundFromStorage === 'function') {
    window.applyPageBackgroundFromStorage();
  }

  const hasWallpaper = localStorage.getItem('originalWallpaper');
  if (hasWallpaper) {
    const wallpaperOption = document.querySelector(`.wallpaper-option[data-wallpaper-url="${hasWallpaper}"]`);
    if (wallpaperOption) {
      wallpaperOption.classList.add('active');
    }
  }

  // Background / accent clicks are handled in settings.js

  // 监听主题变化
  const observer = new MutationObserver((mutations) => {
    mutations.forEach((mutation) => {
      if (mutation.attributeName === 'class') {
        // 当背景类发生变化时，调整文字颜色
        requestAnimationFrame(() => {
          const welcomeElement = document.getElementById('welcome-message');
          if (welcomeElement && window.WelcomeManager) {
            window.WelcomeManager.adjustTextColor(welcomeElement);
          }
        });
      }
    });
  });

  // 开始观察 documentElement 的 class 变化
  observer.observe(document.documentElement, {
    attributes: true,
    attributeFilter: ['class']
  });

  // 初始化快捷链接显示状态
  chrome.storage.sync.get(['enableQuickLinks'], function(result) {
    const quickLinksWrapper = document.querySelector('.recently-visited-links-wrapper');
    if (quickLinksWrapper) {
      quickLinksWrapper.style.display = result.enableQuickLinks !== false ? 'flex' : 'none';
    }
  });

  // 应用保存的书签宽度设置
  chrome.storage.sync.get(['bookmarkWidth'], (result) => {
    applyBookmarkGridWidth(result.bookmarkWidth || 150);
  });

  // 初始化预览/编辑模式切换
  initBookmarksModeToggle();

  // 应用保存的书签容器宽度设置
  chrome.storage.sync.get(['bookmarkContainerWidth'], (result) => {
    const savedWidth = result.bookmarkContainerWidth || 100; // 默认100%
    const bookmarksContainer = document.querySelector('.bookmarks-container');
    if (bookmarksContainer) {
      bookmarksContainer.style.width = `${savedWidth}%`;
    }
  });

  // 应用保存的界面元素显示设置
  chrome.storage.sync.get(
    [
      'showSearchBox', 
      'showWelcomeMessage', 
      'showFooter',
      'showHistoryLink',
      'showDownloadsLink',
      'showPasswordsLink',
      'showExtensionsLink',
      'showChromeWebStoreLink',
      'showCustomizeChromeLink'
    ], 
    (result) => {
      // 应用搜索框显示设置 - 修改为默认隐藏
      const searchContainer = document.querySelector('.search-container');
      if (searchContainer) {
        searchContainer.style.display = result.showSearchBox !== false ? '' : 'none';
      }
      
      // 欢迎语显示由 WelcomeManager 处理（需登录 + showWelcomeMessage）
      if (window.WelcomeManager) {
        window.WelcomeManager.updateWelcomeMessage();
      }
      
      // 应用页脚显示设置
      const footer = document.querySelector('footer');
      if (footer) {
        footer.style.display = result.showFooter !== false ? '' : 'none';
      }
      
      // 应用快捷链接图标显示设置
      const toggleElementVisibility = (selector, isVisible) => {
        const element = document.querySelector(selector);
        if (element) {
          element.style.display = isVisible ? '' : 'none';
        }
      };
      
      toggleElementVisibility('#history-link', result.showHistoryLink !== false);
      toggleElementVisibility('#downloads-link', result.showDownloadsLink !== false);
      toggleElementVisibility('#passwords-link', result.showPasswordsLink !== false);
      toggleElementVisibility('#extensions-link', result.showExtensionsLink !== false);
      toggleElementVisibility('#chrome-web-store-link', result.showChromeWebStoreLink !== false);
      toggleElementVisibility('#customize-chrome-link', result.showCustomizeChromeLink !== false);
      
      const linksContainer = document.querySelector('.chrome-quick-icons');
      if (linksContainer) {
        const allLinksHidden = 
          result.showHistoryLink === false && 
          result.showDownloadsLink === false && 
          result.showPasswordsLink === false && 
          result.showExtensionsLink === false &&
          result.showChromeWebStoreLink === false &&
          result.showCustomizeChromeLink === false;
        
        linksContainer.style.display = allLinksHidden ? 'none' : '';
      }
    }
  );
});

// 修改书签缓存对象的定义
const bookmarksCache = {
  data: new Map(),
  maxSize: 100, // 最大缓存条目数
  maxAge: 5 * 60 * 1000, // 5分钟缓存

  set(parentId, bookmarks) {
    // 如果缓存即将超出限制，清理最旧的数据
    if (this.data.size >= this.maxSize) {
      this.cleanup();
    }

    this.data.set(parentId, {
      timestamp: Date.now(),
      bookmarks: bookmarks
    });
  },

  get(parentId) {
    const cached = this.data.get(parentId);
    if (!cached) return null;

    if (Date.now() - cached.timestamp > this.maxAge) {
      this.data.delete(parentId);
      return null;
    }

    return cached;
  },

  // 添加 delete 方法
  delete(parentId) {
    return this.data.delete(parentId);
  },

  // 添加清除方法
  clear() {
    this.data.clear();
  },

  // 清理过期和最少使用缓存
  cleanup() {
    const now = Date.now();
    const entries = Array.from(this.data.entries());

    // 按最后访问时间排序
    entries.sort((a, b) => a[1].timestamp - b[1].timestamp);

    // 删除最旧的 20% 缓存
    const deleteCount = Math.floor(entries.length * 0.2);
    entries.slice(0, deleteCount).forEach(([key]) => {
      this.data.delete(key);
    });
  }
};

function updateBookmarkCards() {
  const bookmarksList = document.getElementById('bookmarks-list');
  const defaultBookmarkId = localStorage.getItem('defaultBookmarkId');
  const parentId = defaultBookmarkId || bookmarksList.dataset.parentId || '1';

  chrome.bookmarks.getSubTree(parentId, function (results) {
    const node = results && results[0];
    if (node) {
      displayBookmarks(node);
    }

    // 在显示书签后更新默认书签指示器
    updateDefaultBookmarkIndicator();
    updateSidebarDefaultBookmarkIndicator();

    // 更新 bookmarks-list 的 data-parent-id
    bookmarksList.dataset.parentId = parentId;
  });
}

document.addEventListener('DOMContentLoaded', function () {
  // Create context menu immediately when the document loads
  contextMenu = createContextMenu();
  
  const searchEngineIcon = document.getElementById('search-engine-icon');
  const defaultSearchEngine = localStorage.getItem('selectedSearchEngine') || 'google';
  console.log('[Init] Default search engine:', localStorage.getItem('selectedSearchEngine'));
  let deletedBookmark = null;
  let deletedCategory = null; // 添加这行
  let deleteTimeout = null;
  let bookmarkTreeNodes = []; // 定义全局变量
  // 调用 updateBookmarkCards
  updateBookmarkCards();
  
  updateSearchEngineIcon(defaultSearchEngine);

  if (searchEngineIcon.src === '') {      
    searchEngineIcon.src = '../images/placeholder-icon.svg';
  }
  setTimeout(() => {
    updateSearchEngineIcon(defaultSearchEngine);
  }, 0);

  // 修改 updateSearchEngineIcon 函数
  function updateSearchEngineIcon(engineName) {
    setSearchEngineIcon(engineName);
  }

  // 更新侧边栏默认书签指示器和选中状态
  updateSidebarDefaultBookmarkIndicator();

  // ... 其他代码 ...

  


  
  // 优化后的更新显示函数
  async function updateBookmarksDisplay(parentId) {
    const bookmarksContainer = document.querySelector('.bookmarks-container');
    
    // 添加加载状态
    bookmarksContainer.classList.add('loading');
    
    try {
      const cached = bookmarksCache.get(parentId);
      
      if (cached && !movedItemId) {
        // 使用缓存数据进行分页显示
        renderBookmarksPage(cached, 0);
        return;
      }

      chrome.bookmarks.getChildren(parentId, (bookmarks) => {
        if (chrome.runtime.lastError) {
          throw chrome.runtime.lastError;
        }
        
        // 缓存新数据
        bookmarksCache.set(parentId, bookmarks);
        
        // 初始渲染第一页
        renderBookmarksPage({ bookmarks, totalCount: bookmarks.length }, 0);
      });
    } finally {
      // 移除加载状态
      bookmarksContainer.classList.remove('loading');
    }
  }

  // 分页渲染函数
  function renderBookmarksPage(cachedData, pageIndex, pageSize = 100) {
    const startIndex = pageIndex * pageSize;
    const endIndex = Math.min(startIndex + pageSize, cachedData.totalCount);
    
    const bookmarksList = document.getElementById('bookmarks-list');
    const bookmarksContainer = document.querySelector('.bookmarks-container');
    
    // 使用 DocumentFragment 优化 DOM 操作
    const fragment = document.createDocumentFragment();
    
    // 获取当前页的书签
    const pageBookmarks = cachedData.bookmarks.slice(startIndex, endIndex);
    
    // 渲染书签
    pageBookmarks.forEach((bookmark, index) => {
      const bookmarkElement = bookmark.url ? 
        createBookmarkCard(bookmark, startIndex + index) : 
        createFolderCard(bookmark, startIndex + index);
      fragment.appendChild(bookmarkElement);
    });
    
    // 更新 DOM
    bookmarksList.innerHTML = '';
    bookmarksList.appendChild(fragment);
    
    // 更新分页信息
    updatePagination(pageIndex, Math.ceil(cachedData.totalCount / pageSize));
  }

  // 添加分页控制
  function updatePagination(currentPage, totalPages) {
    // 实现分页控制UI
    // ...
  }

  // 化书顺序步
  function syncBookmarkOrder(parentId) {
    const cached = bookmarksCache.get(parentId);
    if (!cached) return;
    
    chrome.bookmarks.getChildren(parentId, (bookmarks) => {
      const chromeOrder = bookmarks.map(b => b.id);
      const cachedOrder = cached.bookmarks.map(b => b.id);
      
      if (JSON.stringify(chromeOrder) !== JSON.stringify(cachedOrder)) {
        // 更新缓存
        bookmarksCache.set(parentId, bookmarks);
        
        // 重新渲染当前页
        renderBookmarksPage({ bookmarks, totalCount: bookmarks.length }, 0);
      }
    });
  }

  // 修改右键菜单事件监听器
  document.addEventListener('contextmenu', async function (event) {
    const targetFolder = event.target.closest('.bookmark-folder');
    
    if (targetFolder) {
      event.preventDefault();
      event.stopPropagation(); // 阻止事件冒泡
      
      // 确保文件夹上下文菜单存在
      if (!bookmarkFolderContextMenu) {
        bookmarkFolderContextMenu = createBookmarkFolderContextMenu();
      }

      if (!bookmarkFolderContextMenu) {
        console.error('Failed to create bookmark folder context menu');
        return;
      }

      // 更新当前文件夹
      const oldFolder = currentBookmarkFolder;
      currentBookmarkFolder = targetFolder;
      
      // 重新创建菜单项
      await createMenuItems(bookmarkFolderContextMenu);
      
      // 先显示菜单但设为不可见，以便获取其尺寸
      bookmarkFolderContextMenu.style.display = 'block';
      bookmarkFolderContextMenu.style.visibility = 'hidden';
      bookmarkFolderContextMenu.style.left = '0';
      bookmarkFolderContextMenu.style.top = '0';
      
      // 获取视窗尺寸
      const viewportWidth = window.innerWidth;
      const viewportHeight = window.innerHeight;
      
      // 等待一下以确保菜单已渲染
      setTimeout(() => {
        const menuRect = bookmarkFolderContextMenu.getBoundingClientRect();
        
        // 计算最佳位置
        let left = event.clientX;
        let top = event.clientY;
        
        // 检查右侧空间
        if (left + menuRect.width > viewportWidth) {
          // 如果右侧空间不足，尝试将菜单放在点击位置的左侧
          left = Math.max(5, left - menuRect.width);
        }
        
        // 检查底部空间
        if (top + menuRect.height > viewportHeight) {
          // 如果底部空间不足，尝试将菜单放在点击位置的上方
          top = Math.max(5, viewportHeight - menuRect.height - 5);
        }
        
        // 应用计算后的位置
        bookmarkFolderContextMenu.style.left = `${left}px`;
        bookmarkFolderContextMenu.style.top = `${top}px`;
        
        // 使菜单可见
        bookmarkFolderContextMenu.style.visibility = 'visible';
      }, 0);

      // 隐藏其他上下文菜单
      if (contextMenu) {
        contextMenu.style.display = 'none';
      }
    }
  });

  // 修改文档点击事件，确保正确关闭菜单
  document.addEventListener('click', function(event) {
    // 如果点击的不是菜单本身，则关闭菜单
    if (bookmarkFolderContextMenu && 
        !bookmarkFolderContextMenu.contains(event.target) && 
        !event.target.closest('.bookmark-folder')) {
      bookmarkFolderContextMenu.style.display = 'none';
      currentBookmarkFolder = null; // 重置当前文件夹
    }
  });

  // 为菜单本身添加点击事件处理
  if (bookmarkFolderContextMenu) {
    bookmarkFolderContextMenu.addEventListener('click', function(event) {
      event.stopPropagation(); // 阻止事件冒泡到文档
    });
  }

  // 在点击其他地方时重置状态
  document.addEventListener('click', function () {
    // 延迟处理点击事件，让菜单项的点击事件先执行
    setTimeout(() => {
    if (contextMenu) {
      contextMenu.style.display = 'none';
        currentBookmark = null;
      }
      
      if (bookmarkFolderContextMenu) {
        bookmarkFolderContextMenu.style.display = 'none';
        currentBookmarkFolder = null;
      }
    }, 200);
  });
});

function showMovingFeedback(element) {
  element.style.opacity = '0.5';
}

function hideMovingFeedback(element) {
  element.style.opacity = '1';
}

function showSuccessFeedback(element) {
  element.style.backgroundColor = '#e6ffe6';
  setTimeout(() => {
    element.style.backgroundColor = '';
  }, 1000);
}

function showErrorFeedback(element) {
  element.style.backgroundColor = '#ffe6e6';
  setTimeout(() => {
    element.style.backgroundColor = '';
  }, 1000);
}

function openCategory(category) {
  if (category && category.classList.contains('folder-item')) {
    document.querySelectorAll('#categories-list li').forEach(function (item) {
      item.classList.remove('bg-emerald-500');
    });
    category.classList.add('bg-emerald-500');

    if (category.dataset.id) {
      updateBookmarksDisplay(category.dataset.id);
    }
  }
}

async function isFolderUnderRoot(folderId, rootId) {
  if (!folderId || !rootId) return false;
  if (folderId === rootId) return true;

  let currentId = folderId;
  while (currentId && currentId !== '0') {
    if (currentId === rootId) {
      return true;
    }
    try {
      const results = await chrome.bookmarks.get(currentId);
      const node = results && results[0];
      if (!node || !node.parentId || node.parentId === '0') {
        return false;
      }
      currentId = node.parentId;
    } catch (error) {
      return false;
    }
  }
  return false;
}

async function getBookmarkRootId(folderId) {
  if (!folderId) return null;

  let currentId = folderId;
  while (currentId && currentId !== '0') {
    try {
      const results = await chrome.bookmarks.get(currentId);
      const node = results && results[0];
      if (!node) return null;
      if (!node.parentId || node.parentId === '0') {
        return node.id;
      }
      currentId = node.parentId;
    } catch (error) {
      console.log('Unable to resolve bookmark root:', error);
      return null;
    }
  }

  return null;
}

async function getFirstExistingDefaultFolder() {
  const { defaultFolders } = await chrome.storage.sync.get('defaultFolders');
  const folders = (defaultFolders?.items || []).slice().sort((a, b) => a.order - b.order);

  for (const folder of folders) {
    try {
      const results = await chrome.bookmarks.get(folder.id);
      if (results && results.length > 0) {
        return folder.id;
      }
    } catch (error) {
      console.log('Default folder no longer exists:', error);
    }
  }

  return null;
}

function revealSidebarFolder(folderId) {
  const folder = document.querySelector(`#categories-list li[data-id="${folderId}"]`);
  if (!folder) return;

  let parent = folder.parentElement;
  while (parent && parent.id !== 'categories-list') {
    if (parent.tagName === 'UL') {
      parent.style.display = 'block';
      const parentFolder = parent.previousElementSibling;
      const arrowIcon = parentFolder?.querySelector('.folder-expand-toggle');
      if (arrowIcon) {
        arrowIcon.innerHTML = ICONS.expand_less;
        arrowIcon.setAttribute('aria-expanded', 'true');
      }
    }
    parent = parent.parentElement;
  }
}

async function showSidebarRootForFolder(folderId) {
  const rootId = await getBookmarkRootId(folderId);
  if (!rootId) return null;

  const categoriesList = document.getElementById('categories-list');
  if (!categoriesList) return rootId;

  const activeRoot = document.querySelector('#bookmark-roots-list .bookmark-root-toggle.active');
  const folderAlreadyVisible = categoriesList.querySelector(`li[data-id="${folderId}"]`);

  if (activeRoot?.dataset.id !== rootId || !folderAlreadyVisible) {
    const nodes = await new Promise((resolve, reject) => {
      chrome.bookmarks.getTree((tree) => {
        if (chrome.runtime.lastError) {
          reject(chrome.runtime.lastError);
          return;
        }
        resolve(tree);
      });
    });

    bookmarkTreeNodes = nodes;
    const rootNodes = nodes[0]?.children || [];
    const rootNode = rootNodes.find(node => node.id === rootId);

    if (rootNode) {
      if (!document.querySelector('#bookmark-roots-list .bookmark-root-toggle')) {
        renderBookmarkRootList(rootNodes);
      }

      document.querySelectorAll('#bookmark-roots-list .bookmark-root-toggle').forEach(button => {
        const isActive = button.dataset.id === rootId;
        button.classList.toggle('active', isActive);
        button.setAttribute('aria-pressed', isActive ? 'true' : 'false');
      });

      localStorage.setItem('selectedBookmarkRootId', rootId);
      displayBookmarkCategories(rootNode.children || [], 0, categoriesList, rootId);
      await updateSidebarHomepageIndicators();
    }
  }

  revealSidebarFolder(folderId);
  return rootId;
}

// 移除所有 defaultBookmarkId 相关的代码
// 修改 waitForFirstCategory 函数
async function waitForFirstCategory(attemptsLeft = 5) {
  try {
    // 1. 先隐藏书签列表，避免闪烁
    const bookmarksList = document.getElementById('bookmarks-list');
    const bookmarksContainer = document.querySelector('.bookmarks-container');
    if (bookmarksList && bookmarksContainer) {
      bookmarksContainer.style.opacity = '0';
      bookmarksContainer.style.transition = 'opacity 0.3s ease';
    }

    const selectedRootId = localStorage.getItem('selectedBookmarkRootId');
    const { lastViewedFolder } = await chrome.storage.local.get('lastViewedFolder');
    let folderToShow = null;

    // 2. Homepage 固定文件夹优先于用户上次点击的根目录
    folderToShow = await getFirstExistingDefaultFolder();

    // 3. 无固定文件夹时，恢复上次访问的文件夹（需属于当前选中的根目录）
    if (!folderToShow && lastViewedFolder) {
      try {
        const results = await chrome.bookmarks.get(lastViewedFolder);
        if (results && results.length > 0) {
          const underSelectedRoot = !selectedRootId
            || await isFolderUnderRoot(lastViewedFolder, selectedRootId);
          if (underSelectedRoot) {
            folderToShow = lastViewedFolder;
          }
        }
      } catch (error) {
        console.log('Last viewed folder no longer exists:', error);
      }
    }

    // 4. 否则恢复用户选中的根目录（Other / Mobile 等）
    if (!folderToShow && selectedRootId) {
      try {
        const results = await chrome.bookmarks.get(selectedRootId);
        if (results && results.length > 0) {
          folderToShow = selectedRootId;
        }
      } catch (error) {
        console.log('Selected bookmark root no longer exists:', error);
      }
    }

    // 5. 兜底方案：使用书签栏根目录
    if (!folderToShow) {
      folderToShow = '1';
    }

    await showSidebarRootForFolder(folderToShow);
    await updateBookmarksDisplay(folderToShow);
    updateFolderName(folderToShow);
    selectSidebarFolder(folderToShow);
    bookmarksContainer.style.opacity = '1';

  } catch (error) {
    console.error('Error in waitForFirstCategory:', error);
    if (attemptsLeft > 0) {
      setTimeout(() => waitForFirstCategory(attemptsLeft - 1), 1000);
    } else {
      // 重试次数用完，使用已选根目录或书签栏
      const fallbackId = localStorage.getItem('selectedBookmarkRootId') || '1';
      await updateBookmarksDisplay(fallbackId);
      updateFolderName(fallbackId);
      selectSidebarFolder(fallbackId);
      // 显示内容
      const bookmarksContainer = document.querySelector('.bookmarks-container');
      if (bookmarksContainer) {
        bookmarksContainer.style.opacity = '1';
      }
    }
  }
}

// 在侧栏文件夹树上同步 Homepage 固定状态指示
async function updateSidebarHomepageIndicators(defaultFolderIds) {
  let homepageIds = defaultFolderIds;
  if (!homepageIds) {
    const data = await chrome.storage.sync.get('defaultFolders');
    homepageIds = (data.defaultFolders?.items || []).map(folder => String(folder.id));
  } else {
    homepageIds = homepageIds.map(id => String(id));
  }

  const homepageSet = new Set(homepageIds);
  const allCategories = document.querySelectorAll('#categories-list li.folder-item, #categories-list li');
  const homepageTitle = getLocalizedMessage('homepage') || 'Homepage';

  allCategories.forEach(category => {
    const folderId = category.dataset.id;
    if (!folderId) return;

    // 不再在名称后显示 pin 图标
    category.querySelector('.default-indicator')?.remove();

    let folderIcon = category.querySelector('.folder-type-icon');
    if (!folderIcon) {
      // 兼容尚未带 class 的旧节点：取左侧第一个非展开图标
      folderIcon = Array.from(category.querySelectorAll('.material-icons')).find(
        (el) => !el.classList.contains('folder-expand-toggle')
      );
      if (folderIcon) {
        folderIcon.classList.add('folder-type-icon');
      }
    }

    const shouldShow = homepageSet.has(String(folderId));
    if (shouldShow) {
      category.classList.add('is-homepage-folder');
      if (folderIcon) {
        folderIcon.innerHTML = ICONS.home;
        folderIcon.title = homepageTitle;
        folderIcon.setAttribute('aria-label', homepageTitle);
      }
    } else {
      category.classList.remove('is-homepage-folder');
      if (folderIcon) {
        folderIcon.innerHTML = ICONS.folder;
        folderIcon.removeAttribute('title');
        folderIcon.removeAttribute('aria-label');
      }
    }
  });
}

// 修改 initDefaultFoldersTabs 函数
async function initDefaultFoldersTabs({ refreshTree = true, switchFolder = true } = {}) {
  const defaultFoldersTabs = document.querySelector('.default-folders-tabs');
  const tabsContainer = defaultFoldersTabs?.querySelector('.tabs-container');
  
  if (!tabsContainer || !defaultFoldersTabs) {
    console.error('Tabs container not found');
    return;
  }

  // 获取默认文件夹列表
  const data = await chrome.storage.sync.get(['defaultFolders', 'lastViewedFolder']);
  let defaultFolders = data.defaultFolders?.items || [];
  const lastViewedFolder = data.lastViewedFolder;
  
  // 确保文件夹按 order 排序
  defaultFolders = defaultFolders.sort((a, b) => a.order - b.order);
  
  console.log('Initializing default folders tabs:', defaultFolders);

  // 清空现有标签
  tabsContainer.innerHTML = '';

  // 创建标签
  for (const folder of defaultFolders) {
    const tab = document.createElement('div');
    tab.className = 'folder-tab';
    tab.dataset.folderId = folder.id;
    tab.dataset.order = folder.order;
    tab.dataset.name = folder.name;
    tab.addEventListener('click', () => switchToFolder(folder.id));
    tabsContainer.appendChild(tab);
  }

  // 仅在需要时重建书签树（首次加载）；Pin/Unpin 只更新指示，避免树状态丢失
  if (refreshTree) {
    await new Promise((resolve) => {
      chrome.bookmarks.getTree(function (nodes) {
        bookmarkTreeNodes = nodes;
        displayBookmarkCategories(bookmarkTreeNodes[0].children, 0, null, '1');
        resolve();
      });
    });
  }

  await updateSidebarHomepageIndicators(defaultFolders.map(folder => folder.id));

  // 如果有默认文件夹，激活第一个或上次访问的文件夹
  if (switchFolder && defaultFolders.length > 0) {
    let folderToActivate;
    
    // 检查上次访问的文件夹是否在默认文件夹列表中
    // lastViewedFolder 实际保存在 local，这里兼容 sync 中的旧数据
    const localData = await chrome.storage.local.get('lastViewedFolder');
    const lastViewed = localData.lastViewedFolder || lastViewedFolder;

    if (lastViewed && defaultFolders.some(f => f.id === lastViewed)) {
      folderToActivate = lastViewed;
    } else {
      // 否则使用第一个默认文件夹
      folderToActivate = defaultFolders[0].id;
    }

    // 激活选中的文件夹
    const activeTab = document.querySelector(`.folder-tab[data-folder-id="${folderToActivate}"]`);
    if (activeTab) {
      activeTab.classList.add('active');
      activeTab.style.transform = 'scale(1.2)';
    }

    // 切换到选中的文件夹
    await switchToFolder(folderToActivate);
  }
  // 无默认文件夹快捷标签时，不强制切回书签栏；
  // 由 waitForFirstCategory 按 selectedBookmarkRootId / lastViewedFolder 恢复 Other/Mobile 等根目录

  // 重新初始化滚轮切换功能
  initWheelSwitching();

  // 更新显示状态
  updateDefaultFoldersTabsVisibility();

  return defaultFolders;
}

// 修改滚轮切换功能的实现
function initWheelSwitching() {
  const main = document.querySelector('main');
  if (!main) return;

  let wheelTimeout;
  let isProcessing = false;
  let wheelEventListener = null;
  let isEnabled = false; // 默认禁用
  
  // 创建滚轮事件处理函数
  const wheelHandler = async (event) => {
    // 如果功能被禁用，直接返回
    if (!isEnabled) return;
    
    // 检查是否在搜索相关元素内滚动
    if (event.target.closest('#bookmarks-list') || 
        event.target.closest('.search-form') || 
        event.target.closest('.search-suggestions') ||
        event.target.closest('.search-suggestions-wrapper')) {
      return;
    }

    // 防止重复触发
    if (isProcessing) return;

    // 防抖处理
    clearTimeout(wheelTimeout);
    wheelTimeout = setTimeout(async () => {
      isProcessing = true;

      try {
        const data = await chrome.storage.sync.get('defaultFolders');
        const defaultFolders = data.defaultFolders?.items || [];
        if (defaultFolders.length <= 1) {
          isProcessing = false;
          return;
        }

        // 获取当前激活的标签
        const activeTab = document.querySelector('.folder-tab.active');
        if (!activeTab) {
          isProcessing = false;
          return;
        }

        const currentOrder = parseInt(activeTab.dataset.order);
        let nextOrder;

        // 根据滚动方向决定下一个标签
        if (event.deltaY > 0) { // 向下滚动
          nextOrder = currentOrder + 1;
          if (nextOrder >= defaultFolders.length) {
            nextOrder = 0;
          }
        } else { // 向上滚动
          nextOrder = currentOrder - 1;
          if (nextOrder < 0) {
            nextOrder = defaultFolders.length - 1;
          }
        }

        // 找到对应顺序的文件夹并切换
        const nextFolder = defaultFolders.find(f => f.order === nextOrder);
        if (nextFolder) {
          await switchToFolder(nextFolder.id);
          
          // 添加切换动画效果
          const tabs = document.querySelectorAll('.folder-tab');
          tabs.forEach(tab => {
            if (tab.dataset.folderId === nextFolder.id) {
              tab.classList.add('switching');
              tab.style.transform = 'scale(1.2)';
              setTimeout(() => {
                tab.classList.remove('switching');
              }, 1500);
            } else {
              tab.style.transform = 'scale(1)';
            }
          });
        }
      } catch (error) {
        console.error('Error in wheel switching:', error);
      } finally {
        // 设置一个短暂的冷却时间
        setTimeout(() => {
          isProcessing = false;
        }, 150);
      }
    }, 50); // 50ms 的防抖延迟
  };
  
  // 添加或移除事件监听器的函数
  const updateWheelListener = (enabled) => {
    if (enabled) {
      if (!wheelEventListener) {
        main.addEventListener('wheel', wheelHandler, { passive: true });
        wheelEventListener = wheelHandler;
      }
    } else {
      if (wheelEventListener) {
        main.removeEventListener('wheel', wheelEventListener);
        wheelEventListener = null;
      }
    }
  };
  
  // 检查设置并初始化
  chrome.storage.sync.get({ enableWheelSwitching: false }, (result) => {
    isEnabled = result.enableWheelSwitching;
    updateWheelListener(isEnabled);
  });
  
  // 监听设置变化
  document.addEventListener('wheelSwitchingChanged', (event) => {
    isEnabled = event.detail.enabled;
    updateWheelListener(isEnabled);
  });
}

// 修改文件夹切换函数，确保同步更新所有状态
async function switchToFolder(folderId) {
  try {
    console.log('Switching to folder:', folderId);
    
    // 验证文件夹是否存在
    const results = await chrome.bookmarks.get(folderId);
    if (!results || results.length === 0) {
      throw new Error('Folder not found');
    }

    await showSidebarRootForFolder(folderId);

    // 更新UI状态
    document.querySelectorAll('.folder-tab').forEach(tab => {
      const isActive = tab.dataset.folderId === folderId;
      tab.classList.toggle('active', isActive);
      tab.style.transform = isActive ? 'scale(1.2)' : 'scale(1)';
      tab.style.transition = 'transform 0.3s ease';
    });

    // 同步更新所有状态
    await Promise.all([
      updateBookmarksDisplay(folderId),
      updateFolderName(folderId),
      selectSidebarFolder(folderId)
    ]);

    // 保存最后访问的文件夹
    await chrome.storage.local.set({ 
      lastViewedFolder: folderId,
      lastViewedTime: Date.now()
    });
    
  } catch (error) {
    console.error('Error switching folder:', error);
    // 错误时回退到根目录
    await updateBookmarksDisplay('1');
    updateFolderName('1');
    selectSidebarFolder('1');
  }
}

function updateBookmarksDisplay(parentId, movedItemId, newIndex, options = {}) {
  const { animate = true, updateName = true } = options;

  return new Promise((resolve, reject) => {
    // 使用 getSubTree 获取完整子树，以便递归展示子文件夹内容
    chrome.bookmarks.getSubTree(parentId, (results) => {
      if (chrome.runtime.lastError) {
        reject(chrome.runtime.lastError);
        return;
      }

      const node = results && results[0];
      if (!node) {
        reject(new Error('Folder not found'));
        return;
      }

      // 更新缓存（保留嵌套 children，供分组展示使用）
      bookmarksCache.set(parentId, node.children || []);

      displayBookmarks(node, { animate });

      if (movedItemId) {
        highlightBookmark(movedItemId);
      }

      if (updateName) {
        updateFolderName(parentId);
      }

      resolve();
    });
  });
}

// 获取书栏的本地化名称
function getBookmarksBarName() {
  return new Promise((resolve) => {
    chrome.bookmarks.getTree(function(tree) {
      if (tree && tree[0] && tree[0].children) {
        const bookmarksBar = tree[0].children.find(child => child.id === '1');
        if (bookmarksBar) {
          resolve(bookmarksBar.title);
        } else {
          resolve('Bookmarks Bar'); // 默认英文名称
        }
      } else {
        resolve('Bookmarks Bar'); // 默认英文名称
      }
    });
  });
}

function getBookmarkPath(bookmarkId) {
  return new Promise((resolve, reject) => {
    function getParentRecursive(id, path = []) {
      chrome.bookmarks.get(id, function(results) {
        if (chrome.runtime.lastError) {
          reject(chrome.runtime.lastError);
          return;
        }
        if (results && results[0]) {
          const node = results[0];
          // 跳过不可见的根节点（id 为 '0'）
          if (node.id !== '0') {
            path.unshift(node.title);
          }

          // 到达顶级文件夹（书签栏 / 其他书签 / 移动书签等）即结束，不再强制插入书签栏名称
          if (node.parentId && node.parentId !== '0') {
            getParentRecursive(node.parentId, path);
          } else {
            resolve(path);
          }
        } else {
          reject(new Error('Bookmark not found'));
        }
      });
    }
    getParentRecursive(bookmarkId);
  });
}

function updateFolderName(bookmarkId) {
  const folderNameElement = document.getElementById('folder-name');
  if (!folderNameElement) return;

  // 检查 bookmarkId 是否有效
  if (!bookmarkId || bookmarkId === 'undefined') {
    folderNameElement.textContent = getLocalizedMessage('bookmarks');
    folderNameElement.classList.remove('is-loading');
    return;
  }

  // Keep existing crumbs until the new path is ready to avoid :empty skeleton flash
  getBookmarkPath(bookmarkId).then(pathArray => {
    let breadcrumbHtml = '';
    let currentPath = '';

    pathArray.forEach((part, index) => {
      currentPath += (index > 0 ? ' > ' : '') + part;
      breadcrumbHtml += `<span class="breadcrumb-item" data-path="${escapeHtml(currentPath)}">${escapeHtml(getLocalizedMessage(part))}</span>`;
      if (index < pathArray.length - 1) {
        breadcrumbHtml += '<span class="breadcrumb-separator">&gt;</span>';
      }
    });

    folderNameElement.innerHTML = breadcrumbHtml;
    folderNameElement.classList.remove('is-loading');
    addBreadcrumbClickListeners();
  }).catch(error => {
    console.warn('Error updating folder name:', error);
    folderNameElement.textContent = getLocalizedMessage('bookmarks');
    folderNameElement.classList.remove('is-loading');
  });
}

function addBreadcrumbClickListeners() {
  const breadcrumbItems = document.querySelectorAll('.breadcrumb-item');
  breadcrumbItems.forEach((item, index) => {
    // Current folder (last crumb) is not navigable
    if (index === breadcrumbItems.length - 1) return;
    item.addEventListener('click', function () {
      const path = this.dataset.path;
      navigateToPath(path);
    });
  });
}

function navigateToPath(path) {
  const pathParts = path.split(' > ').filter(Boolean);
  if (pathParts.length === 0) {
    return;
  }

  getBookmarksBarName().then(bookmarksBarName => {
    let currentId = '1';
    let startIndex = 1;

    function navigateRecursive(index) {
      if (index >= pathParts.length) {
        updateBookmarksDisplay(currentId);
        updateFolderName(currentId);
        return;
      }

      chrome.bookmarks.getChildren(currentId, function(children) {
        const matchingChild = children.find(child => child.title === pathParts[index]);
        if (matchingChild) {
          currentId = matchingChild.id;
          navigateRecursive(index + 1);
        } else {
          updateBookmarksDisplay(currentId);
          updateFolderName(currentId);
        }
      });
    }

    function startFromRoot(rootId) {
      currentId = rootId;
      startIndex = 1;
      navigateRecursive(startIndex);
    }

    if (pathParts[0] === bookmarksBarName) {
      startFromRoot('1');
      return;
    }

    // 从「其他书签」「移动书签」等顶级根目录开始
    chrome.bookmarks.getChildren('0', function(roots) {
      const matchingRoot = (roots || []).find(child => !child.url && child.title === pathParts[0]);
      if (matchingRoot) {
        startFromRoot(matchingRoot.id);
        return;
      }

      chrome.bookmarks.search({ title: pathParts[0] }, function(results) {
        const folder = (results || []).find(item => !item.url);
        startFromRoot(folder ? folder.id : '1');
      });
    });
  });
}

let isBookmarksEditMode = localStorage.getItem('bookmarksEditMode') === 'true';

function setBookmarksEditMode(enabled) {
  isBookmarksEditMode = !!enabled;
  localStorage.setItem('bookmarksEditMode', isBookmarksEditMode ? 'true' : 'false');

  document.body.classList.toggle('bookmarks-edit-mode', isBookmarksEditMode);

  const container = document.querySelector('.bookmarks-container');
  if (container) {
    container.classList.toggle('bookmarks-edit-mode', isBookmarksEditMode);
  }

  document.querySelectorAll('.bookmarks-mode-btn').forEach(btn => {
    btn.classList.toggle('active', btn.dataset.mode === (isBookmarksEditMode ? 'edit' : 'preview'));
  });

  const parentId = document.getElementById('bookmarks-list')?.dataset.parentId;
  if (parentId) {
    // Mode toggle only — skip fade + breadcrumb refresh to avoid header flash
    updateBookmarksDisplay(parentId, undefined, undefined, {
      animate: false,
      updateName: false
    });
  }
}

function initBookmarksModeToggle() {
  const previewBtn = document.getElementById('bookmarks-preview-btn');
  const editBtn = document.getElementById('bookmarks-edit-btn');
  if (!previewBtn || !editBtn) return;

  previewBtn.textContent = getLocalizedMessage('previewMode') || 'Preview';
  editBtn.textContent = getLocalizedMessage('editMode') || 'Edit';

  previewBtn.addEventListener('click', () => setBookmarksEditMode(false));
  editBtn.addEventListener('click', () => setBookmarksEditMode(true));

  document.body.classList.toggle('bookmarks-edit-mode', isBookmarksEditMode);

  const container = document.querySelector('.bookmarks-container');
  if (container) {
    container.classList.toggle('bookmarks-edit-mode', isBookmarksEditMode);
  }
  previewBtn.classList.toggle('active', !isBookmarksEditMode);
  editBtn.classList.toggle('active', isBookmarksEditMode);

  initBookmarksAiRecommendButton();
  initBookmarksAiOrganizeButton();
  initBookmarksClear404Button();
  initBookmarksAiRestoreButton();
}

/**
 * Use AI to introduce a bookmarked website.
 */
async function introduceWebsiteWithAi(bookmark) {
  if (!bookmark?.url) return;

  const allowed = await requireAiIntroduceFeature();
  if (!allowed) return;

  const settings = await loadAiOrganizeSettings();
  const readiness = await canRunAiOrganize(settings);
  if (!readiness.ok) {
    const message = readiness.reason === 'NOT_SIGNED_IN'
      ? (getLocalizedMessage('aiOrganizeNeedSignIn') || 'Sign in to use SuperMark hosted AI')
      : readiness.reason === 'AI_QUOTA_EXCEEDED'
        ? (getLocalizedMessage('aiOrganizeQuotaExceeded')
          || 'Monthly hosted AI quota used up. Upgrade or use your own API key.')
        : (getLocalizedMessage('aiOrganizeNeedConfig')
          || 'Please configure AI API in Settings → AI first');
    Utilities.showToast(message, 2800);
    if (window.settingsManager?.openAiOrganizeSettings) {
      window.settingsManager.openAiOrganizeSettings();
    }
    return;
  }

  if (readiness.mode === 'byok' && !isHostedAiProvider(settings)) {
    const granted = await ensureAiHostPermission(settings.baseUrl);
    if (!granted) {
      Utilities.showToast(
        getLocalizedMessage('aiOrganizePermissionDenied')
        || 'Network permission denied for the AI API',
        2500
      );
      return;
    }
  }

  await showWebsiteIntroduceDialog({
    title: bookmark.title,
    url: bookmark.url
  });
}

/**
 * Recommend bookmarks by topic via AI and add selected ones to the folder.
 */
async function recommendBookmarksWithAi(folderId) {
  if (!folderId) return;

  const allowed = await requireProFeature(PRO_FEATURES.AI_RECOMMEND);
  if (!allowed) return;

  const settings = await loadAiOrganizeSettings();
  const readiness = await canRunAiOrganize(settings, { aiFeature: PRO_FEATURES.AI_RECOMMEND });
  if (!readiness.ok) {
    const message = readiness.reason === 'NOT_SIGNED_IN'
      ? (getLocalizedMessage('aiOrganizeNeedSignIn') || 'Sign in to use SuperMark hosted AI')
      : readiness.reason === 'AI_QUOTA_EXCEEDED'
        ? (getLocalizedMessage('aiOrganizeQuotaExceeded')
          || 'Monthly hosted AI quota used up. Upgrade or use your own API key.')
        : (getLocalizedMessage('aiOrganizeNeedConfig')
          || 'Please configure AI API in Settings → AI first');
    Utilities.showToast(message, 2800);
    if (window.settingsManager?.openAiOrganizeSettings) {
      window.settingsManager.openAiOrganizeSettings();
    }
    return;
  }

  if (readiness.mode === 'byok' && !isHostedAiProvider(settings)) {
    const granted = await ensureAiHostPermission(settings.baseUrl);
    if (!granted) {
      Utilities.showToast(
        getLocalizedMessage('aiOrganizePermissionDenied')
        || 'Network permission denied for the AI API',
        2500
      );
      return;
    }
  }

  const result = await showAiRecommendDialog(folderId);
  if (!result) return;

  bookmarksCache.clear();
  await refreshBookmarkSidebar(folderId);
  await updateBookmarksDisplay(folderId);
  updateFolderName(folderId);

  const msg = chrome.i18n.getMessage(
    'aiRecommendSuccess',
    [String(result.added)]
  ) || `Added ${result.added} bookmarks`;
  Utilities.showToast(msg, 3000);
}

/**
 * Run AI organize for a folder, refresh UI, and show status toasts.
 */
async function organizeFolderWithAi(folderId) {
  if (!folderId) return;

  const allowed = await requireProFeature(PRO_FEATURES.AI_ORGANIZE);
  if (!allowed) return;

  const settings = await loadAiOrganizeSettings();
  const readiness = await canRunAiOrganize(settings);
  if (!readiness.ok) {
    const message = readiness.reason === 'NOT_SIGNED_IN'
      ? (getLocalizedMessage('aiOrganizeNeedSignIn') || 'Sign in to use SuperMark hosted AI')
      : readiness.reason === 'AI_QUOTA_EXCEEDED'
        ? (getLocalizedMessage('aiOrganizeQuotaExceeded')
          || 'Monthly hosted AI quota used up. Upgrade or use your own API key.')
        : (getLocalizedMessage('aiOrganizeNeedConfig')
          || 'Please configure AI API in Settings → AI first');
    Utilities.showToast(message, 2800);
    if (window.settingsManager?.openAiOrganizeSettings) {
      window.settingsManager.openAiOrganizeSettings();
    }
    return;
  }

  // Request host permission while still in the click gesture chain (BYOK only)
  if (readiness.mode === 'byok' && !isHostedAiProvider(settings)) {
    const granted = await ensureAiHostPermission(settings.baseUrl);
    if (!granted) {
      Utilities.showToast(
        getLocalizedMessage('aiOrganizePermissionDenied')
        || 'Network permission denied for the AI API',
        2500
      );
      return;
    }
  }

  const result = await runAiOrganizeFolder(folderId);
  if (!result) return;

  bookmarksCache.clear();
  await refreshBookmarkSidebar(folderId);
  await updateBookmarksDisplay(folderId);
  updateFolderName(folderId);

  const msg = chrome.i18n.getMessage(
    'aiOrganizeSuccess',
    [String(result.foldersCreated), String(result.bookmarksMoved)]
  ) || `Created ${result.foldersCreated} folders, moved ${result.bookmarksMoved} bookmarks`;
  Utilities.showToast(msg, 3000);
  updateAiOrganizeRestoreButtonVisibility(folderId);
}

async function restoreFolderFromAiOrganize(folderId) {
  if (!folderId) return;

  const snapshot = await loadAiOrganizeSnapshot(folderId);
  if (!snapshot) {
    Utilities.showToast(
      getLocalizedMessage('aiOrganizeRestoreNone') || 'No previous AI Organize snapshot for this folder',
      2500
    );
    updateAiOrganizeRestoreButtonVisibility(folderId);
    return;
  }

  const confirmed = await showAiOrganizeRestoreConfirm(snapshot.folderTitle);
  if (!confirmed) return;

  Utilities.showToast(
    getLocalizedMessage('aiOrganizeRestoring') || 'Restoring previous structure…',
    2000
  );

  const result = await restoreAiOrganizeSnapshot(folderId);

  bookmarksCache.clear();
  await refreshBookmarkSidebar(folderId);
  await updateBookmarksDisplay(folderId);
  updateFolderName(folderId);
  updateAiOrganizeRestoreButtonVisibility(folderId);

  if (result.incomplete) {
    Utilities.showToast(
      getLocalizedMessage('aiOrganizeRestoreIncomplete')
      || 'Restored with some changes; a few bookmarks may have been recreated',
      3500
    );
    return;
  }

  Utilities.showToast(
    getLocalizedMessage('aiOrganizeRestoreSuccess') || 'Folder structure restored',
    3000
  );
}

async function updateAiOrganizeRestoreButtonVisibility(folderId) {
  const btn = document.getElementById('bookmarks-ai-restore-btn');
  if (!btn) return;

  const currentId = folderId || document.getElementById('bookmarks-list')?.dataset.parentId;
  if (!currentId) {
    btn.hidden = true;
    return;
  }

  try {
    btn.hidden = !(await hasAiOrganizeSnapshot(currentId));
  } catch (error) {
    console.warn('Failed to check AI organize snapshot:', error);
    btn.hidden = true;
  }
}

function initBookmarksAiRecommendButton() {
  const btn = document.getElementById('bookmarks-ai-recommend-btn');
  if (!btn || btn.dataset.bound === 'true') return;

  const iconEl = btn.querySelector('.bookmarks-ai-recommend-icon');
  if (iconEl && ICONS.lightbulb) {
    iconEl.innerHTML = ICONS.lightbulb;
  }

  const label = getLocalizedMessage('aiRecommendBookmarks') || 'AI Recommend';
  const labelEl = btn.querySelector('.bookmarks-ai-recommend-label');
  if (labelEl) labelEl.textContent = label;
  btn.title = label;
  btn.setAttribute('aria-label', label);

  btn.dataset.bound = 'true';
  btn.addEventListener('click', async () => {
    const folderId = document.getElementById('bookmarks-list')?.dataset.parentId;
    if (!folderId) {
      Utilities.showToast(
        getLocalizedMessage('aiOrganizeNoFolder') || 'No folder selected',
        2000
      );
      return;
    }

    btn.disabled = true;
    try {
      await recommendBookmarksWithAi(folderId);
    } catch (error) {
      console.error('AI recommend failed:', error);
      Utilities.showToast(getAiRecommendErrorMessage(error), 3000);
    } finally {
      btn.disabled = false;
    }
  });
}

function initBookmarksAiOrganizeButton() {
  const btn = document.getElementById('bookmarks-ai-organize-btn');
  if (!btn || btn.dataset.bound === 'true') return;

  const iconEl = btn.querySelector('.bookmarks-ai-organize-icon');
  if (iconEl && ICONS.auto_awesome) {
    iconEl.innerHTML = ICONS.auto_awesome;
  }

  const label = getLocalizedMessage('aiOrganizeThisFolder') || 'AI Organize';
  const labelEl = btn.querySelector('.bookmarks-ai-organize-label');
  if (labelEl) labelEl.textContent = label;
  btn.title = label;
  btn.setAttribute('aria-label', label);

  btn.dataset.bound = 'true';
  btn.addEventListener('click', async () => {
    const folderId = document.getElementById('bookmarks-list')?.dataset.parentId;
    if (!folderId) {
      Utilities.showToast(
        getLocalizedMessage('aiOrganizeNoFolder') || 'No folder selected',
        2000
      );
      return;
    }

    btn.disabled = true;
    btn.classList.add('is-busy');
    try {
      await organizeFolderWithAi(folderId);
    } catch (error) {
      console.error('AI organize failed:', error);
      Utilities.showToast(getAiOrganizeErrorMessage(error), 3000);
    } finally {
      btn.classList.remove('is-busy');
      btn.disabled = false;
    }
  });
}

async function clear404BookmarksInFolder(folderId) {
  if (!folderId) return;

  const granted = await ensureScanHostPermission();
  if (!granted) {
    Utilities.showToast(
      getLocalizedMessage('clear404PermissionDenied')
      || 'Network permission is required to check bookmarks',
      2800
    );
    return;
  }

  const [status, catalog] = await Promise.all([
    getCachedMembershipStatus(),
    fetchProductCatalog().catch(() => null)
  ]);
  const speedMultiplier = getClear404ScanSpeedMultiplier({ status, catalog });

  const progress = showClear404Progress({
    title: getLocalizedMessage('clear404ProgressTitle') || 'Checking bookmarks…',
    cancellable: true,
    speed: speedMultiplier
  });

  let scan;
  try {
    scan = await findBrokenBookmarks(folderId, {
      signal: progress?.signal,
      speedMultiplier,
      onProgress: (payload) => {
        progress?.update(payload);
      }
    });
  } catch (error) {
    progress?.close({ cancelled: true });
    throw error;
  }

  const wasCancelled = Boolean(scan.cancelled || progress?.aborted);

  if (!wasCancelled && scan.broken.length === 0) {
    await progress?.showSuccess({
      checked: scan.checked,
      empty: scan.checked === 0
    });
    return;
  }

  if (wasCancelled && scan.broken.length === 0) {
    progress?.close({ cancelled: true });
    Utilities.showToast(
      getLocalizedMessage('clear404Stopped') || 'Scan stopped',
      2500
    );
    return;
  }

  progress?.close({ cancelled: wasCancelled });

  if (wasCancelled) {
    // Still offer the partial results found before stop
    Utilities.showToast(
      getLocalizedMessage('clear404StoppedWithResults')
        ? chrome.i18n.getMessage('clear404StoppedWithResults', [String(scan.broken.length)])
        : `Scan stopped. Found ${scan.broken.length} broken bookmarks so far.`,
      2800
    );
  }

  const preview = await showClear404Preview(scan.broken);

  if (preview.action === 'cancel') {
    Utilities.showToast(
      getLocalizedMessage('clear404Cancelled') || 'Cancelled',
      1800
    );
    return;
  }

  let deleted = preview.deletedCount || 0;
  const editedCount = preview.editedCount || 0;

  if (preview.action === 'deleteAll' && preview.remaining.length > 0) {
    const deleteProgress = showClear404Progress({
      title: getLocalizedMessage('clear404Deleting') || 'Deleting…',
      cancellable: false
    });
    deleteProgress?.setFound(preview.remaining.length);
    deleteProgress?.update({
      phase: 'deleting',
      done: 0,
      total: preview.remaining.length,
      found: preview.remaining.length
    });

    try {
      deleted += await deleteBrokenBookmarks(preview.remaining, {
        onProgress: (payload) => deleteProgress?.update(payload)
      });
    } catch (error) {
      deleteProgress?.close();
      throw error;
    }
    deleteProgress?.close();
  }

  if (deleted <= 0 && editedCount <= 0) {
    Utilities.showToast(
      getLocalizedMessage('clear404Cancelled') || 'Cancelled',
      1800
    );
    return;
  }

  bookmarksCache.clear();
  await refreshBookmarkSidebar(folderId);
  await updateBookmarksDisplay(folderId);
  updateFolderName(folderId);

  if (deleted > 0) {
    Utilities.showToast(
      getLocalizedMessage('clear404Success')
        ? chrome.i18n.getMessage('clear404Success', [String(deleted)])
        : `Deleted ${deleted} broken bookmarks`,
      3000
    );
  } else {
    Utilities.showToast(
      getLocalizedMessage('clear404Edited')
        ? chrome.i18n.getMessage('clear404Edited', [String(editedCount)])
        : `Updated ${editedCount} bookmarks`,
      2500
    );
  }
}

function initBookmarksClear404Button() {
  const btn = document.getElementById('bookmarks-clear-404-btn');
  if (!btn || btn.dataset.bound === 'true') return;

  const iconEl = btn.querySelector('.bookmarks-clear-404-icon');
  if (iconEl && ICONS.cleaning_services) {
    iconEl.innerHTML = ICONS.cleaning_services;
  }

  const label = getLocalizedMessage('clear404Bookmarks') || 'Clear 404';
  const labelEl = btn.querySelector('.bookmarks-clear-404-label');
  if (labelEl) labelEl.textContent = label;
  btn.title = label;
  btn.setAttribute('aria-label', label);

  btn.dataset.bound = 'true';
  btn.addEventListener('click', async () => {
    const folderId = document.getElementById('bookmarks-list')?.dataset.parentId;
    if (!folderId) {
      Utilities.showToast(
        getLocalizedMessage('aiOrganizeNoFolder') || 'No folder selected',
        2000
      );
      return;
    }

    btn.disabled = true;
    try {
      await clear404BookmarksInFolder(folderId);
    } catch (error) {
      console.error('Clear 404 bookmarks failed:', error);
      Utilities.showToast(getClear404ErrorMessage(error), 3000);
    } finally {
      btn.disabled = false;
    }
  });
}

function initBookmarksAiRestoreButton() {
  const btn = document.getElementById('bookmarks-ai-restore-btn');
  if (!btn || btn.dataset.bound === 'true') return;

  const iconEl = btn.querySelector('.bookmarks-ai-restore-icon');
  if (iconEl && ICONS.undo) {
    iconEl.innerHTML = ICONS.undo;
  }

  const label = getLocalizedMessage('aiOrganizeRestore') || 'Restore Previous Structure';
  const labelEl = btn.querySelector('.bookmarks-ai-restore-label');
  if (labelEl) labelEl.textContent = label;
  btn.title = label;
  btn.setAttribute('aria-label', label);

  btn.dataset.bound = 'true';
  btn.addEventListener('click', async () => {
    const folderId = document.getElementById('bookmarks-list')?.dataset.parentId;
    if (!folderId) {
      Utilities.showToast(
        getLocalizedMessage('aiOrganizeNoFolder') || 'No folder selected',
        2000
      );
      return;
    }

    btn.disabled = true;
    try {
      await restoreFolderFromAiOrganize(folderId);
    } catch (error) {
      console.error('AI organize restore failed:', error);
      Utilities.showToast(
        getLocalizedMessage('aiOrganizeRestoreFailed')
          ? chrome.i18n.getMessage('aiOrganizeRestoreFailed', [String(error.message || '').slice(0, 120)])
          : `Failed to restore folder: ${String(error.message || '').slice(0, 120)}`,
        3000
      );
    } finally {
      btn.disabled = false;
    }
  });

  updateAiOrganizeRestoreButtonVisibility();
}

function applyBookmarkGridWidth(width) {
  const widthValue = parseInt(width, 10) || 150;
  document.documentElement.style.setProperty('--bookmark-width', widthValue + 'px');
  const columns = `repeat(auto-fill, minmax(${widthValue}px, 1fr))`;
  document.querySelectorAll('.bookmark-section-items').forEach(el => {
    el.style.gridTemplateColumns = columns;
  });
}

function scrollToBookmarkSection(folderId) {
  const bookmarksList = document.getElementById('bookmarks-list');
  if (!bookmarksList || !folderId) {
    return false;
  }

  const section = bookmarksList.querySelector(`.bookmark-section[data-folder-id="${folderId}"]`);
  if (!section) {
    return false;
  }

  section.scrollIntoView({ behavior: 'smooth', block: 'start' });
  section.classList.remove('bookmark-section-highlight');
  // restart animation
  void section.offsetWidth;
  section.classList.add('bookmark-section-highlight');
  setTimeout(() => {
    section.classList.remove('bookmark-section-highlight');
  }, 1400);

  return true;
}

let focusSidebarFolderRequestId = 0;
let lastSidebarFolderFocusKey = '';
let lastSidebarFolderFocusAt = 0;

async function focusSidebarFolderSection(folderId) {
  if (!folderId) return;

  const now = Date.now();
  const key = String(folderId);
  // 同一文件夹短时间内的重复触发（click + Sortable onEnd）合并为一次
  if (key === lastSidebarFolderFocusKey && now - lastSidebarFolderFocusAt < 280) {
    return;
  }
  lastSidebarFolderFocusKey = key;
  lastSidebarFolderFocusAt = now;

  const requestId = ++focusSidebarFolderRequestId;
  selectSidebarFolder(folderId);

  try {
    await updateBookmarksDisplay(folderId);
  } catch (error) {
    console.error('Failed to open sidebar folder:', error);
    return;
  }

  // 快速连续点击时，只应用最后一次请求的结果
  if (requestId !== focusSidebarFolderRequestId) {
    return;
  }

  updateFolderName(folderId);

  chrome.storage.local.set({
    lastViewedFolder: folderId,
    lastViewedTime: Date.now()
  });

  requestAnimationFrame(() => {
    document.querySelector('.bookmarks-container')?.scrollIntoView({ behavior: 'smooth', block: 'start' });
  });
}

function createBookmarkSection(folderId, pathTitles, { showTitle }) {
  const section = document.createElement('section');
  section.className = 'bookmark-section';
  section.dataset.folderId = folderId;

  if (showTitle && pathTitles && pathTitles.length > 0) {
    const header = document.createElement('div');
    header.className = 'bookmark-section-header';
    header.dataset.id = folderId;

    const icon = document.createElement('span');
    icon.className = 'material-icons bookmark-section-icon';
    icon.innerHTML = ICONS.folder;

    const title = document.createElement('h3');
    title.className = 'bookmark-section-title';
    title.textContent = pathTitles.join(' > ');

    header.appendChild(icon);
    header.appendChild(title);
    section.appendChild(header);
  }

  const items = document.createElement('div');
  items.className = 'bookmark-section-items';
  items.dataset.parentId = folderId;
  section.appendChild(items);

  return { section, items };
}

function createAddBookmarkCard(parentId) {
  const card = document.createElement('button');
  card.type = 'button';
  card.className = 'bookmark-add-card';
  card.dataset.parentId = parentId;

  const icon = document.createElement('span');
  icon.className = 'bookmark-add-icon';
  icon.textContent = '+';

  const label = document.createElement('span');
  label.className = 'bookmark-add-label';
  label.textContent = getLocalizedMessage('newLink') || 'New Link';

  card.appendChild(icon);
  card.appendChild(label);
  card.addEventListener('click', function (event) {
    event.preventDefault();
    event.stopPropagation();
    openCreateBookmarkDialog(parentId);
  });

  return card;
}

function openCreateBookmarkDialog(parentId) {
  const editDialog = document.getElementById('edit-dialog');
  const form = document.getElementById('edit-form');
  const nameInput = document.getElementById('edit-name');
  const urlInput = document.getElementById('edit-url');
  const titleEl = editDialog.querySelector('h2');

  nameInput.value = '';
  urlInput.value = 'https://';
  if (titleEl) {
    titleEl.textContent = getLocalizedMessage('addBookmarkTitle') || 'Add Bookmark';
  }

  editDialog.style.display = 'block';

  form.onsubmit = function (event) {
    event.preventDefault();
    const title = nameInput.value.trim();
    let url = urlInput.value.trim();
    if (!title || !url) return;

    if (!/^https?:\/\//i.test(url)) {
      url = 'https://' + url;
    }

    chrome.bookmarks.create({ parentId, title, url }, function (result) {
      if (chrome.runtime.lastError) {
        console.error('Error creating bookmark:', chrome.runtime.lastError);
        return;
      }
      editDialog.style.display = 'none';
      bookmarksCache.clear();
      updateBookmarksDisplay(document.getElementById('bookmarks-list')?.dataset.parentId || parentId);
    });
  };

  const cancelButton = editDialog.querySelector('.cancel-button');
  const closeButton = editDialog.querySelector('.close-button');
  const closeDialog = () => { editDialog.style.display = 'none'; };
  cancelButton.onclick = closeDialog;
  closeButton.onclick = closeDialog;
}

function appendFolderSection(folderNode, fragment, pathTitles) {
  const children = (folderNode.children || []).slice().sort((a, b) => a.index - b.index);
  const bookmarks = children.filter(child => child.url);
  const folders = children.filter(child => !child.url);

  // 空文件夹也使用分组标题布局，与有书签的文件夹保持一致
  const { section, items } = createBookmarkSection(folderNode.id, pathTitles, { showTitle: true });

  bookmarks.forEach(bookmark => {
    items.appendChild(createBookmarkCard(bookmark, bookmark.index));
  });
  if (isBookmarksEditMode) {
    items.appendChild(createAddBookmarkCard(folderNode.id));
  }

  fragment.appendChild(section);

  folders.forEach(folder => {
    appendFolderSection(folder, fragment, pathTitles.concat(folder.title || ''));
  });
}

function appendBookmarksGrouped(folderNode, fragment) {
  const children = (folderNode.children || []).slice().sort((a, b) => a.index - b.index);
  const bookmarks = children.filter(child => child.url);
  const folders = children.filter(child => !child.url);

  // 当前文件夹自身的书签（无标题分组）
  if (bookmarks.length > 0 || isBookmarksEditMode) {
    const { section, items } = createBookmarkSection(folderNode.id, [], { showTitle: false });

    bookmarks.forEach(bookmark => {
      items.appendChild(createBookmarkCard(bookmark, bookmark.index));
    });
    if (isBookmarksEditMode) {
      items.appendChild(createAddBookmarkCard(folderNode.id));
    }

    fragment.appendChild(section);
  }

  // 所有子文件夹（含空文件夹）统一按路径分组展示
  folders.forEach(folder => {
    appendFolderSection(folder, fragment, [folder.title || '']);
  });
}

function displayBookmarks(bookmark, options = {}) {
  const { animate = true } = options;
  const bookmarksList = document.getElementById('bookmarks-list');
  const bookmarksContainer = document.querySelector('.bookmarks-container');
  if (!bookmarksList) {
    return;
  }

  if (animate) {
    bookmarksContainer.classList.remove('loaded');
  }
  document.body.classList.toggle('bookmarks-edit-mode', isBookmarksEditMode);
  bookmarksContainer.classList.toggle('bookmarks-edit-mode', isBookmarksEditMode);
  bookmarkFaviconRenderIndex = 0;

  const fragment = document.createDocumentFragment();
  appendBookmarksGrouped(bookmark, fragment);

  bookmarksList.innerHTML = '';
  bookmarksList.appendChild(fragment);
  bookmarksList.dataset.parentId = bookmark.id;

  if (typeof window.updateFolderStats === 'function') {
    window.updateFolderStats(bookmark);
  }

  updateAiOrganizeRestoreButtonVisibility(bookmark.id);

  chrome.storage.sync.get(['bookmarkWidth'], (result) => {
    applyBookmarkGridWidth(result.bookmarkWidth || 150);
  });

  if (animate) {
    requestAnimationFrame(() => {
      bookmarksContainer.classList.add('loaded');
    });
  } else {
    bookmarksContainer.classList.add('loaded');
  }

  setupBookmarkCardsSortable();
}

function getColors(img) {
  const canvas = document.createElement('canvas');
  const ctx = canvas.getContext('2d');
  canvas.width = img.width;
  canvas.height = img.height;
  ctx.drawImage(img, 0, 0, img.width, img.height);
  const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
  const data = imageData.data;
  let colors = {};

  for (let i = 0; i < data.length; i += 4) {
    const r = data[i];
    const g = data[i + 1];
    const b = data[i + 2];
    const a = data[i + 3];
    if (a === 0) continue; // 跳过完全透明的像素
    const rgb = `${r},${g},${b}`;
    colors[rgb] = (colors[rgb] || 0) + 1;
  }

  const sortedColors = Object.entries(colors).sort((a, b) => b[1] - a[1]);
  
  if (sortedColors.length === 0) {
    // 如果图片完全透明，返回默认颜色
    return { primary: [200, 200, 200], secondary: [220, 220, 220] };
  }
  
  const primaryColor = sortedColors[0][0].split(',').map(Number);
  const secondaryColor = sortedColors.length > 1 
    ? sortedColors[1][0].split(',').map(Number)
    : primaryColor.map(c => Math.min(255, c + 20)); // 如果只有一种颜色，创建一个稍微亮的次要颜色

  return { primary: primaryColor, secondary: secondaryColor };
}



// 修改现有的颜色处理函数
function updateBookmarkColors(bookmark, img, card) {
  img.onload = function () {
    const colors = getColors(img);
    applyColors(card, colors);
    // 使用新的缓存系统
    ColorCache.set(bookmark.id, bookmark.url, colors);
  };

  img.onerror = function () {
    const defaultColors = {
      primary: [200, 200, 200],
      secondary: [220, 220, 220]
    };
    applyColors(card, defaultColors);
    ColorCache.set(bookmark.id, bookmark.url, defaultColors);
  };
}

function createBookmarkCard(bookmark, index) {
  const card = document.createElement('a');
  card.href = bookmark.url;
  card.className = 'bookmark-card card';
  card.dataset.id = bookmark.id;
  card.dataset.parentId = bookmark.parentId;
  card.dataset.index = index.toString();

  // 书签卡片背景已固定透明，不再从图标提取主色（避免批量 onload 卡主线程）
  card.style.background = 'transparent';
  card.style.border = 'none';

  const eager = bookmarkFaviconRenderIndex < BOOKMARK_FAVICON_EAGER_COUNT;
  bookmarkFaviconRenderIndex += 1;
  const img = createBookmarkFaviconImg(bookmark.url, { eager });

  const favicon = document.createElement('div');
  favicon.className = 'favicon';
  favicon.appendChild(img);
  card.appendChild(favicon);

  const content = document.createElement('div');
  content.className = 'card-content';

  const title = document.createElement('div');
  title.className = 'card-title';
  title.textContent = bookmark.title;

  content.appendChild(title);
  card.appendChild(content);

  const actions = document.createElement('div');
  actions.className = 'bookmark-card-actions';

  const editBtn = document.createElement('button');
  editBtn.type = 'button';
  editBtn.className = 'bookmark-card-action-btn';
  editBtn.title = getLocalizedMessage('editQuickLink') || 'Edit';
  editBtn.innerHTML = ICONS.edit;
  editBtn.addEventListener('click', function (event) {
    event.preventDefault();
    event.stopPropagation();
    openEditDialog(bookmark);
  });

  const deleteBtn = document.createElement('button');
  deleteBtn.type = 'button';
  deleteBtn.className = 'bookmark-card-action-btn bookmark-card-action-delete';
  deleteBtn.title = getLocalizedMessage('delete') || 'Delete';
  deleteBtn.innerHTML = ICONS.delete;
  deleteBtn.addEventListener('click', function (event) {
    event.preventDefault();
    event.stopPropagation();
    const message = chrome.i18n.getMessage('confirmDeleteBookmark', [`<strong>${bookmark.title}</strong>`])
      || getLocalizedMessage('confirmDeleteMessage').replace('$1', bookmark.title);
    showConfirmDialog(message, function () {
      deleteBookmark(bookmark.id, bookmark.title);
    });
  });

  actions.appendChild(editBtn);
  actions.appendChild(deleteBtn);
  card.appendChild(actions);

  card.addEventListener('contextmenu', function(event) {
    event.preventDefault();
    event.stopPropagation(); // 阻止事件冒泡，防止触发文档级的contextmenu事件监听器
    console.log('Bookmark context menu triggered:', bookmark);
    showContextMenu(event, bookmark, 'bookmark'); // 明确指定类型为 'bookmark'
  });

  // 添加鼠标悬停效果（保持透明背景，仅提升阴影）
  card.addEventListener('mouseenter', function() {
    this.style.transform = 'scale(1.03)';
  });

  card.addEventListener('mouseleave', function() {
    this.style.transform = 'scale(1)';
  });

  // 在文件顶部添加防重复点击控制
  let isProcessingClick = false;
  const CLICK_COOLDOWN = 500; // 点击冷却时间

  // 只使用一个事件处理器
  card.addEventListener('click', async (e) => {
    e.preventDefault();
    e.stopPropagation();

    if (isProcessingClick) return;
    isProcessingClick = true;

    try {
      const isInternalUrl = bookmark.url.startsWith('chrome://') || 
                           bookmark.url.startsWith('chrome-extension://') ||
                           bookmark.url.startsWith('edge://') ||
                           bookmark.url.startsWith('about:');

      console.log('[Bookmark Click] Starting...', {
        url: bookmark.url,
        isInternalUrl: isInternalUrl
      });

      // 处理内部链接
      if (isInternalUrl) {
        console.log('[Bookmark Click] Opening internal URL');
        chrome.tabs.create({
          url: bookmark.url,
          active: true
        }).then(tab => {
          console.log('[Bookmark Click] Internal tab created successfully:', tab);
        }).catch(error => {
          console.error('[Bookmark Click] Failed to create internal tab:', error);
        });
        return;
      }

      // 处理普通链接
      console.log('[Bookmark Click] Opening in Main Window mode');
      chrome.storage.sync.get(['openInNewTab'], (result) => {
        if (result.openInNewTab === true) {
          window.open(bookmark.url, '_blank');
        } else {
          window.location.href = bookmark.url;
        }
      });
    } catch (error) {
      console.error('[Bookmark Click] Error:', error);
    } finally {
      setTimeout(() => {
        isProcessingClick = false;
      }, CLICK_COOLDOWN);
    }
  });

  return card;
}

function adjustColor(r, g, b) {
  const brightness = (r * 299 + g * 587 + b * 114) / 1000;
  let factor = 1;

  if (brightness < 128) {
    // 如果颜色太暗，增加亮度
    factor = 1 + (128 - brightness) / 128;
  } else if (brightness > 200) {
    // 如果颜色太亮，减少亮度
    factor = 1 - (brightness - 200) / 55;
  }

  return {
    r: Math.min(255, Math.round(r * factor)),
    g: Math.min(255, Math.round(g * factor)),
    b: Math.min(255, Math.round(b * factor))
  };
}

function applyColors(card, colors) {
  // 书签链接：透明背景、无边框（阴影由 CSS 控制）
  if (card.classList.contains('bookmark-card')) {
    card.style.background = 'transparent';
    card.style.border = 'none';
    return;
  }

  const isDark = document.documentElement.getAttribute('data-theme') === 'dark';

  if (isDark) {
    card.style.background = '#404040';
  } else {
    card.style.background = '#f3f4f6';
  }
  card.style.border = '';
}

function openInNewWindow(url) {
  chrome.windows.create({ url: url }, function (window) {
    console.log('New window opened with id: ' + window.id);
  });
}

function openInIncognito(url) {
  chrome.windows.create({ url: url, incognito: true }, function (window) {
    console.log('New incognito window opened with id: ' + window.id);
  });
}

// Encapsulate toast and bookmark link copier functionality in a closure
const Utilities = (function() {
  let toastTimeout;

  function showToast(message, duration = 1500) {
    if (message == null || message === '') {
      console.warn('[Toast] Empty message ignored');
      return;
    }

    const toast = document.getElementById('more-button-toast');
    if (!toast) {
      console.error('Toast element not found');
      return;
    }

    // If toast is already showing, clear the previous timeout
    if (toast.classList.contains('show')) {
      clearTimeout(toastTimeout);
      toast.classList.remove('show');
      setTimeout(() => showToast(message, duration), 300); // Try showing again after a short delay
      return;
    }

    const toastMessage = toast.querySelector('p');
    if (toastMessage) {
      toastMessage.textContent = message;
    }

    toast.classList.add('show');

    toastTimeout = setTimeout(() => {
      toast.classList.remove('show');
    }, duration);
  }

  function copyBookmarkLink(bookmark) {
    try {
      if (!bookmark || !bookmark.url) {
        throw new Error('No valid bookmark link found');
      }
      navigator.clipboard.writeText(bookmark.url).then(() => {
        showToast(getLocalizedMessage('linkCopied'));
      }).catch(err => {
        console.error('Failed to copy link:', err);
        showToast(getLocalizedMessage('copyLinkFailed'));
      });
    } catch (error) {
      console.error('Error copying bookmark link:', error);
      if (error.message === 'Extension context invalidated.') {
        showToast(getLocalizedMessage('extensionReloaded'));
      } else {
        showToast(getLocalizedMessage('copyLinkFailed'));
      }
    }
  }

  return {
    showToast: showToast,
    copyBookmarkLink: copyBookmarkLink
  };
})();

// Expose for membership/settings modules that gate Pro features
window.Utilities = Utilities;

// 修改 showContextMenu 函数
function showContextMenu(event, item, type = 'bookmark') {
  // 先关闭所有已存在的上下文菜单
  const existingMenus = document.querySelectorAll('.custom-context-menu');
  existingMenus.forEach(menu => {
    if (menu !== contextMenu && menu.style.display !== 'none') {
      menu.style.display = 'none';
    }
  });

  // 如果上下文菜单不存在，则创建一个新的
  if (!contextMenu) {
    contextMenu = createContextMenu();
  }

  if (!contextMenu) {
    console.error('Failed to create context menu');
    return;
  }

  // 清除之前的状态
  itemToDelete = null;
  currentBookmark = null;
  
  // 设置当前项目，确保包含类型信息
  currentBookmark = {
    id: item.id || item.dataset?.id,
    title: item.title || item.querySelector?.('.card-title')?.textContent || item.querySelector?.('span')?.textContent,
    url: item.url || item.dataset?.url,
    parentId: item.parentId || item.dataset?.parentId,
    index: typeof item.index === 'number' ? item.index : (item.dataset?.index != null ? Number(item.dataset.index) : undefined),
    type: item.type || type  // 优先使用项目自带的类型，否则使用传入的类型
  };

  // Duplicate only applies to bookmark links, not quick links
  const duplicateItem = contextMenu.querySelector('[data-action="duplicateBookmark"]');
  if (duplicateItem) {
    duplicateItem.style.display = currentBookmark.type === 'quickLink' ? 'none' : '';
  }

  const aiIntroduceItem = contextMenu.querySelector('[data-action="aiIntroduceWebsite"]');
  if (aiIntroduceItem) {
    aiIntroduceItem.style.display = currentBookmark.url ? '' : 'none';
  }

  // 先显示菜单但设为不可见，以便获取其尺寸
  contextMenu.style.display = 'block';
  contextMenu.style.visibility = 'hidden';
  contextMenu.style.left = '0';
  contextMenu.style.top = '0';
  
  // 获取视窗尺寸
  const viewportWidth = window.innerWidth;
  const viewportHeight = window.innerHeight;
  
  // 等待一下以确保菜单已渲染
  setTimeout(() => {
    const menuRect = contextMenu.getBoundingClientRect();
    
    // 计算最佳位置
    let left = event.clientX;
    let top = event.clientY;
    
    // 检查右侧空间
    if (left + menuRect.width > viewportWidth) {
      // 如果右侧空间不足，尝试将菜单放在点击位置的左侧
      left = Math.max(5, left - menuRect.width);
    }
    
    // 检查底部空间
    if (top + menuRect.height > viewportHeight) {
      // 如果底部空间不足，尝试将菜单放在点击位置的上方
      top = Math.max(5, viewportHeight - menuRect.height - 5);
    }
    
    // 应用计算后的位置
    contextMenu.style.left = `${left}px`;
    contextMenu.style.top = `${top}px`;
    
    // 使菜单可见
    contextMenu.style.visibility = 'visible';
  }, 0);
}



// 新增函数：根据类型创建菜单项
function createContextMenuItems(contextMenu, type) {
  const menuItems = [
    { text: getLocalizedMessage('openInNewTab'), icon: 'open_in_new', action: () => currentBookmark && window.open(currentBookmark.url, '_blank') },
    { text: getLocalizedMessage('openInNewWindow'), icon: 'launch', action: () => currentBookmark && openInNewWindow(currentBookmark.url) },
    { text: getLocalizedMessage('openInIncognito'), icon: 'visibility_off', action: () => currentBookmark && openInIncognito(currentBookmark.url) },
    { text: getLocalizedMessage('editQuickLink'), icon: 'edit', action: () => currentBookmark && openEditDialog(currentBookmark) },
    { text: getLocalizedMessage('duplicateBookmark'), icon: 'file_copy', action: () => currentBookmark && duplicateBookmark(currentBookmark) },
    { 
      text: type === 'quickLink' ? getLocalizedMessage('deleteQuickLink') : getLocalizedMessage('deleteBookmark'), 
      icon: 'delete', 
      action: () => {
        console.log('=== Delete Action Triggered ===');
        console.log('Current bookmark:', currentBookmark);
        console.log('Menu type:', type);
        
        if (!currentBookmark) {
          console.error('No item selected for deletion');
          return;
        }

        // 使用全局的 itemToDelete 变量
        itemToDelete = {
          type: currentBookmark.type,  // 使用当前项目的类型
          data: {
            id: currentBookmark.id,
            title: currentBookmark.title,
            url: currentBookmark.url,
            type: currentBookmark.type  // 确保在 data 中也保存类型信息
          }
        };
        
        console.log('Set itemToDelete:', itemToDelete);
        
        // 根据类型显示不同的确认消息
        const message = itemToDelete.type === 'quickLink' 
          ? chrome.i18n.getMessage("confirmDeleteQuickLink", [`<strong>${itemToDelete.data.title}</strong>`])
          : chrome.i18n.getMessage("confirmDeleteBookmark", [`<strong>${itemToDelete.data.title}</strong>`]);
        
        console.log('Showing confirmation dialog with message:', message);
        
        showConfirmDialog(message, () => {
          console.log('=== Delete Confirmation Callback ===');
          console.log('itemToDelete:', itemToDelete);
          
          if (itemToDelete && itemToDelete.data) {
            if (itemToDelete.type === 'quickLink') {
              console.log('Deleting quick link:', itemToDelete.data);
              deleteQuickLink(itemToDelete.data);
            } else {
              console.log('Deleting bookmark:', itemToDelete.data);
              deleteBookmark(itemToDelete.data.id, itemToDelete.data.title);
            }
          } else {
            console.error('Invalid itemToDelete state:', itemToDelete);
          }
        });
      }
    },
    { text: getLocalizedMessage('copyLink'), icon: 'content_copy', action: () => currentBookmark && Utilities.copyBookmarkLink(currentBookmark) },
    { text: getLocalizedMessage('createQRCode'), icon: 'qr_code', action: () => currentBookmark && createQRCode(currentBookmark.url, currentBookmark.title) }
  ];

  menuItems.forEach(item => {
    const menuItem = document.createElement('div');
    menuItem.className = 'custom-context-menu-item';
    
    const icon = document.createElement('span');
    icon.className = 'material-icons';
    icon.innerHTML = ICONS[item.icon];
    icon.style.marginRight = '8px';
    icon.style.fontSize = '18px';
    
    const text = document.createElement('span');
    text.textContent = item.text;

    menuItem.appendChild(icon);
    menuItem.appendChild(text);

    menuItem.addEventListener('click', () => {
      if (typeof item.action === 'function') {
        item.action();
      }
      contextMenu.style.display = 'none';
    });

    menu.appendChild(menuItem);
  });
}

function showDeleteConfirmDialog() {
  if (!itemToDelete || !itemToDelete.data) {
    console.error('Invalid delete item:', itemToDelete);
    return;
  }

  console.log('=== Showing Delete Confirm Dialog ===');
  console.log('Item to delete:', itemToDelete);

  const confirmDialog = document.getElementById('confirm-dialog');
  const confirmMessage = document.getElementById('confirm-dialog-message');
  const confirmButton = document.getElementById('confirm-delete-button');
  const cancelButton = document.getElementById('cancel-delete-button');

  if (!confirmDialog || !confirmMessage || !confirmButton || !cancelButton) {
    console.error('Required dialog elements not found');
    return;
  }

  // 清空之前的消息
  confirmMessage.innerHTML = '';
  
  // 根据类型显示不同的确认消息
  const message = itemToDelete.type === 'quickLink' 
    ? chrome.i18n.getMessage("confirmDeleteQuickLink", [`<strong>${itemToDelete.data.title}</strong>`])
    : chrome.i18n.getMessage("confirmDeleteBookmark", [`<strong>${itemToDelete.data.title}</strong>`]);
  confirmMessage.innerHTML = message;
  
  console.log('Showing confirmation dialog for:', {
    type: itemToDelete.type,
    title: itemToDelete.data.title
  });
  
  confirmDialog.style.display = 'block';

  const handleConfirm = () => {
    console.log('=== Delete Confirmed ===');
    console.log('Deleting item:', itemToDelete);
    
    if (itemToDelete.type === 'quickLink') {
      deleteQuickLink(itemToDelete.data);
    } else {
      deleteBookmark(itemToDelete.data.id, itemToDelete.data.title);
    }
    
    confirmDialog.style.display = 'none';
    cleanup();
    itemToDelete = null;
  };

  const handleCancel = () => {
    console.log('=== Delete Cancelled ===');
    console.log('Cancelled item:', itemToDelete);
    confirmDialog.style.display = 'none';
    cleanup();
    itemToDelete = null;
  };

  const cleanup = () => {
    console.log('Cleaning up event listeners and state');
    confirmButton.removeEventListener('click', handleConfirm);
    cancelButton.removeEventListener('click', handleCancel);
    itemToDelete = null;
  };

  // 设置事件监听器
  confirmButton.removeEventListener('click', handleConfirm);
  cancelButton.removeEventListener('click', handleCancel);
  confirmButton.addEventListener('click', handleConfirm);
  cancelButton.addEventListener('click', handleCancel);
}

// 在创建快捷链接卡片时
function createQuickLinkCard(quickLink) {
  const card = document.createElement('div');
  card.className = 'quick-link-item-container';
  card.dataset.url = quickLink.url;
  card.dataset.id = quickLink.id;
  card.dataset.type = 'quickLink';  // 明确设置类型

  // ... 其他代码保持不变 ...

  card.addEventListener('contextmenu', function(event) {
    event.preventDefault();
    console.log('=== Quick Link Context Menu Triggered ===');
    console.log('Quick link data:', quickLink);
    console.log('Card dataset:', this.dataset);
    
    // 构造完整的快捷链接对象
    const quickLinkData = {
      id: quickLink.id || this.dataset.id,
      title: quickLink.title || this.querySelector('span').textContent,
      url: quickLink.url || this.dataset.url,
      type: 'quickLink'  // 明确指定类型
    };
    
    console.log('Constructed quickLinkData:', quickLinkData);
    showContextMenu(event, quickLinkData, 'quickLink');
  });

  // ... 其他代码保持不变 ...
}

// 在确认对话框关闭时清理数据
function closeConfirmDialog() {
  const confirmDialog = document.getElementById('confirm-dialog');
  if (confirmDialog) {
    confirmDialog.style.display = 'none';
    // 清理所有相关数据
    currentBookmark = null;
    itemToDelete = null;
  }
}

// 分别定义两个函数处理不同类型的删除
function confirmBookmarkDeletion(bookmark) {
  console.log('=== Starting Bookmark Deletion Process ===');
  console.log('Input bookmark:', bookmark);
  console.log('Current states before setting:', {
    itemToDelete,
    currentBookmark
  });

  if (!bookmark || !bookmark.id) {
    console.error('Invalid bookmark data:', bookmark);
    return;
  }

  // 设置当前要删除的书签
  itemToDelete = { ...bookmark };
  
  console.log('States after setting bookmark:', {
    itemToDelete,
    currentBookmark
  });

  const confirmDialog = document.getElementById('confirm-dialog');
  const confirmMessage = document.getElementById('confirm-dialog-message');
  const confirmButton = document.getElementById('confirm-delete-button');
  const cancelButton = document.getElementById('cancel-delete-button');

  if (!confirmDialog || !confirmMessage || !confirmButton || !cancelButton) {
    console.error('Required dialog elements not found');
    return;
  }

  // 清空之前的消息
  confirmMessage.innerHTML = '';
  
  // 只显示书签删除的确认消息
  confirmMessage.innerHTML = chrome.i18n.getMessage(
    "confirmDeleteBookmark", 
    [`<strong>${bookmark.title}</strong>`]
  );
  
  confirmDialog.style.display = 'block';

  const handleConfirm = () => {
    console.log('=== Bookmark Deletion Confirmed ===');
    console.log('Deleting bookmark:', itemToDelete);
    deleteBookmark(itemToDelete);
    confirmDialog.style.display = 'none';
    cleanup();
    clearDeleteStates();
  };

  const handleCancel = () => {
    console.log('=== Bookmark Deletion Cancelled ===');
    console.log('States before cleanup:', {
      itemToDelete,
      currentBookmark
    });
    confirmDialog.style.display = 'none';
    cleanup();
    clearDeleteStates();
  };

  const cleanup = () => {
    confirmButton.removeEventListener('click', handleConfirm);
    cancelButton.removeEventListener('click', handleCancel);
  };

  // 设置事件监听器
  confirmButton.removeEventListener('click', handleConfirm);
  cancelButton.removeEventListener('click', handleCancel);
  confirmButton.addEventListener('click', handleConfirm);
  cancelButton.addEventListener('click', handleCancel);
}

function confirmQuickLinkDeletion(quickLink) {
  console.log('=== Starting QuickLink Deletion Process ===');
  console.log('Input quickLink:', quickLink);
  console.log('Current states before setting:', {
    itemToDelete,
    currentBookmark
  });

  if (!quickLink || !quickLink.id) {
    console.error('Invalid quick link data:', quickLink);
    return;
  }

  // 设置当前要删除的快捷链接
  itemToDelete = { ...quickLink };

  console.log('States after setting quickLink:', {
    itemToDelete,
    currentBookmark
  });

  const confirmDialog = document.getElementById('confirm-dialog');
  const confirmMessage = document.getElementById('confirm-dialog-message');
  const confirmButton = document.getElementById('confirm-delete-button');
  const cancelButton = document.getElementById('cancel-delete-button');

  if (!confirmDialog || !confirmMessage || !confirmButton || !cancelButton) {
    console.error('Required dialog elements not found');
    return;
  }

  // 清空之前的消息
  confirmMessage.innerHTML = '';
  
  // 只显示快捷链接删除的确认消息
  confirmMessage.innerHTML = chrome.i18n.getMessage(
    "confirmDeleteQuickLink", 
    [`<strong>${quickLink.title}</strong>`]
  );
  
  confirmDialog.style.display = 'block';

  const handleConfirm = () => {
    console.log('=== QuickLink Deletion Confirmed ===');
    console.log('Deleting quickLink:', itemToDelete);
    deleteQuickLink(itemToDelete);
    confirmDialog.style.display = 'none';
    cleanup();
    clearDeleteStates();
  };

  const handleCancel = () => {
    console.log('=== QuickLink Deletion Cancelled ===');
    console.log('States before cleanup:', {
      itemToDelete,
      currentBookmark
    });
    confirmDialog.style.display = 'none';
    cleanup();
    clearDeleteStates();
  };

  const cleanup = () => {
    console.log('Cleaning up QuickLink deletion event listeners');
    confirmButton.removeEventListener('click', handleConfirm);
    cancelButton.removeEventListener('click', handleCancel);
  };

  // 设置事件监听器
  confirmButton.removeEventListener('click', handleConfirm);
  cancelButton.removeEventListener('click', handleCancel);
  confirmButton.addEventListener('click', handleConfirm);
  cancelButton.addEventListener('click', handleCancel);
}

// 新增：清理所有删除相关的状态
function clearDeleteStates() {
  console.log('=== Clearing All Delete States ===');
  console.log('States before clearing:', {
    itemToDelete,
    currentBookmark
  });
  
  itemToDelete = null;
  currentBookmark = null;
  
  console.log('States after clearing:', {
    itemToDelete,
    currentBookmark
  });
}

// 修改 showConfirmDialog 函数
function showConfirmDialog(message, callback) {
  // 先保存当前状态的副本
  const currentState = {
    itemToDelete: itemToDelete ? { ...itemToDelete } : null,
    currentBookmark: currentBookmark ? { ...currentBookmark } : null,
    type: itemToDelete ? itemToDelete.type : 'unknown'  // 从 itemToDelete 获取类型
  };
  
  console.log('Current state:', currentState);
  
  const confirmDialog = document.getElementById('confirm-dialog');
  const confirmMessage = document.getElementById('confirm-dialog-message');
  const confirmQuickLinkMessage = document.getElementById('confirm-delete-quick-link-message');
  const confirmButton = document.getElementById('confirm-delete-button');
  const cancelButton = document.getElementById('cancel-delete-button');

  if (!confirmDialog || !confirmMessage || !confirmButton || !cancelButton) {
    console.error('Required dialog elements not found');
    return;
  }

  // 清空所有确认消息
  confirmMessage.innerHTML = '';
  if (confirmQuickLinkMessage) {
    confirmQuickLinkMessage.innerHTML = '';
    confirmQuickLinkMessage.style.display = 'none';
  }
  
  // 根据 itemToDelete 的类型显示相应的消息
  if (itemToDelete && itemToDelete.type === 'quickLink') {
    if (confirmQuickLinkMessage) {
      confirmQuickLinkMessage.innerHTML = message;
      confirmQuickLinkMessage.style.display = 'block';
      confirmMessage.style.display = 'none';
    }
  } else {
    confirmMessage.innerHTML = message;
    confirmMessage.style.display = 'block';
    if (confirmQuickLinkMessage) {
      confirmQuickLinkMessage.style.display = 'none';
    }
  }

  confirmDialog.style.display = 'block';

  const handleConfirm = () => {
    console.log('Confirm clicked. Current state:', currentState);
    if (typeof callback === 'function') {
      callback();
    }
    confirmDialog.style.display = 'none';
    cleanup();
  };

  const handleCancel = () => {
    console.log('Cancel clicked. Clearing state...');
    confirmDialog.style.display = 'none';
    
    // 清空所有确认消息
    confirmMessage.innerHTML = '';
    confirmMessage.style.display = 'block';
    if (confirmQuickLinkMessage) {
      confirmQuickLinkMessage.innerHTML = '';
      confirmQuickLinkMessage.style.display = 'none';
    }
    
    // 使用之前保存的状态副本记录日志
    console.log('State before cancel:', currentState);
    
    clearAllStates();
    cleanup();
  };

  const cleanup = () => {
    console.log('Cleaning up event listeners');
    confirmButton.removeEventListener('click', handleConfirm);
    cancelButton.removeEventListener('click', handleCancel);
  };

  // 移除旧的事件监听器并添加新的
  confirmButton.removeEventListener('click', handleConfirm);
  cancelButton.removeEventListener('click', handleCancel);
  confirmButton.addEventListener('click', handleConfirm);
  cancelButton.addEventListener('click', handleCancel);
}

// 新增一个函数来清理所有状态
function clearAllStates() {
  itemToDelete = null;
  currentBookmark = null;
  
  // 隐藏上下文菜单
  if (contextMenu) {
    contextMenu.style.display = 'none';
  }
}

function handleBookmarkDeletion() {
  console.log('=== Handling Bookmark Deletion ===');
  console.log('Current itemToDelete:', itemToDelete);
  
  if (!itemToDelete || !itemToDelete.data) {
    console.error('No valid bookmark to delete');
    Utilities.showToast(getLocalizedMessage('deleteBookmarkError'));
    clearAllStates();
    return;
  }

  // 关闭确认对话框
  const confirmDialog = document.getElementById('confirm-dialog');
  if (confirmDialog) {
    confirmDialog.style.display = 'none';
  }

  // 执行删除操作
  deleteBookmark(itemToDelete.data.id, itemToDelete.data.title);

  // 清理状态
  clearAllStates();
}

function deleteBookmark(bookmarkId, bookmarkTitle) {
  if (!bookmarkId) {
    console.error('No bookmark ID provided for deletion');
    return;
  }

  // 先从界面上移除书签卡片
  const bookmarkCard = document.querySelector(`.bookmark-card[data-id="${bookmarkId}"]`);
  if (bookmarkCard) {
    // 添加淡出动画
    bookmarkCard.style.transition = 'opacity 0.3s ease, transform 0.3s ease';
    bookmarkCard.style.opacity = '0';
    bookmarkCard.style.transform = 'scale(0.95)';
    
    // 等待动画完成后移除元素
    setTimeout(() => {
      bookmarkCard.remove();
    }, 300);
  }

  // 然后调用 Chrome API 删除书签
  chrome.bookmarks.remove(bookmarkId, function() {
    if (chrome.runtime.lastError) {
      console.error('Error deleting bookmark:', chrome.runtime.lastError);
      Utilities.showToast(getLocalizedMessage('deleteBookmarkError'));
      
      // 如果删除失败，恢复书签卡片
      if (bookmarkCard && bookmarkCard.parentNode) {
        bookmarkCard.style.opacity = '1';
        bookmarkCard.style.transform = 'scale(1)';
      }
    } else {
      // 保留成功删除的日志，但简化
      Utilities.showToast(getLocalizedMessage('deleteSuccess'));
      
      // 清除相关缓存
      bookmarksCache.clear();
      
      // 更新父文件夹的显示
      const parentId = document.getElementById('bookmarks-list').dataset.parentId;
      if (parentId) {
        // 不需要完全刷新，因为我们已经从界面上移除了书签卡片
        // 但我们需要更新缓存和排序
        chrome.bookmarks.getChildren(parentId, (bookmarks) => {
          if (!chrome.runtime.lastError) {
            bookmarkOrderCache[parentId] = bookmarks.map(b => b.id);
          }
        });
      }
    }
  });
}

function showToast(message, duration = 3000) {
  const toast = document.getElementById('toast');
  if (!toast) {
    console.error('Toast element not found');
    return;
  }
  toast.textContent = message;
  toast.style.display = 'block';
  toast.classList.add('show');

  setTimeout(() => {
    toast.classList.remove('show');
    setTimeout(() => {
      toast.style.display = 'none';
    }, 300);
  }, duration);
}



function createFolderCard(folder, index) {
  const card = document.createElement('div');
  card.className = 'bookmark-folder card';
  card.dataset.id = folder.id;
  card.dataset.parentId = folder.parentId;
  card.dataset.index = index.toString();

  const icon = document.createElement('span');
  icon.className = 'material-icons mr-2';
  icon.innerHTML = ICONS.folder;
  
  const content = document.createElement('div');
  content.className = 'card-content';
  
  const title = document.createElement('div');
  title.className = 'card-title';
  title.textContent = folder.title;
  
  content.appendChild(title);
  card.appendChild(icon);
  card.appendChild(content);

  // Add click event handler to display folder contents
  card.addEventListener('click', function() {
    updateBookmarksDisplay(folder.id);
    updateFolderName(folder.id);
  });

  // 从缓存获取文件夹颜色
  const cachedColors = ColorCache.get(folder.id, 'folder');
  if (cachedColors) {
    applyColors(card, cachedColors);
  } else {
    // 为文件夹生成默认颜色
    const defaultColors = {
      primary: [230, 230, 230],    // 稍微浅一点的灰色
      secondary: [240, 240, 240]    // 更浅的灰色
    };
    applyColors(card, defaultColors);
    ColorCache.set(folder.id, 'folder', defaultColors);
  }

  // 修改右键点击事件，使用文件夹的上下文菜单
  card.addEventListener('contextmenu', async function (event) {
    event.preventDefault();
    event.stopPropagation();
    
    console.log('Folder card right click:', {
      folderId: card.dataset.id,
      folderTitle: card.querySelector('.card-title')?.textContent
    });
    
    // 确保文件夹上下文菜单存在
    if (!bookmarkFolderContextMenu) {
      bookmarkFolderContextMenu = createBookmarkFolderContextMenu();
    }

    if (!bookmarkFolderContextMenu) {
      console.error('Failed to create bookmark folder context menu');
      return;
    }

    // 更新当前文件夹
    currentBookmarkFolder = card;
    
    // 重新创建菜单项以反映当前文件夹的状态
    await createMenuItems(bookmarkFolderContextMenu);
    
    // 先显示菜单但设为不可见，以便获取其尺寸
    bookmarkFolderContextMenu.style.display = 'block';
    bookmarkFolderContextMenu.style.visibility = 'hidden';
    bookmarkFolderContextMenu.style.left = '0';
    bookmarkFolderContextMenu.style.top = '0';
    
    // 获取视窗尺寸
    const viewportWidth = window.innerWidth;
    const viewportHeight = window.innerHeight;
    
    // 等待一下以确保菜单已渲染
    setTimeout(() => {
      const menuRect = bookmarkFolderContextMenu.getBoundingClientRect();
      
      // 计算最佳位置
      let left = event.clientX;
      let top = event.clientY;
      
      // 检查右侧空间
      if (left + menuRect.width > viewportWidth) {
        // 如果右侧空间不足，尝试将菜单放在点击位置的左侧
        left = Math.max(5, left - menuRect.width);
      }
      
      // 检查底部空间
      if (top + menuRect.height > viewportHeight) {
        // 如果底部空间不足，尝试将菜单放在点击位置的上方
        top = Math.max(5, viewportHeight - menuRect.height - 5);
      }
      
      // 应用计算后的位置
      bookmarkFolderContextMenu.style.left = `${left}px`;
      bookmarkFolderContextMenu.style.top = `${top}px`;
      
      // 使菜单可见
      bookmarkFolderContextMenu.style.visibility = 'visible';
    }, 0);

    // 隐藏其他上下文菜单
    if (contextMenu) {
      contextMenu.style.display = 'none';
    }
  });

  return card;
}

function getSelectedBookmarkRootId() {
  return localStorage.getItem('selectedBookmarkRootId') || '1';
}

let sidebarDraggingFolderId = null;
let sidebarCrossRootMovePending = false;
let sidebarPlacementMode = false;
let sidebarPlacementFolderId = null;
let sidebarPlacementFolderTitle = '';
let sidebarPlacementSourceRootId = null;
let sidebarRootHoverTimer = null;
let sidebarPlacementTarget = null;
let sidebarPlacementGhost = null;
let sidebarPlacementIndicator = null;
let sidebarPlacementIgnoreUpUntil = 0;
let sidebarRootHoverTargetId = null;
const SIDEBAR_ROOT_HOVER_SWITCH_MS = 350;

function clearSidebarRootHoverTimer() {
  if (sidebarRootHoverTimer) {
    clearTimeout(sidebarRootHoverTimer);
    sidebarRootHoverTimer = null;
  }
  sidebarRootHoverTargetId = null;
}

function getBookmarkRootToggleAtPoint(clientX, clientY) {
  const toggles = document.querySelectorAll('#bookmark-roots-list .bookmark-root-toggle');
  for (const toggle of toggles) {
    const rect = toggle.getBoundingClientRect();
    if (
      clientX >= rect.left &&
      clientX <= rect.right &&
      clientY >= rect.top &&
      clientY <= rect.bottom
    ) {
      return toggle;
    }
  }
  return null;
}

function isPointInBookmarkRootsList(clientX, clientY) {
  const rootsList = document.getElementById('bookmark-roots-list');
  if (!rootsList) return false;
  const rect = rootsList.getBoundingClientRect();
  // 稍微扩大命中区域，拖拽时更容易悬停
  const pad = 6;
  return (
    clientX >= rect.left - pad &&
    clientX <= rect.right + pad &&
    clientY >= rect.top - pad &&
    clientY <= rect.bottom + pad
  );
}

function clearSidebarFolderDragState() {
  clearSidebarRootHoverTimer();
  sidebarDraggingFolderId = null;
  document.body.classList.remove('is-dragging-sidebar-folder');
  document.querySelectorAll('#bookmark-roots-list .bookmark-root-toggle.drop-target').forEach((el) => {
    el.classList.remove('drop-target');
  });
  if (sidebarPlacementMode) {
    exitSidebarPlacementMode({ restoreSourceRoot: false });
  } else {
    cleanupSidebarDragArtifacts();
  }
}

function removeSidebarFolderFromDom(folderId) {
  if (!folderId) return;

  const li = document.querySelector(`#categories-list li.folder-item[data-id="${folderId}"]`);
  if (!li) return;

  let sublist = li._associatedSublist;
  if (!sublist || !sublist.isConnected) {
    sublist = document.querySelector(`#categories-list ul[data-parent-folder-id="${folderId}"]`);
  }

  li.remove();
  if (sublist) {
    sublist.remove();
  }
}

function getSidebarFolderTitle(folderId) {
  const li = document.querySelector(`#categories-list li.folder-item[data-id="${folderId}"]`);
  if (!li) return '';
  return li.dataset.title ||
    Array.from(li.querySelectorAll('span')).map((s) => s.textContent.trim()).filter(Boolean).pop() ||
    '';
}

function getFolderIndexAmongSiblingFolders(folderLi) {
  if (!folderLi?.parentElement) return 0;
  const siblings = Array.from(folderLi.parentElement.children).filter(
    (el) => el.matches && el.matches('li.folder-item')
  );
  return Math.max(0, siblings.indexOf(folderLi));
}

function ensureSidebarPlacementUi() {
  if (!sidebarPlacementGhost) {
    sidebarPlacementGhost = document.createElement('div');
    sidebarPlacementGhost.className = 'sidebar-folder-placement-ghost';
    sidebarPlacementGhost.setAttribute('aria-hidden', 'true');
    document.body.appendChild(sidebarPlacementGhost);
  }

  if (!sidebarPlacementIndicator) {
    sidebarPlacementIndicator = document.createElement('div');
    sidebarPlacementIndicator.className = 'sidebar-folder-drop-indicator';
    sidebarPlacementIndicator.setAttribute('aria-hidden', 'true');
    document.body.appendChild(sidebarPlacementIndicator);
  }

  if (document.body.dataset.sidebarPlacementBound === 'true') {
    return;
  }
  document.body.dataset.sidebarPlacementBound = 'true';

  const onMove = (event) => onSidebarPlacementPointerMove(event);
  const onUp = (event) => onSidebarPlacementPointerUp(event);

  document.addEventListener('dragover', onMove, true);
  document.addEventListener('mousemove', onMove, true);
  document.addEventListener('drop', onUp, true);
  document.addEventListener('mouseup', onUp, true);
  document.addEventListener('dragend', onUp, true);
  document.addEventListener('keydown', (event) => {
    if (event.key === 'Escape' && sidebarPlacementMode) {
      event.preventDefault();
      cancelSidebarPlacementMode();
    }
  }, true);
}

function hideSidebarPlacementIndicator() {
  if (sidebarPlacementIndicator) {
    sidebarPlacementIndicator.style.display = 'none';
  }
  document.querySelectorAll('#categories-list li.folder-item.drop-into-target').forEach((el) => {
    el.classList.remove('drop-into-target');
  });
}

function removeSortableDragClones() {
  document.querySelectorAll(
    '.sidebar-folder-drag-fallback, .sidebar-folder-drag-active, .sortable-fallback, .sortable-drag'
  ).forEach((el) => {
    if (el.closest('#categories-list')) {
      el.classList.remove(
        'sidebar-folder-drag-fallback',
        'sidebar-folder-drag-active',
        'sidebar-folder-drag-chosen',
        'sidebar-folder-drag-ghost',
        'sortable-fallback',
        'sortable-drag',
        'sortable-chosen',
        'sortable-ghost'
      );
      el.style.cssText = '';
      return;
    }
    el.remove();
  });
}

function cleanupSidebarDragArtifacts() {
  removeSortableDragClones();

  if (sidebarPlacementGhost) {
    sidebarPlacementGhost.style.display = 'none';
    sidebarPlacementGhost.textContent = '';
  }

  hideSidebarPlacementIndicator();
}

function exitSidebarPlacementMode({ restoreSourceRoot = false } = {}) {
  const wasPlacement = sidebarPlacementMode;
  const sourceRootId = sidebarPlacementSourceRootId;

  sidebarPlacementMode = false;
  sidebarPlacementFolderId = null;
  sidebarPlacementFolderTitle = '';
  sidebarPlacementSourceRootId = null;
  sidebarPlacementTarget = null;
  sidebarCrossRootMovePending = false;
  clearSidebarRootHoverTimer();

  document.body.classList.remove('is-sidebar-folder-placing', 'is-dragging-sidebar-folder');
  cleanupSidebarDragArtifacts();
  // 再清一次，防止 Sortable 异步残留
  requestAnimationFrame(() => {
    removeSortableDragClones();
    setTimeout(removeSortableDragClones, 50);
  });

  document.querySelectorAll('#bookmark-roots-list .bookmark-root-toggle.drop-target').forEach((el) => {
    el.classList.remove('drop-target');
  });

  if (wasPlacement && restoreSourceRoot && sourceRootId) {
    switchToBookmarkRoot(sourceRootId, { updateMainView: false });
  }
}

function cancelSidebarPlacementMode() {
  const sourceRootId = sidebarPlacementSourceRootId || getSelectedBookmarkRootId();
  exitSidebarPlacementMode({ restoreSourceRoot: false });
  sidebarDraggingFolderId = null;
  switchToBookmarkRoot(sourceRootId, { updateMainView: false });
}

function scheduleSidebarRootSwitchDuringDrag(rootId) {
  if (!rootId) return;
  if (!sidebarDraggingFolderId && !sidebarPlacementMode) return;

  const currentRootId = getSelectedBookmarkRootId();
  if (rootId === currentRootId) {
    // 已在目标根：只清掉指向其他根的等待
    if (sidebarRootHoverTargetId && sidebarRootHoverTargetId !== rootId) {
      clearSidebarRootHoverTimer();
    }
    return;
  }

  // 关键关键同一目标时不要重置计时器，否则永远等不到切换
  if (sidebarRootHoverTimer && sidebarRootHoverTargetId === rootId) {
    return;
  }

  clearSidebarRootHoverTimer();
  sidebarRootHoverTargetId = rootId;
  sidebarRootHoverTimer = setTimeout(() => {
    sidebarRootHoverTimer = null;
    sidebarRootHoverTargetId = null;
    enterSidebarPlacementModeForRoot(rootId);
  }, SIDEBAR_ROOT_HOVER_SWITCH_MS);
}

function enterSidebarPlacementModeForRoot(rootId) {
  const folderId = sidebarDraggingFolderId || sidebarPlacementFolderId;
  if (!folderId || !rootId) return;

  const title = sidebarPlacementFolderTitle || getSidebarFolderTitle(folderId);
  if (!sidebarPlacementSourceRootId) {
    sidebarPlacementSourceRootId = getSelectedBookmarkRootId();
  }

  // 先加锁，避免 Sortable 在重建 DOM 时触发普通移动
  sidebarPlacementMode = true;
  sidebarCrossRootMovePending = true;
  sidebarPlacementFolderId = folderId;
  sidebarPlacementFolderTitle = title;
  sidebarDraggingFolderId = folderId;
  // 忽略紧随其后的 dragend/mouseup（来自 Sortable 结束），让用户继续选位置
  sidebarPlacementIgnoreUpUntil = Date.now() + 500;

  ensureSidebarPlacementUi();
  document.body.classList.add('is-dragging-sidebar-folder', 'is-sidebar-folder-placing');
  // 只移除 Sortable 克隆，保留放置预览
  removeSortableDragClones();

  if (sidebarPlacementGhost) {
    sidebarPlacementGhost.textContent = title || 'Folder';
    sidebarPlacementGhost.style.display = 'block';
  }

  localStorage.setItem('selectedBookmarkRootId', rootId);
  document.querySelectorAll('#bookmark-roots-list .bookmark-root-toggle').forEach((item) => {
    const isActive = item.dataset.id === rootId;
    item.classList.toggle('active', isActive);
    item.setAttribute('aria-pressed', isActive ? 'true' : 'false');
    item.classList.toggle('drop-target', isActive);
  });

  chrome.bookmarks.getSubTree(rootId, (subtrees) => {
    if (!sidebarPlacementMode || sidebarPlacementFolderId !== folderId) {
      return;
    }
    if (chrome.runtime.lastError) {
      console.error('Error loading root during placement:', chrome.runtime.lastError);
      cancelSidebarPlacementMode();
      return;
    }

    const categoriesList = document.getElementById('categories-list');
    const rootNode = subtrees?.[0];
    if (!categoriesList || !rootNode) {
      cancelSidebarPlacementMode();
      return;
    }

    // 排除正在拖拽的文件夹，避免放入自身
    const children = (rootNode.children || []).filter((child) => child.id !== folderId);
    categoriesList.innerHTML = '';
    displayBookmarkCategories(children, 0, categoriesList, rootId);

    // 默认放到当前根顶级末尾
    const topLevelCount = categoriesList.querySelectorAll(':scope > li.folder-item').length;
    sidebarPlacementTarget = { parentId: rootId, index: topLevelCount };
  });
}

function updateSidebarPlacementTargetFromPoint(clientX, clientY) {
  const categoriesList = document.getElementById('categories-list');
  if (!categoriesList || !sidebarPlacementMode) return;

  hideSidebarPlacementIndicator();

  const rootId = getSelectedBookmarkRootId();
  let parentId = rootId;
  let index = categoriesList.querySelectorAll(':scope > li.folder-item').length;
  let indicatorRect = null;
  let intoFolderEl = null;

  // 临时隐藏 ghost，避免挡住 elementFromPoint
  const ghostDisplay = sidebarPlacementGhost?.style.display;
  if (sidebarPlacementGhost) sidebarPlacementGhost.style.display = 'none';
  const el = document.elementFromPoint(clientX, clientY);
  if (sidebarPlacementGhost) sidebarPlacementGhost.style.display = ghostDisplay || 'block';

  const rootToggle = getBookmarkRootToggleAtPoint(clientX, clientY);
  if (rootToggle?.dataset?.id) {
    if (rootToggle.dataset.id !== rootId) {
      scheduleSidebarRootSwitchDuringDrag(rootToggle.dataset.id);
    }
    sidebarPlacementTarget = { parentId: rootToggle.dataset.id, index: 0 };
    return;
  }

  if (!el || !categoriesList.contains(el)) {
    // 在树外：保持上次目标，或落到当前根末尾
    sidebarPlacementTarget = sidebarPlacementTarget || { parentId: rootId, index };
    return;
  }

  const folderLi = el.closest('li.folder-item');
  const nestedList = el.closest('ul[data-parent-folder-id]');

  if (folderLi && folderLi.dataset.id && folderLi.dataset.id !== sidebarPlacementFolderId) {
    const rect = folderLi.getBoundingClientRect();
    const relY = rect.height ? (clientY - rect.top) / rect.height : 0.5;
    const relX = rect.width ? (clientX - rect.left) / rect.width : 0;

    const dropInto = relX > 0.68 || (relY >= 0.35 && relY <= 0.65);

    if (dropInto) {
      parentId = folderLi.dataset.id;
      const childUl = folderLi.nextElementSibling?.tagName === 'UL'
        ? folderLi.nextElementSibling
        : null;
      index = childUl
        ? childUl.querySelectorAll(':scope > li.folder-item').length
        : 0;
      intoFolderEl = folderLi;
      indicatorRect = {
        left: rect.left + 12,
        top: rect.bottom - 2,
        width: Math.max(40, rect.width - 24)
      };
    } else if (relY < 0.5) {
      parentId = folderLi.dataset.parentId || rootId;
      index = getFolderIndexAmongSiblingFolders(folderLi);
      indicatorRect = { left: rect.left, top: rect.top - 1, width: rect.width };
    } else {
      parentId = folderLi.dataset.parentId || rootId;
      index = getFolderIndexAmongSiblingFolders(folderLi) + 1;
      indicatorRect = { left: rect.left, top: rect.bottom - 1, width: rect.width };
    }
  } else if (nestedList && nestedList.id !== 'categories-list') {
    parentId = nestedList.dataset.parentFolderId || rootId;
    const folders = Array.from(nestedList.querySelectorAll(':scope > li.folder-item'));
    index = folders.length;
    for (let i = 0; i < folders.length; i++) {
      const rect = folders[i].getBoundingClientRect();
      if (clientY < rect.top + rect.height / 2) {
        index = i;
        indicatorRect = { left: rect.left, top: rect.top - 1, width: rect.width };
        break;
      }
    }
    if (!indicatorRect) {
      const listRect = nestedList.getBoundingClientRect();
      indicatorRect = {
        left: listRect.left + 8,
        top: listRect.bottom - 4,
        width: Math.max(40, listRect.width - 16)
      };
    }
  } else {
    // 顶级列表空白处
    const topFolders = Array.from(categoriesList.querySelectorAll(':scope > li.folder-item'));
    index = topFolders.length;
    for (let i = 0; i < topFolders.length; i++) {
      const rect = topFolders[i].getBoundingClientRect();
      if (clientY < rect.top + rect.height / 2) {
        index = i;
        indicatorRect = { left: rect.left, top: rect.top - 1, width: rect.width };
        break;
      }
    }
    if (!indicatorRect) {
      const listRect = categoriesList.getBoundingClientRect();
      indicatorRect = {
        left: listRect.left + 8,
        top: Math.min(clientY, listRect.bottom - 4),
        width: Math.max(40, listRect.width - 16)
      };
    }
    parentId = rootId;
  }

  sidebarPlacementTarget = { parentId, index };

  if (intoFolderEl) {
    intoFolderEl.classList.add('drop-into-target');
  }

  if (sidebarPlacementIndicator && indicatorRect) {
    sidebarPlacementIndicator.style.display = 'block';
    sidebarPlacementIndicator.style.left = `${indicatorRect.left}px`;
    sidebarPlacementIndicator.style.top = `${indicatorRect.top}px`;
    sidebarPlacementIndicator.style.width = `${indicatorRect.width}px`;
  }
}

function onSidebarPlacementPointerMove(event) {
  if (!sidebarPlacementMode) {
    // 普通拖拽阶段：悬停根目录按钮预切换
    if (!sidebarDraggingFolderId || sidebarCrossRootMovePending) return;
    const clientX = event.clientX;
    const clientY = event.clientY;
    if (typeof clientX !== 'number') return;

    // 用坐标命中，避免被 Sortable 拖拽幽灵挡住
    const toggle = getBookmarkRootToggleAtPoint(clientX, clientY);
    if (toggle?.dataset?.id) {
      document.querySelectorAll('#bookmark-roots-list .bookmark-root-toggle.drop-target').forEach((item) => {
        item.classList.toggle('drop-target', item === toggle);
      });
      scheduleSidebarRootSwitchDuringDrag(toggle.dataset.id);
    } else if (!isPointInBookmarkRootsList(clientX, clientY)) {
      clearSidebarRootHoverTimer();
      document.querySelectorAll('#bookmark-roots-list .bookmark-root-toggle.drop-target').forEach((item) => {
        item.classList.remove('drop-target');
      });
    }
    return;
  }

  if (event.cancelable && event.type === 'dragover') {
    event.preventDefault();
  }

  const clientX = event.clientX;
  const clientY = event.clientY;
  if (typeof clientX !== 'number') return;

  if (sidebarPlacementGhost) {
    sidebarPlacementGhost.style.display = 'block';
    sidebarPlacementGhost.style.left = `${clientX + 14}px`;
    sidebarPlacementGhost.style.top = `${clientY + 12}px`;
  }

  updateSidebarPlacementTargetFromPoint(clientX, clientY);
}

function onSidebarPlacementPointerUp(event) {
  if (!sidebarPlacementMode) return;

  // Sortable 因切树结束时会立刻冒泡 dragend/mouseup，先吞掉
  if (Date.now() < sidebarPlacementIgnoreUpUntil) {
    event.preventDefault?.();
    event.stopPropagation?.();
    return;
  }

  // 避免误触发点击根目录按钮
  if (event.type === 'mouseup' || event.type === 'drop') {
    event.preventDefault?.();
    event.stopPropagation?.();
  }

  const folderId = sidebarPlacementFolderId;
  const target = sidebarPlacementTarget || {
    parentId: getSelectedBookmarkRootId(),
    index: 0
  };

  if (!folderId || !target.parentId) {
    cancelSidebarPlacementMode();
    return;
  }

  commitSidebarPlacementMove(folderId, target.parentId, target.index);
}

/**
 * 放置模式给出的是「仅文件夹」槽位；Chrome index 含书签，且同父级下移需 +1。
 */
function resolveChromeIndexFromFolderOnlyIndex(folderId, parentId, folderOnlyIndex) {
  return new Promise((resolve, reject) => {
    chrome.bookmarks.get(folderId, (nodes) => {
      if (chrome.runtime.lastError || !nodes?.[0]) {
        reject(chrome.runtime.lastError || new Error('Folder not found'));
        return;
      }

      const { parentId: oldParentId, index: oldIndex } = nodes[0];
      const sameParent = oldParentId === parentId;
      const slot = Math.max(0, folderOnlyIndex | 0);

      chrome.bookmarks.getChildren(parentId, (children) => {
        if (chrome.runtime.lastError) {
          reject(chrome.runtime.lastError);
          return;
        }

        const foldersExcludingMoving = children.filter((child) => !child.url && child.id !== folderId);
        let desiredFinalIndex;

        if (foldersExcludingMoving.length === 0 || slot <= 0) {
          desiredFinalIndex = 0;
        } else if (slot >= foldersExcludingMoving.length) {
          const last = foldersExcludingMoving[foldersExcludingMoving.length - 1];
          desiredFinalIndex = last.index + 1;
        } else {
          const target = foldersExcludingMoving[slot];
          if (sameParent && oldIndex < target.index) {
            desiredFinalIndex = Math.max(0, target.index - 1);
          } else {
            desiredFinalIndex = target.index;
          }
        }

        let apiIndex = desiredFinalIndex;
        if (sameParent && oldIndex < desiredFinalIndex) {
          apiIndex += 1;
        }

        const isNoOp = sameParent && (apiIndex === oldIndex || apiIndex === oldIndex + 1);
        resolve({ apiIndex, isNoOp, oldParentId, oldIndex, sameParent, desiredFinalIndex });
      });
    });
  });
}

function commitSidebarPlacementMove(folderId, parentId, index) {
  if (!folderId || !parentId) {
    cancelSidebarPlacementMode();
    return;
  }

  sidebarCrossRootMovePending = true;

  // 禁止移动到自身或其子树（Chrome 也会拒绝，这里提前拦截）
  if (folderId === parentId) {
    cancelSidebarPlacementMode();
    return;
  }

  resolveChromeIndexFromFolderOnlyIndex(folderId, parentId, index)
    .then(({ apiIndex, isNoOp, oldParentId }) => {
      if (isNoOp) {
        exitSidebarPlacementMode({ restoreSourceRoot: false });
        sidebarDraggingFolderId = null;
        refreshBookmarkSidebar(folderId);
        return;
      }

      chrome.bookmarks.move(folderId, { parentId, index: apiIndex }, (result) => {
        if (chrome.runtime.lastError) {
          console.error('Error placing folder across roots:', chrome.runtime.lastError);
          const sourceRootId = sidebarPlacementSourceRootId;
          exitSidebarPlacementMode({ restoreSourceRoot: false });
          sidebarDraggingFolderId = null;
          if (sourceRootId) {
            switchToBookmarkRoot(sourceRootId, { updateMainView: false });
          }
          refreshBookmarkSidebar(folderId);
          return;
        }

        if (oldParentId) bookmarksCache.delete(oldParentId);
        bookmarksCache.delete(parentId);
        if (sidebarPlacementSourceRootId) {
          bookmarksCache.delete(sidebarPlacementSourceRootId);
        }
        bookmarksCache.delete(getSelectedBookmarkRootId());

        console.log('Folder placed across roots:', {
          folderId,
          parentId,
          requestedIndex: apiIndex,
          index: result?.index
        });

        const targetRootId = getSelectedBookmarkRootId();
        exitSidebarPlacementMode({ restoreSourceRoot: false });
        sidebarDraggingFolderId = null;

        chrome.bookmarks.getSubTree(targetRootId, (subtrees) => {
          const rootNode = subtrees?.[0];
          const categoriesList = document.getElementById('categories-list');
          if (rootNode && categoriesList) {
            categoriesList.innerHTML = '';
            displayBookmarkCategories(rootNode.children || [], 0, categoriesList, targetRootId);
          }
        });

        const bookmarksList = document.getElementById('bookmarks-list');
        if (bookmarksList?.dataset.parentId === folderId) {
          updateBookmarksDisplay(parentId);
          updateFolderName(parentId);
          chrome.storage.local.set({
            lastViewedFolder: parentId,
            lastViewedTime: Date.now()
          });
        } else {
          scheduleBookmarksPreviewRefresh();
        }
      });
    })
    .catch((error) => {
      console.error('Error resolving placement folder index:', error);
      cancelSidebarPlacementMode();
      refreshBookmarkSidebar(folderId);
    });
}

function moveFolderToBookmarkRoot(folderId, targetRootId) {
  // 兼容：直接放到目标根顶级（未进入放置模式时）
  if (!folderId || !targetRootId) return;
  if (sidebarPlacementMode) {
    commitSidebarPlacementMove(folderId, targetRootId, 0);
    return;
  }
  if (sidebarCrossRootMovePending) return;

  sidebarCrossRootMovePending = true;
  sidebarDraggingFolderId = null;

  chrome.bookmarks.get(folderId, (nodes) => {
    const node = nodes?.[0];
    if (!node || node.url || !node.parentId || node.parentId === '0') {
      sidebarCrossRootMovePending = false;
      clearSidebarFolderDragState();
      return;
    }
    performMoveFolderToBookmarkRoot(folderId, targetRootId, node);
  });
}

function performMoveFolderToBookmarkRoot(folderId, targetRootId, node) {
  const sourceRootId = getSelectedBookmarkRootId();
  const oldParentId = node.parentId;

  if (oldParentId === targetRootId && sourceRootId === targetRootId) {
    sidebarCrossRootMovePending = false;
    clearSidebarFolderDragState();
    return;
  }

  chrome.bookmarks.move(folderId, { parentId: targetRootId, index: 0 }, (result) => {
    if (chrome.runtime.lastError) {
      console.error('Error moving folder to bookmark root:', chrome.runtime.lastError);
      sidebarCrossRootMovePending = false;
      clearSidebarFolderDragState();
      refreshBookmarkSidebar(folderId);
      return;
    }

    if (oldParentId) bookmarksCache.delete(oldParentId);
    bookmarksCache.delete(targetRootId);
    bookmarksCache.delete(sourceRootId);

    const viewingRootId = getSelectedBookmarkRootId();
    if (viewingRootId !== targetRootId) {
      removeSidebarFolderFromDom(folderId);
    } else if (oldParentId !== targetRootId) {
      chrome.bookmarks.getSubTree(targetRootId, (subtrees) => {
        const rootNode = subtrees?.[0];
        const categoriesList = document.getElementById('categories-list');
        if (rootNode && categoriesList) {
          categoriesList.innerHTML = '';
          displayBookmarkCategories(rootNode.children || [], 0, categoriesList, targetRootId);
        }
      });
    }

    const bookmarksList = document.getElementById('bookmarks-list');
    if (bookmarksList?.dataset.parentId === folderId) {
      updateBookmarksDisplay(targetRootId);
      updateFolderName(targetRootId);
      chrome.storage.local.set({
        lastViewedFolder: targetRootId,
        lastViewedTime: Date.now()
      });
    } else {
      scheduleBookmarksPreviewRefresh();
    }

    sidebarCrossRootMovePending = false;
    clearSidebarFolderDragState();
  });
}

function setupBookmarkRootDropTargets() {
  const rootsList = document.getElementById('bookmark-roots-list');
  if (!rootsList || rootsList.dataset.dropTargetsBound === 'true') {
    return;
  }
  rootsList.dataset.dropTargetsBound = 'true';
  ensureSidebarPlacementUi();

  const clearDropTargetHighlight = () => {
    rootsList.querySelectorAll('.bookmark-root-toggle.drop-target').forEach((el) => {
      el.classList.remove('drop-target');
    });
  };

  rootsList.addEventListener('dragover', (event) => {
    if (!sidebarDraggingFolderId && !sidebarPlacementMode) return;
    const toggle = event.target.closest('.bookmark-root-toggle');
    if (!toggle) return;
    event.preventDefault();
    event.dataTransfer.dropEffect = 'move';
    clearDropTargetHighlight();
    toggle.classList.add('drop-target');
    scheduleSidebarRootSwitchDuringDrag(toggle.dataset.id);
  });

  rootsList.addEventListener('dragleave', (event) => {
    if (!rootsList.contains(event.relatedTarget)) {
      clearDropTargetHighlight();
      if (!sidebarPlacementMode) {
        clearSidebarRootHoverTimer();
      }
    }
  });

  rootsList.addEventListener('drop', (event) => {
    const toggle = event.target.closest('.bookmark-root-toggle');
    if (!toggle?.dataset?.id) return;

    event.preventDefault();
    event.stopPropagation();
    clearDropTargetHighlight();

    const folderId = sidebarPlacementFolderId || sidebarDraggingFolderId;
    if (!folderId) return;

    // 已在放置模式：放到该根顶级
    if (sidebarPlacementMode) {
      commitSidebarPlacementMove(folderId, toggle.dataset.id, 0);
      return;
    }

    // 未悬停切换完成就松开：直接移到该根顶级
    moveFolderToBookmarkRoot(folderId, toggle.dataset.id);
  });
}

// 侧边栏树结构为 li 与其子 ul 相邻，不能用 closest('li') 找父文件夹
function getSidebarDropParentId(dropList) {
  if (!dropList) {
    return getSelectedBookmarkRootId();
  }

  // 拖到某个文件夹的子列表：前一个兄弟 li 即父文件夹
  if (dropList.tagName === 'UL' && dropList.id !== 'categories-list') {
    const parentFolderLi = dropList.previousElementSibling;
    if (parentFolderLi?.classList?.contains('folder-item') && parentFolderLi.dataset.id) {
      return parentFolderLi.dataset.id;
    }

    const closestLi = dropList.closest('li.folder-item');
    if (closestLi?.dataset?.id) {
      return closestLi.dataset.id;
    }
  }

  // 拖到顶级树：父级为当前选中的根（书签栏 / Other / Mobile）
  return getSelectedBookmarkRootId();
}

function getAdjacentSidebarFolderItem(itemEl, direction) {
  let el = direction === 'prev' ? itemEl.previousElementSibling : itemEl.nextElementSibling;
  while (el) {
    if (el.matches?.('li.folder-item')) {
      return el;
    }
    el = direction === 'prev' ? el.previousElementSibling : el.nextElementSibling;
  }
  return null;
}

/**
 * Sortable 可能把 li 插到「另一文件夹 li」与「其子 ul」之间，破坏树结构。
 * 纠正拖拽项位置，并让每个文件夹的子列表紧跟其后。
 */
function normalizeSidebarFolderDomOrder(itemEl) {
  if (!itemEl?.isConnected) return;

  const next = itemEl.nextElementSibling;
  if (
    next?.tagName === 'UL' &&
    next.dataset.parentFolderId &&
    next.dataset.parentFolderId !== itemEl.dataset.id
  ) {
    next.insertAdjacentElement('afterend', itemEl);
  }

  syncFolderSublistWithItem(itemEl);

  const prevLi = getAdjacentSidebarFolderItem(itemEl, 'prev');
  if (prevLi) syncFolderSublistWithItem(prevLi);
  const nextLi = getAdjacentSidebarFolderItem(itemEl, 'next');
  if (nextLi) syncFolderSublistWithItem(nextLi);
}

/**
 * 将侧边栏「仅文件夹」的落点转换为 chrome.bookmarks.move 可用的 index。
 * Chrome 索引包含书签；同父级下移时传入值是「移除前」语义（finalIndex+1）。
 */
function resolveChromeSidebarFolderMoveIndex(itemId, newParentId, itemEl) {
  return new Promise((resolve, reject) => {
    chrome.bookmarks.get(itemId, (nodes) => {
      if (chrome.runtime.lastError || !nodes?.[0]) {
        reject(chrome.runtime.lastError || new Error('Folder not found'));
        return;
      }

      const { parentId: oldParentId, index: oldIndex } = nodes[0];
      const sameParent = oldParentId === newParentId;

      chrome.bookmarks.getChildren(newParentId, (children) => {
        if (chrome.runtime.lastError) {
          reject(chrome.runtime.lastError);
          return;
        }

        const prevFolder = getAdjacentSidebarFolderItem(itemEl, 'prev');
        const nextFolder = getAdjacentSidebarFolderItem(itemEl, 'next');
        let desiredFinalIndex;

        if (prevFolder) {
          const prevNode = children.find((child) => child.id === prevFolder.dataset.id);
          if (!prevNode) {
            desiredFinalIndex = sameParent ? oldIndex : children.length;
          } else if (sameParent && oldIndex < prevNode.index) {
            // 下移：移除后 prev 前移一位，插在其后 → final = prev 原 index
            desiredFinalIndex = prevNode.index;
          } else {
            desiredFinalIndex = prevNode.index + 1;
          }
        } else if (nextFolder) {
          const nextNode = children.find((child) => child.id === nextFolder.dataset.id);
          if (!nextNode) {
            desiredFinalIndex = 0;
          } else if (sameParent && oldIndex < nextNode.index) {
            desiredFinalIndex = Math.max(0, nextNode.index - 1);
          } else {
            desiredFinalIndex = nextNode.index;
          }
        } else {
          desiredFinalIndex = sameParent ? Math.max(0, children.length - 1) : children.length;
        }

        let apiIndex = desiredFinalIndex;
        if (sameParent && oldIndex < desiredFinalIndex) {
          apiIndex += 1;
        }

        const isNoOp = sameParent && (apiIndex === oldIndex || apiIndex === oldIndex + 1);
        resolve({ apiIndex, oldParentId, oldIndex, sameParent, isNoOp, desiredFinalIndex });
      });
    });
  });
}

let bookmarkCardSortables = [];
let sidebarSortables = [];
let bookmarksPreviewRefreshTimer = null;

function destroySortableInstances(instances) {
  instances.forEach((instance) => {
    try {
      instance.destroy();
    } catch (error) {
      // ignore already-destroyed instances
    }
  });
  instances.length = 0;
}

function scheduleBookmarksPreviewRefresh(delay = 450) {
  if (bookmarksPreviewRefreshTimer) {
    clearTimeout(bookmarksPreviewRefreshTimer);
  }

  bookmarksPreviewRefreshTimer = setTimeout(() => {
    bookmarksPreviewRefreshTimer = null;
    const rootId = getSelectedBookmarkRootId();
    const run = () => {
      updateBookmarksDisplay(rootId);
      updateFolderName(rootId);
    };

    if (typeof requestIdleCallback === 'function') {
      requestIdleCallback(run, { timeout: 1200 });
    } else {
      run();
    }
  }, delay);
}

function syncFolderSublistWithItem(folderLi) {
  if (!folderLi?.dataset?.id) return;

  const folderId = folderLi.dataset.id;
  let sublist = folderLi._associatedSublist;
  if (!sublist || !sublist.isConnected) {
    sublist = document.querySelector(`#categories-list ul[data-parent-folder-id="${folderId}"]`);
  }
  if (!sublist) return;

  if (folderLi.nextElementSibling !== sublist) {
    folderLi.insertAdjacentElement('afterend', sublist);
  }
}

function handleSidebarFolderMoved(itemEl, dropList) {
  const bookmarkId = itemEl.dataset.id;
  if (!bookmarkId) return;

  const newParentId = getSidebarDropParentId(dropList);
  if (!newParentId || bookmarkId === newParentId) {
    refreshBookmarkSidebar(bookmarkId);
    return;
  }

  normalizeSidebarFolderDomOrder(itemEl);
  itemEl.dataset.parentId = newParentId;

  resolveChromeSidebarFolderMoveIndex(bookmarkId, newParentId, itemEl)
    .then(({ apiIndex, isNoOp, oldParentId }) => {
      if (isNoOp) {
        // Sortable 已改 DOM，但 Chrome 认为位置未变 — 重建以保持一致
        refreshBookmarkSidebar(bookmarkId);
        return;
      }

      chrome.bookmarks.move(bookmarkId, { parentId: newParentId, index: apiIndex }, (result) => {
        if (chrome.runtime.lastError) {
          console.error('Error moving sidebar folder:', chrome.runtime.lastError);
          refreshBookmarkSidebar(bookmarkId);
          return;
        }

        if (oldParentId) bookmarksCache.delete(oldParentId);
        if (newParentId) bookmarksCache.delete(newParentId);
        bookmarksCache.delete(getSelectedBookmarkRootId());

        console.log('Sidebar folder moved:', {
          bookmarkId,
          newParentId,
          requestedIndex: apiIndex,
          resultIndex: result?.index
        });

        scheduleBookmarksPreviewRefresh();
      });
    })
    .catch((error) => {
      console.error('Error resolving sidebar folder move index:', error);
      refreshBookmarkSidebar(bookmarkId);
    });
}

function getAdjacentBookmarkCard(itemEl, direction) {
  let el = direction === 'prev' ? itemEl.previousElementSibling : itemEl.nextElementSibling;
  while (el) {
    if (el.matches?.('.bookmark-card, .bookmark-folder')) {
      return el;
    }
    el = direction === 'prev' ? el.previousElementSibling : el.nextElementSibling;
  }
  return null;
}

/**
 * Sortable 给出的是重排后的 DOM 位置；chrome.bookmarks.move 在同父级下移时
 * 需要「移除前」语义（目标 finalIndex 需 +1），且 DOM 只含链接而 Chrome 索引含文件夹。
 * 根据相邻卡片解析正确的 API index。
 */
function resolveChromeBookmarkMoveIndex(itemId, newParentId, itemEl) {
  return new Promise((resolve, reject) => {
    chrome.bookmarks.get(itemId, (nodes) => {
      if (chrome.runtime.lastError || !nodes?.[0]) {
        reject(chrome.runtime.lastError || new Error('Bookmark not found'));
        return;
      }

      const { parentId: oldParentId, index: oldIndex } = nodes[0];
      const sameParent = oldParentId === newParentId;

      chrome.bookmarks.getChildren(newParentId, (children) => {
        if (chrome.runtime.lastError) {
          reject(chrome.runtime.lastError);
          return;
        }

        const prevCard = getAdjacentBookmarkCard(itemEl, 'prev');
        const nextCard = getAdjacentBookmarkCard(itemEl, 'next');
        let desiredFinalIndex;

        if (prevCard) {
          const prevNode = children.find((child) => child.id === prevCard.dataset.id);
          if (!prevNode) {
            desiredFinalIndex = sameParent ? oldIndex : children.length;
          } else if (sameParent && oldIndex < prevNode.index) {
            // 当前在 prev 之前：移除后 prev 前移，插在其后 → final = prev 原 index
            desiredFinalIndex = prevNode.index;
          } else {
            desiredFinalIndex = prevNode.index + 1;
          }
        } else if (nextCard) {
          const nextNode = children.find((child) => child.id === nextCard.dataset.id);
          if (!nextNode) {
            desiredFinalIndex = 0;
          } else if (sameParent && oldIndex < nextNode.index) {
            desiredFinalIndex = Math.max(0, nextNode.index - 1);
          } else {
            desiredFinalIndex = nextNode.index;
          }
        } else {
          desiredFinalIndex = sameParent ? Math.max(0, children.length - 1) : children.length;
        }

        // Chromium：同父级且目标在旧位置之后时，传入 finalIndex+1
        let apiIndex = desiredFinalIndex;
        if (sameParent && oldIndex < desiredFinalIndex) {
          apiIndex += 1;
        }

        // Chromium 对 index === oldIndex | oldIndex+1 直接 no-op
        const isNoOp = sameParent && (apiIndex === oldIndex || apiIndex === oldIndex + 1);

        resolve({ apiIndex, oldParentId, oldIndex, sameParent, isNoOp });
      });
    });
  });
}

function setupBookmarkCardsSortable() {
  destroySortableInstances(bookmarkCardSortables);

  const bookmarksList = document.getElementById('bookmarks-list');
  if (!bookmarksList) {
    return;
  }

  bookmarksList.querySelectorAll('.bookmark-section-items').forEach((container) => {
    const sortable = new Sortable(container, {
      animation: 150,
      group: 'bookmark-cards',
      filter: '.bookmark-add-card, .bookmark-section-header',
      draggable: '.bookmark-card, .bookmark-folder',
      onEnd: function (evt) {
        const itemId = evt.item.dataset.id;
        const newParentId = evt.to.dataset.parentId || bookmarksList.dataset.parentId;
        evt.item.dataset.parentId = newParentId;

        showMovingFeedback(evt.item);

        moveBookmark(itemId, newParentId, evt.item)
          .then(() => {
            hideMovingFeedback(evt.item);
            showSuccessFeedback(evt.item);
          })
          .catch((error) => {
            console.error('Error moving bookmark:', error);
            hideMovingFeedback(evt.item);
            showErrorFeedback(evt.item);
            syncBookmarkOrder(newParentId);
          });
      }
    });
    bookmarkCardSortables.push(sortable);
  });
}

function setupSidebarSortable() {
  destroySortableInstances(sidebarSortables);

  const categoriesList = document.getElementById('categories-list');
  if (!categoriesList) {
    return;
  }

  const sharedSortableOptions = {
    animation: 150,
    group: 'nested',
    draggable: 'li.folder-item',
    // 避免轻微抖动被当成拖拽从而吞掉 click（表现为要点多次才能打开）
    distance: 8,
    filter: '.folder-expand-toggle',
    preventOnFilter: true,
    // 强制鼠标跟随模式，保证悬停根目录时能持续收到 mousemove
    forceFallback: true,
    fallbackOnBody: true,
    fallbackClass: 'sidebar-folder-drag-fallback',
    ghostClass: 'sidebar-folder-drag-ghost',
    chosenClass: 'sidebar-folder-drag-chosen',
    dragClass: 'sidebar-folder-drag-active',
    swapThreshold: 0.65,
    onStart: function (evt) {
      sidebarDraggingFolderId = evt.item.dataset.id || null;
      sidebarPlacementFolderTitle = getSidebarFolderTitle(sidebarDraggingFolderId);
      sidebarPlacementSourceRootId = getSelectedBookmarkRootId();
      document.body.classList.add('is-dragging-sidebar-folder');
      ensureSidebarPlacementUi();
      const next = evt.item.nextElementSibling;
      evt.item._associatedSublist =
        next &&
        next.tagName === 'UL' &&
        next.dataset.parentFolderId === evt.item.dataset.id
          ? next
          : document.querySelector(`#categories-list ul[data-parent-folder-id="${evt.item.dataset.id}"]`);
    },
    onMove: function (evt, originalEvent) {
      // 拖拽过程中同步检测根目录悬停（比只靠 document 事件更稳）
      if (!sidebarDraggingFolderId || sidebarPlacementMode) return true;
      const clientX = originalEvent?.clientX;
      const clientY = originalEvent?.clientY;
      if (typeof clientX !== 'number') return true;

      const toggle = getBookmarkRootToggleAtPoint(clientX, clientY);
      if (toggle?.dataset?.id) {
        document.querySelectorAll('#bookmark-roots-list .bookmark-root-toggle.drop-target').forEach((item) => {
          item.classList.toggle('drop-target', item === toggle);
        });
        scheduleSidebarRootSwitchDuringDrag(toggle.dataset.id);
      }
      return true;
    },
    onEnd: function (evt) {
      // 跨根放置模式：由 placement 逻辑处理，忽略 Sortable 落点
      if (sidebarPlacementMode || sidebarCrossRootMovePending) {
        // Sortable 结束时可能晚一拍挂上 fallback 克隆，再清一次
        requestAnimationFrame(() => {
          removeSortableDragClones();
          setTimeout(removeSortableDragClones, 0);
        });
        return;
      }

      clearSidebarRootHoverTimer();

      // 快速拖放到根目录按钮（未等悬停切换）：移到该根顶级
      const pointerEvent = evt.originalEvent;
      if (pointerEvent && typeof pointerEvent.clientX === 'number') {
        const rootToggle = getBookmarkRootToggleAtPoint(pointerEvent.clientX, pointerEvent.clientY);
        if (rootToggle?.dataset?.id && evt.item?.dataset?.id) {
          moveFolderToBookmarkRoot(evt.item.dataset.id, rootToggle.dataset.id);
          return;
        }
      }

      clearSidebarFolderDragState();

      // 未发生排序（等同点击）：确保打开该文件夹内容
      if (evt.oldIndex === evt.newIndex && evt.from === evt.to) {
        const folderId = evt.item?.dataset?.id;
        if (folderId) {
          focusSidebarFolderSection(folderId);
        }
        return;
      }

      // Sortable 可能把 li 插到「文件夹 li」与「其子 ul」之间，先纠正再写 Chrome
      normalizeSidebarFolderDomOrder(evt.item);
      handleSidebarFolderMoved(evt.item, evt.to);
    }
  };

  const rootSortable = new Sortable(categoriesList, sharedSortableOptions);
  sidebarSortables.push(rootSortable);

  categoriesList.querySelectorAll('ul[data-parent-folder-id]').forEach((folder) => {
    const nestedSortable = new Sortable(folder, sharedSortableOptions);
    sidebarSortables.push(nestedSortable);
  });
}

function setupSortable() {
  setupBookmarkCardsSortable();
  setupSidebarSortable();
}

function moveBookmark(itemId, newParentId, itemEl) {
  return resolveChromeBookmarkMoveIndex(itemId, newParentId, itemEl).then(
    ({ apiIndex, isNoOp, oldParentId }) => {
      if (isNoOp) {
        console.log(`Bookmark ${itemId} already at target position`);
        return updateAffectedBookmarks(newParentId, itemId, apiIndex).then(() => ({
          id: itemId,
          parentId: newParentId,
          index: apiIndex
        }));
      }

      return new Promise((resolve, reject) => {
        const destination = { index: apiIndex };
        if (newParentId) {
          destination.parentId = newParentId;
        }
        chrome.bookmarks.move(itemId, destination, (result) => {
          if (chrome.runtime.lastError) {
            console.error('Error moving bookmark:', chrome.runtime.lastError);
            reject(chrome.runtime.lastError);
            return;
          }

          console.log(`Bookmark ${itemId} moved to index ${result.index}`);
          if (oldParentId && oldParentId !== newParentId) {
            bookmarksCache.delete(oldParentId);
          }
          updateAffectedBookmarks(newParentId, itemId, result.index)
            .then(() => {
              console.log(`Bookmark ${itemId} position updated in UI`);
              resolve(result);
            })
            .catch(reject);
        });
      });
    }
  );
}

function updateAffectedBookmarks(parentId, movedItemId, newIndex) {
  return new Promise((resolve, reject) => {
    const bookmarksList = document.getElementById('bookmarks-list');
    const movedElement = bookmarksList?.querySelector(`[data-id="${movedItemId}"]`);

    // 侧边栏文件夹拖拽时，主列表可能没有对应卡片，视为成功即可
    if (!movedElement) {
      console.log(`Moved item ${movedItemId} not in bookmarks list (likely sidebar folder move)`);
      resolve();
      return;
    }

    const parentContainer = movedElement.closest('.bookmark-section-items') || bookmarksList;
    const bookmarkElements = Array.from(
      parentContainer.querySelectorAll(':scope > .bookmark-card, :scope > .bookmark-folder')
    );

    highlightBookmark(movedItemId);
    bookmarkOrderCache[parentId] = bookmarkElements.map(el => el.dataset.id);
    console.log(`UI updated: Bookmark ${movedItemId} at index ${newIndex}`);
    resolve();
  });
}

function highlightBookmark(itemId) {
  const bookmarkElement = document.querySelector(`[data-id="${itemId}"]`);
  if (bookmarkElement) {
    bookmarkElement.style.transition = 'background-color 0.5s ease';
    bookmarkElement.style.backgroundColor = '#ffff99';
    setTimeout(() => {
      bookmarkElement.style.backgroundColor = '';
    }, 1000);
  }
}

function refreshBookmarkSidebar(selectFolderId) {
  return new Promise((resolve, reject) => {
    chrome.bookmarks.getTree((nodes) => {
      if (chrome.runtime.lastError) {
        reject(chrome.runtime.lastError);
        return;
      }

      bookmarkTreeNodes = nodes;
      displayBookmarkCategories(nodes[0].children || [], 0, null, '1');

      if (selectFolderId) {
        selectSidebarFolder(selectFolderId);
      }

      resolve(nodes);
    });
  });
}

function openFolderDialog({ mode, folderId, parentId, currentTitle = '' }) {
  const dialog = document.getElementById('edit-category-dialog');
  const form = document.getElementById('edit-category-form');
  const input = document.getElementById('edit-category-name');
  const titleEl = dialog?.querySelector('h2');
  const cancelButton = dialog?.querySelector('.cancel-category-button');
  const closeButton = dialog?.querySelector('.close-category-button');

  if (!dialog || !form || !input) {
    console.error('Folder dialog elements not found');
    return;
  }

  if (titleEl) {
    titleEl.textContent = mode === 'create'
      ? (getLocalizedMessage('createFolderTitle') || 'New Folder')
      : (getLocalizedMessage('renameFolderTitle') || 'Rename Folder');
  }

  input.value = mode === 'create' ? '' : (currentTitle || '');
  dialog.style.display = 'block';
  setTimeout(() => input.focus(), 0);

  const closeDialog = () => {
    dialog.style.display = 'none';
  };

  form.onsubmit = function (event) {
    event.preventDefault();
    const title = input.value.trim();
    if (!title) return;

    if (mode === 'create') {
      const targetParentId = parentId || getSelectedBookmarkRootId();
      chrome.bookmarks.create({ parentId: targetParentId, title }, (result) => {
        if (chrome.runtime.lastError) {
          console.error('Error creating folder:', chrome.runtime.lastError);
          Utilities.showToast(chrome.runtime.lastError.message);
          return;
        }

        closeDialog();
        bookmarksCache.clear();
        refreshBookmarkSidebar(result.id).then(() => {
          updateBookmarksDisplay(targetParentId);
          updateFolderName(targetParentId);
        });
      });
      return;
    }

    chrome.bookmarks.update(folderId, { title }, () => {
      if (chrome.runtime.lastError) {
        console.error('Error renaming folder:', chrome.runtime.lastError);
        Utilities.showToast(chrome.runtime.lastError.message);
        return;
      }

      closeDialog();
      updateCategoryUI(folderId, title);
    });
  };

  if (cancelButton) cancelButton.onclick = closeDialog;
  if (closeButton) closeButton.onclick = closeDialog;
}

function openCreateFolderDialog(parentId) {
  openFolderDialog({ mode: 'create', parentId });
}

function openRenameFolderDialog(folderId, currentTitle) {
  openFolderDialog({ mode: 'rename', folderId, currentTitle });
}

function deleteSidebarFolder(folderId, folderTitle, parentId) {
  const message = chrome.i18n.getMessage('confirmDeleteFolder', [`<strong>${folderTitle}</strong>`]);
  showConfirmDialog(message, () => {
    chrome.bookmarks.removeTree(folderId, async () => {
      if (chrome.runtime.lastError) {
        console.error('Error deleting folder:', chrome.runtime.lastError);
        Utilities.showToast(getLocalizedMessage('deleteFolderError'));
        return;
      }

      bookmarksCache.clear();
      Utilities.showToast(getLocalizedMessage('categoryDeleted') || getLocalizedMessage('deleteSuccess'));

      const fallbackParentId = parentId || getSelectedBookmarkRootId();
      const currentParentId = document.getElementById('bookmarks-list')?.dataset.parentId;
      const nextFolderId = currentParentId === folderId ? fallbackParentId : (currentParentId || fallbackParentId);

      await refreshBookmarkSidebar(nextFolderId);
      await updateBookmarksDisplay(nextFolderId);
      updateFolderName(nextFolderId);
      selectSidebarFolder(nextFolderId);
    });
  });
}

function initFolderTreeCrud() {
  const createFolderBtn = document.getElementById('create-folder-btn');
  if (createFolderBtn) {
    const label = createFolderBtn.querySelector('.bookmark-tree-action-label');
    const folderLabel = getLocalizedMessage('newFolder') || 'New Folder';
    if (label) {
      label.textContent = folderLabel;
    } else {
      createFolderBtn.textContent = folderLabel;
    }
    createFolderBtn.addEventListener('click', (event) => {
      event.preventDefault();
      event.stopPropagation();
      openCreateFolderDialog(getSelectedBookmarkRootId());
    });
  }

  const treeColumn = document.querySelector('.bookmark-tree-column');
  if (treeColumn) {
    treeColumn.addEventListener('contextmenu', (event) => {
      if (event.target.closest('#categories-list li')) {
        return;
      }
      event.preventDefault();
      openCreateFolderDialog(getSelectedBookmarkRootId());
    });
  }
}

function getSidebarSearchResultHostname(url) {
  if (!url) return '';
  try {
    return new URL(url).hostname.replace(/^www\./, '');
  } catch {
    return url;
  }
}

const sidebarBookmarkSearchState = {
  requestId: 0,
  debounceTimer: null
};

function clearSidebarBookmarkSearch({ restoreFocus = true } = {}) {
  const input = document.getElementById('sidebar-bookmark-search-input');
  const clearBtn = document.getElementById('sidebar-bookmark-search-clear');
  const resultsEl = document.getElementById('sidebar-bookmark-search-results');
  const nav = document.querySelector('.bookmark-sidebar-nav');

  sidebarBookmarkSearchState.requestId += 1;
  if (sidebarBookmarkSearchState.debounceTimer) {
    clearTimeout(sidebarBookmarkSearchState.debounceTimer);
    sidebarBookmarkSearchState.debounceTimer = null;
  }

  if (input) input.value = '';
  if (clearBtn) clearBtn.hidden = true;
  if (resultsEl) {
    resultsEl.innerHTML = '';
    resultsEl.hidden = true;
  }
  nav?.classList.remove('is-sidebar-searching');
  if (restoreFocus) input?.focus();
}

function createSidebarBookmarkSearchItem(node) {
  const isFolder = !node.url;
  const item = document.createElement(isFolder ? 'button' : 'a');
  if (isFolder) {
    item.type = 'button';
  } else {
    item.href = node.url;
  }
  item.className = 'sidebar-bookmark-search-item';
  item.dataset.id = node.id;
  item.setAttribute('role', 'option');

  const iconWrap = document.createElement('span');
  iconWrap.className = 'sidebar-bookmark-search-item-icon';
  if (isFolder) {
    iconWrap.innerHTML = ICONS.folder;
  } else {
    const img = document.createElement('img');
    img.alt = '';
    img.decoding = 'async';
    img.loading = 'lazy';
    applyFaviconWithFallback(img, node.url);
    iconWrap.appendChild(img);
  }

  const textWrap = document.createElement('span');
  textWrap.className = 'sidebar-bookmark-search-item-text';

  const title = document.createElement('span');
  title.className = 'sidebar-bookmark-search-item-title';
  title.textContent = node.title || (isFolder
    ? (getLocalizedMessage('sidebarBookmarkSearchFolder') || 'Folder')
    : getSidebarSearchResultHostname(node.url));

  const meta = document.createElement('span');
  meta.className = 'sidebar-bookmark-search-item-meta';
  meta.textContent = isFolder
    ? (getLocalizedMessage('sidebarBookmarkSearchFolder') || 'Folder')
    : getSidebarSearchResultHostname(node.url);

  textWrap.appendChild(title);
  textWrap.appendChild(meta);
  item.appendChild(iconWrap);
  item.appendChild(textWrap);

  if (node.parentId) {
    chrome.bookmarks.get(node.parentId, (parents) => {
      if (chrome.runtime.lastError || !parents?.[0] || !item.isConnected) return;
      const parentTitle = (parents[0].title || '').trim();
      if (!parentTitle || parents[0].parentId === '0') return;
      if (isFolder) {
        meta.textContent = parentTitle;
      } else {
        const host = getSidebarSearchResultHostname(node.url);
        meta.textContent = host ? `${parentTitle} · ${host}` : parentTitle;
      }
    });
  }

  if (isFolder) {
    item.addEventListener('click', (event) => {
      event.preventDefault();
      clearSidebarBookmarkSearch({ restoreFocus: false });
      focusSidebarFolderSection(node.id);
    });
  }

  return item;
}

function initSidebarBookmarkSearch() {
  const nav = document.querySelector('.bookmark-sidebar-nav');
  const input = document.getElementById('sidebar-bookmark-search-input');
  const clearBtn = document.getElementById('sidebar-bookmark-search-clear');
  const resultsEl = document.getElementById('sidebar-bookmark-search-results');
  const iconEl = document.querySelector('.sidebar-bookmark-search-icon');
  if (!nav || !input || !clearBtn || !resultsEl) return;

  if (iconEl && ICONS.search) {
    iconEl.innerHTML = ICONS.search;
  }

  const clearLabel = getLocalizedMessage('sidebarBookmarkSearchClear') || 'Clear';
  clearBtn.title = clearLabel;
  clearBtn.setAttribute('aria-label', clearLabel);

  const MAX_RESULTS = 40;

  const renderResults = (nodes, query) => {
    resultsEl.innerHTML = '';
    if (!query) {
      resultsEl.hidden = true;
      nav.classList.remove('is-sidebar-searching');
      return;
    }

    nav.classList.add('is-sidebar-searching');
    resultsEl.hidden = false;

    if (!nodes.length) {
      const empty = document.createElement('div');
      empty.className = 'sidebar-bookmark-search-empty';
      empty.textContent = getLocalizedMessage('sidebarBookmarkSearchNoResults') || 'No results';
      resultsEl.appendChild(empty);
      return;
    }

    const folders = nodes.filter((node) => !node.url);
    const bookmarks = nodes.filter((node) => !!node.url);
    [...folders, ...bookmarks].forEach((node) => {
      resultsEl.appendChild(createSidebarBookmarkSearchItem(node));
    });
  };

  const runSearch = (rawQuery) => {
    const query = rawQuery.trim();
    clearBtn.hidden = !rawQuery;
    if (!query) {
      renderResults([], '');
      return;
    }

    const currentRequest = ++sidebarBookmarkSearchState.requestId;
    chrome.bookmarks.search(query, (results) => {
      if (currentRequest !== sidebarBookmarkSearchState.requestId) return;
      if (chrome.runtime.lastError) {
        console.error('Sidebar bookmark search failed:', chrome.runtime.lastError);
        renderResults([], query);
        return;
      }

      const filtered = (results || [])
        .filter((node) => node && node.parentId && node.parentId !== '0')
        .slice(0, MAX_RESULTS);
      renderResults(filtered, query);
    });
  };

  clearBtn.addEventListener('click', (event) => {
    event.preventDefault();
    clearSidebarBookmarkSearch({ restoreFocus: true });
  });

  input.addEventListener('keydown', (event) => {
    if (event.key === 'Escape') {
      event.preventDefault();
      if (input.value) {
        clearSidebarBookmarkSearch({ restoreFocus: true });
      } else {
        input.blur();
      }
    }
  });

  input.addEventListener('input', () => {
    const value = input.value;
    clearBtn.hidden = !value;
    if (sidebarBookmarkSearchState.debounceTimer) {
      clearTimeout(sidebarBookmarkSearchState.debounceTimer);
    }
    sidebarBookmarkSearchState.debounceTimer = setTimeout(() => {
      sidebarBookmarkSearchState.debounceTimer = null;
      runSearch(value);
    }, 160);
  });
}

function isPrimaryBookmarkRoot(bookmark) {
  // 显示所有顶级书签文件夹（书签栏、其他书签、移动书签等）
  return bookmark && !bookmark.url;
}

function getInitialBookmarkRoot(rootNodes) {
  const savedRootId = localStorage.getItem('selectedBookmarkRootId');
  const savedRoot = rootNodes.find(node => node.id === savedRootId);
  if (savedRoot) {
    return savedRoot;
  }

  return rootNodes.find(node => node.id === '1') || rootNodes[0];
}

function getBookmarkRootToggleLabel(title) {
  const label = (title || '').trim();
  if (!label) return '';

  return label
    .replace(/\s*bookmarks?\s*/gi, ' ')
    .replace(/\s*书签\s*/g, ' ')
    .replace(/\s*書籤\s*/g, ' ')
    .replace(/\s+/g, ' ')
    .trim() || label;
}

function switchToBookmarkRoot(rootId, options = {}) {
  const { updateMainView = true } = options;
  const categoriesList = document.getElementById('categories-list');
  if (!rootId || !categoriesList) {
    return;
  }

  localStorage.setItem('selectedBookmarkRootId', rootId);
  chrome.storage.local.set({
    lastViewedFolder: rootId,
    lastViewedTime: Date.now()
  });

  document.querySelectorAll('#bookmark-roots-list .bookmark-root-toggle').forEach((item) => {
    const isActive = item.dataset.id === rootId;
    item.classList.toggle('active', isActive);
    item.setAttribute('aria-pressed', isActive ? 'true' : 'false');
  });

  chrome.bookmarks.getSubTree(rootId, (subtrees) => {
    if (chrome.runtime.lastError) {
      console.error('Error loading bookmark root:', chrome.runtime.lastError);
      return;
    }

    const rootNode = subtrees?.[0];
    categoriesList.innerHTML = '';
    displayBookmarkCategories(rootNode?.children || [], 0, categoriesList, rootId);

    if (updateMainView) {
      updateBookmarksDisplay(rootId);
      updateFolderName(rootId);
    }
  });
}

function renderBookmarkRootList(rootNodes) {
  const rootsList = document.getElementById('bookmark-roots-list');
  const categoriesList = document.getElementById('categories-list');
  if (!rootsList || !categoriesList) {
    return null;
  }

  rootsList.innerHTML = '';
  setupBookmarkRootDropTargets();

  const roots = rootNodes.filter(isPrimaryBookmarkRoot);
  const selectedRoot = getInitialBookmarkRoot(roots);

  roots.forEach(root => {
    const button = document.createElement('button');
    button.type = 'button';
    button.className = 'bookmark-root-toggle';
    button.dataset.id = root.id;
    button.dataset.title = root.title;
    button.title = root.title;
    button.textContent = getBookmarkRootToggleLabel(root.title);
    button.setAttribute('aria-pressed', 'false');

    button.addEventListener('click', function (event) {
      event.stopPropagation();
      // 始终重新拉取子树，避免跨根拖拽后仍使用过期的 root.children
      switchToBookmarkRoot(root.id);
    });

    rootsList.appendChild(button);
  });

  if (selectedRoot) {
    const selectedEl = rootsList.querySelector(`.bookmark-root-toggle[data-id="${selectedRoot.id}"]`);
    if (selectedEl) {
      selectedEl.classList.add('active');
      selectedEl.setAttribute('aria-pressed', 'true');
    }
  }

  return selectedRoot;
}

// 修改 displayBookmarkCategories 函数，添加清理逻辑
function displayBookmarkCategories(bookmarkNodes, level, parentUl, parentId) {
  const categoriesList = parentUl || document.getElementById('categories-list');

  // 如果是根级调用，先清空现有内容
  if (!parentUl) {
    destroySortableInstances(sidebarSortables);
    const selectedRoot = renderBookmarkRootList(bookmarkNodes);
    categoriesList.innerHTML = '';
    if (selectedRoot) {
      displayBookmarkCategories(selectedRoot.children || [], 0, categoriesList, selectedRoot.id);
    }
    return;
  }

  // 切换顶级文件夹时，第二栏必须先清空；否则无子文件夹的根目录会残留旧树
  if (level === 0 && categoriesList?.id === 'categories-list') {
    destroySortableInstances(sidebarSortables);
    categoriesList.innerHTML = '';
  }

  bookmarkNodes.forEach(function (bookmark) {
    if (bookmark.children) {
      let li = document.createElement('li');
      li.className = 'cursor-pointer p-2 hover:bg-emerald-500 rounded-lg flex items-center folder-item';
      li.style.paddingLeft = `${(level * 20) + 8}px`;
      li.dataset.title = bookmark.title;
      li.dataset.id = bookmark.id;
      li.dataset.parentId = parentId;

      let span = document.createElement('span');
      span.textContent = bookmark.title;

      const folderIcon = document.createElement('span');
      folderIcon.className = 'material-icons mr-2 folder-type-icon';
      folderIcon.innerHTML = ICONS.folder;
      li.insertBefore(folderIcon, li.firstChild);

      const hasSubfolders = bookmark.children.some(child => child.children);
      let arrowIcon;

      const sublist = document.createElement('ul');
      sublist.className = 'pl-4 space-y-2';
      sublist.style.display = 'none';
      sublist.dataset.parentFolderId = bookmark.id;

      if (hasSubfolders) {
        arrowIcon = document.createElement('span');
        arrowIcon.className = 'material-icons ml-auto folder-expand-toggle';
        arrowIcon.setAttribute('role', 'button');
        arrowIcon.setAttribute('tabindex', '0');
        arrowIcon.setAttribute('aria-expanded', 'false');
        arrowIcon.setAttribute('aria-label', 'Expand folder');
        arrowIcon.innerHTML = ICONS.chevron_right;

        const toggleExpand = function (event) {
          event.preventDefault();
          event.stopPropagation();
          const isExpanded = sublist.style.display === 'block';
          const nextExpanded = !isExpanded;
          sublist.style.display = nextExpanded ? 'block' : 'none';
          arrowIcon.innerHTML = nextExpanded ? ICONS.expand_less : ICONS.chevron_right;
          arrowIcon.setAttribute('aria-expanded', nextExpanded ? 'true' : 'false');
        };

        arrowIcon.addEventListener('click', toggleExpand);
        arrowIcon.addEventListener('keydown', function (event) {
          if (event.key === 'Enter' || event.key === ' ') {
            toggleExpand(event);
          }
        });
        li.appendChild(arrowIcon);
      }

      // 用 pointer 判定点击，避免 Sortable 在轻微移动时吞掉 click
      let folderPointerStart = null;
      li.addEventListener('pointerdown', function (event) {
        if (event.button !== 0) return;
        if (event.target.closest('.folder-expand-toggle')) {
          folderPointerStart = null;
          return;
        }
        folderPointerStart = { x: event.clientX, y: event.clientY, pointerId: event.pointerId };
      });
      li.addEventListener('pointercancel', function () {
        folderPointerStart = null;
      });
      li.addEventListener('pointerup', function (event) {
        if (!folderPointerStart || event.pointerId !== folderPointerStart.pointerId) return;
        if (event.target.closest('.folder-expand-toggle')) {
          folderPointerStart = null;
          return;
        }
        const dx = Math.abs(event.clientX - folderPointerStart.x);
        const dy = Math.abs(event.clientY - folderPointerStart.y);
        folderPointerStart = null;
        if (dx > 8 || dy > 8) return;

        event.stopPropagation();
        document.querySelectorAll('#categories-list li').forEach(function (item) {
          item.classList.remove('bg-emerald-500');
        });
        li.classList.add('bg-emerald-500');
        focusSidebarFolderSection(bookmark.id);
      });
      // 保留 click 作为兜底（部分环境下 pointerup 后仍会有可靠 click）
      li.addEventListener('click', function (event) {
        if (event.target.closest('.folder-expand-toggle')) return;
        event.stopPropagation();
        document.querySelectorAll('#categories-list li').forEach(function (item) {
          item.classList.remove('bg-emerald-500');
        });
        li.classList.add('bg-emerald-500');
        focusSidebarFolderSection(bookmark.id);
      });

      li.appendChild(span);
      categoriesList.appendChild(li);
      categoriesList.appendChild(sublist);

      displayBookmarkCategories(bookmark.children, level + 1, sublist, bookmark.id);
    }
  });

  // 仅在整棵树构建完成后初始化一次 Sortable，避免递归重复创建实例
  if (level === 0) {
    setupSidebarSortable();
    // 树重建后同步 Homepage 固定指示
    updateSidebarHomepageIndicators();
  }
}

// 添加一个获取文件夹内书签数量的函数
function getFolderBookmarkCount(folderId) {
  return new Promise((resolve) => {
    let count = 0;

    function countBookmarks(bookmarkNodes) {
      bookmarkNodes.forEach(node => {
        if (node.url) {
          count++;
        }
        if (node.children) {
          countBookmarks(node.children);
        }
      });
    }

    chrome.bookmarks.getChildren(folderId, (children) => {
      if (chrome.runtime.lastError) {
        resolve(0);
        return;
      }
      countBookmarks(children);
      resolve(count);
    });
  });
}
// 新增辅助函数
async function isDefaultFolder(folderId) {
  if (!folderId) return false;

  const data = await chrome.storage.sync.get('defaultFolders');
  const defaultFolders = data.defaultFolders?.items || [];
  return defaultFolders.some(folder => folder.id === folderId);
}
// 创建文件夹上下文菜单
function createBookmarkFolderContextMenu() {
  console.log('Creating folder context menu');

  // 移除任何已存在的上下文菜单
  const existingMenu = document.querySelector('.bookmark-folder-context-menu');
  if (existingMenu) {
    existingMenu.remove();
  }

  const menu = document.createElement('div');
  menu.className = 'bookmark-folder-context-menu custom-context-menu';
  document.body.appendChild(menu);

  // 异步创建菜单项
  createMenuItems(menu).catch(error => {
    console.error('Error creating menu items:', error);
  });

  return menu;
}

async function createMenuItems(menu) {  
  console.log('=== Creating Menu Items ===');
  console.log('Current bookmark folder:', currentBookmarkFolder);
  
  // 清空现有菜单项
  menu.innerHTML = '';

  // 每次创建菜单时重新检查当前文件夹的状态
  let isDefault = false;
  if (currentBookmarkFolder?.dataset?.id) {
    try {
      // 确保在获取状态前等待 chrome.storage.sync.get 完成
      const data = await chrome.storage.sync.get('defaultFolders');
      const defaultFolders = data.defaultFolders?.items || [];
      isDefault = defaultFolders.some(folder => folder.id === currentBookmarkFolder.dataset.id);
      
      console.log('Folder status check:', {
        folderId: currentBookmarkFolder.dataset.id,
        isDefault: isDefault,
        defaultFolders: defaultFolders,
        folderTitle: currentBookmarkFolder.querySelector('.card-title')?.textContent
      });
    } catch (error) {
      console.error('Error checking default folder status:', error);
      isDefault = false;
    }
  }

  const menuItems = [
    { 
      text: getLocalizedMessage('openAllBookmarks'),
      icon: 'open_in_new',  
      action: () => {
        if (currentBookmarkFolder) {
          const folderId = currentBookmarkFolder.dataset.id;
          const folderTitle = currentBookmarkFolder.querySelector('.card-title').textContent;
          
          chrome.bookmarks.getChildren(folderId, (bookmarks) => {
            // 过滤出有效的书签URL
            const validUrls = bookmarks
              .filter(bookmark => bookmark.url)
              .map(bookmark => bookmark.url);

            if (validUrls.length > 0) {
              openMultipleTabsAndGroup(validUrls, folderTitle).then((response) => {
                if (response?.success) {
                  console.log('Bookmarks opened in new tab group');
                } else {
                  console.error('Error opening bookmarks:', response?.error);
                }
              });
            }
          });
        }
      }
    },
    // 原有的菜单项
    { text: getLocalizedMessage('rename'), icon: 'edit', action: () => currentBookmarkFolder && openEditBookmarkFolderDialog(currentBookmarkFolder) },
    { text: getLocalizedMessage('delete'), icon: 'delete', action: () => {
      if (currentBookmarkFolder) {
        const folderId = currentBookmarkFolder.dataset.id;
        const folderTitle = currentBookmarkFolder.querySelector('.card-title').textContent;
        const parentId = currentBookmarkFolder.dataset.parentId || '1';
        
        showConfirmDialog(chrome.i18n.getMessage("confirmDeleteFolder", [`<strong>${folderTitle}</strong>`]), async () => {
          try {
            await chrome.bookmarks.removeTree(folderId);
            
            // 1. 立即从 UI 中移除文件夹卡片
            const folderCard = document.querySelector(`.bookmark-folder[data-id="${folderId}"]`);
            if (folderCard) {
              folderCard.remove();
            }
            
            // 2. 从侧边栏中移除对应的文件夹及其所有子文件夹
            const sidebarFolder = document.querySelector(`#categories-list li[data-id="${folderId}"]`);
            if (sidebarFolder) {
              // 获取并移除所有子文件夹
              const subFolders = sidebarFolder.querySelectorAll('ul');
              subFolders.forEach(ul => ul.remove());
              sidebarFolder.remove();
            }

            // 3. 清除相关缓存
            if (bookmarksCache.data.has(folderId)) {
              bookmarksCache.delete(folderId);
            }
            if (bookmarksCache.data.has(parentId)) {
              bookmarksCache.delete(parentId);
            }
            
            // 4. 显示删除成功的 toast 消息
            Utilities.showToast(getLocalizedMessage('deleteSuccess'));

            // 5. 如果删除的是当前显示的文件夹，则返回上一级并重新加载
            const bookmarksList = document.getElementById('bookmarks-list');
            if (bookmarksList.dataset.parentId === folderId) {
              await updateBookmarksDisplay(parentId);
              updateFolderName(parentId);
              selectSidebarFolder(parentId);
            }

            // 6. 重新加载父文件夹的内容
            const parentFolder = document.querySelector(`.bookmark-folder[data-id="${parentId}"]`);
            if (parentFolder) {
              await updateBookmarksDisplay(parentId);
            }

          } catch (error) {
            console.error('Error deleting folder:', error);
            Utilities.showToast(getLocalizedMessage('deleteFolderError'));
          }
        });
      }
    }},
    {
      // 根据当前状态设置文本
      text: isDefault ? getLocalizedMessage('removeFromDefaultFolders') : getLocalizedMessage('addToDefaultFolders'),
      icon: isDefault ? 'keep_off' : 'keep',
      action: async () => {
        const folder = currentBookmarkFolder;
        console.log('Toggle default folder action triggered:', {
          folder: folder,
          folderId: folder?.dataset?.id,
          currentIsDefault: isDefault
        });

        if (!folder?.dataset?.id) {
          console.error('No valid folder selected');
          return;
        }

        await toggleDefaultFolder(folder);
        
        // 重新获取当前状态
        const data = await chrome.storage.sync.get('defaultFolders');
        const defaultFolders = data.defaultFolders?.items || [];
        const newIsDefault = defaultFolders.some(f => f.id === folder.dataset.id);
        
        console.log('Menu item status update:', {
          oldState: isDefault,
          newState: newIsDefault,
          folderId: folder.dataset.id,
          defaultFolders: defaultFolders
        });

        const menuItem = menu.querySelector(`[data-action="toggleDefault"]`);
        if (menuItem) {
          const newText = getLocalizedMessage(newIsDefault ? 'removeFromDefaultFolders' : 'addToDefaultFolders');
          console.log('Updating menu item text to:', newText);
          
          menuItem.querySelector('.text').textContent = newText;
          const iconElement = menuItem.querySelector('.icon-svg');
          if (iconElement) {
            iconElement.innerHTML = ICONS[newIsDefault ? 'keep_off' : 'keep'];
          }
        }
      }
    }
  ];

  // 创建菜单项
  menuItems.forEach((item, index) => {
    console.log(`Creating menu item ${index}:`, {
      text: item.text,
      icon: item.icon
    });
    const menuItem = document.createElement('div');
    menuItem.className = 'custom-context-menu-item';
    
    if (item.icon === 'keep' || item.icon === 'keep_off') {
      menuItem.dataset.action = 'toggleDefault';
    }
    
    const icon = document.createElement('span');
    icon.className = 'icon-svg';
    icon.innerHTML = ICONS[item.icon];
    if (item.icon === 'keep' || item.icon === 'keep_off') {
      icon.classList.toggle('selected', isDefault);
    }
    
    const text = document.createElement('span');
    text.className = 'text';
    text.textContent = item.text;

    menuItem.appendChild(icon);
    menuItem.appendChild(text);
    menuItem.addEventListener('click', async (e) => {
      e.stopPropagation();
      await item.action();
      setTimeout(() => {
      menu.style.display = 'none';
      }, 100);
    });

    menu.appendChild(menuItem);
  });
}


// 添加文件夹相关的全局变量
// Add event listeners or logic that uses these variables
document.addEventListener('DOMContentLoaded', () => {
  // Example initialization logic
  bookmarkFolderContextMenu = document.querySelector('#bookmark-folder-context-menu');
  currentBookmarkFolder = document.querySelector('.bookmark-folder.active');

  // Ensure these elements exist before using them
  if (bookmarkFolderContextMenu && currentBookmarkFolder) {
    // Add your event listeners or logic here
  }
});


function openEditBookmarkFolderDialog(folderElement) {
  const folderId = folderElement.dataset.id;
  const folderTitle = folderElement.querySelector('.card-title').textContent;

  const editCategoryNameInput = document.getElementById('edit-category-name');
  const editCategoryDialog = document.getElementById('edit-category-dialog');
  const editCategoryForm = document.getElementById('edit-category-form');

  editCategoryNameInput.value = folderTitle;
  editCategoryDialog.style.display = 'block';

  editCategoryForm.onsubmit = function (event) {
    event.preventDefault();
    const newTitle = editCategoryNameInput.value;
    chrome.bookmarks.update(folderId, { title: newTitle }, function () {
      console.log('Bookmark updated:', folderId, newTitle);
      updateCategoryUI(folderId, newTitle);
      editCategoryDialog.style.display = 'none';
    });
  };
}

function updateCategoryUI(folderId, newTitle) {
  // 更新侧边栏中的文件夹名称
  const sidebarItem = document.querySelector(`#categories-list li[data-id="${folderId}"]`);
  if (sidebarItem) {
    // 更新文本内容
    const textSpan = sidebarItem.querySelector('span:not(.material-icons)');
    if (textSpan) {
      textSpan.textContent = newTitle;
    }

    // 更新 data-title 属性
    sidebarItem.setAttribute('data-title', newTitle);

    // 更新样式
    sidebarItem.classList.add('updated-folder');
    setTimeout(() => {
      sidebarItem.classList.remove('updated-folder');
    }, 2000); // 2秒后移除高亮效果
  }

  // 更新文件夹卡片（如果在当前视图中）
  const folderCard = document.querySelector(`.bookmark-folder[data-id="${folderId}"]`);
  if (folderCard) {
    const titleElement = folderCard.querySelector('.card-title');
    if (titleElement) {
      titleElement.textContent = newTitle;
    }
  }

  // bookmarks-container 使用 .bookmark-section 路径标题（非 .bookmark-folder 卡片）。
  // 同步该文件夹对应 section 的末段名称，并刷新当前视图以修正嵌套路径中的祖先名。
  document.querySelectorAll(`.bookmark-section[data-folder-id="${CSS.escape(String(folderId))}"] .bookmark-section-title`)
    .forEach((titleEl) => {
      const parts = String(titleEl.textContent || '').split(' > ');
      if (!parts.length) return;
      parts[parts.length - 1] = newTitle;
      titleEl.textContent = parts.join(' > ');
    });

  const bookmarksList = document.getElementById('bookmarks-list');
  const viewingId = bookmarksList?.dataset.parentId;
  if (viewingId) {
    bookmarksCache.delete(viewingId);
    bookmarksCache.delete(folderId);
    // 面包屑始终对应当前正在查看的文件夹，不要用被重命名的子文件夹 id 覆盖
    updateBookmarksDisplay(viewingId, undefined, undefined, {
      animate: false,
      updateName: true
    }).catch((error) => {
      console.error('Failed to refresh bookmarks after rename:', error);
    });
  }
}


function showFolder(folderId) {
  // 显示侧边栏的文件夹
  const sidebarFolderElement = document.querySelector(`#categories-list li[data-id="${folderId}"]`);
  if (sidebarFolderElement) {
    sidebarFolderElement.style.display = '';
    // 如果文夹之前是展开的，显示其子列表
    const sublist = sidebarFolderElement.nextElementSibling;
    if (sublist && sublist.tagName === 'UL') {
      sublist.style.display = '';

    }
  } else {
    console.log('Sidebar folder element not found');
  }

  // 显示内容区域中的文件夹内容（如果当前显示的是该文夹的内容）
  const bookmarksList = document.getElementById('bookmarks-list');
  if (bookmarksList.dataset.parentId === folderId) {
    bookmarksList.style.display = '';

  }

  // 显示文件夹卡片
  const folderCard = document.querySelector(`.bookmark-folder[data-id="${folderId}"]`);
  if (folderCard) {
    folderCard.style.display = '';

  } else {
    console.log('Folder card not found');
  }
}

function setDefaultBookmark(bookmarkId) {

  localStorage.setItem('defaultBookmarkId', bookmarkId);
  updateDefaultBookmarkIndicator();
  selectSidebarFolder(bookmarkId);


  // 刷新 bookmarks-container
  updateBookmarksDisplay(bookmarkId);

  // 更新侧边栏中的默认书签指示和选中状态
  updateSidebarDefaultBookmarkIndicator();

  // 通知背景脚本更新默认书签ID
  chrome.runtime.sendMessage({ action: 'setDefaultBookmarkId', defaultBookmarkId: bookmarkId }, function (response) {
    if (response && response.success) {
      console.log('Background script has updated the defaultBookmarkId');
    }
  });
}

function updateSidebarDefaultBookmarkIndicator() {
  // 兼容旧逻辑：选中态仍可读 defaultBookmarkId，固定指示统一走 defaultFolders
  const defaultBookmarkId = localStorage.getItem('defaultBookmarkId');
  if (defaultBookmarkId) {
    selectSidebarFolder(defaultBookmarkId);
  }
  updateSidebarHomepageIndicators();
}

// 添加局变量来存储本地缓存
let bookmarkOrderCache = {};

// 添加一函数来同步本地缓存和 Chrome 书签
function syncBookmarkOrder(parentId) {
  const cached = bookmarksCache.get(parentId);
  if (!cached) return;
  
  
  chrome.bookmarks.getChildren(parentId, (bookmarks) => {
    const chromeOrder = bookmarks.map(b => b.id);
    const cachedOrder = cached.bookmarks.map(b => b.id);
    
    if (JSON.stringify(chromeOrder) !== JSON.stringify(cachedOrder)) {
      // 更新缓存
      bookmarksCache.set(parentId, bookmarks);
      
      // 重新渲染当前页
      renderBookmarksPage({ bookmarks, totalCount: bookmarks.length }, 0);
    }
  });
}

// 添加一个定期同步函数
function startPeriodicSync() {
  setInterval(() => {
      const bookmarksList = document.getElementById('bookmarks-list');
      if (bookmarksList && bookmarksList.dataset.parentId) {
      const currentParentId = bookmarksList.dataset.parentId;
      try {
        syncBookmarkOrder(currentParentId);
      } catch (error) {
        console.error('Error during bookmark sync:', error);
      }
    }
  }, 30000); // 每30秒同步一次
}

let isRequestPending = false;

const DEFAULT_LINKS_ICONS_ORDER = [
  'history-link',
  'downloads-link',
  'passwords-link',
  'extensions-link',
  'chrome-web-store-link',
  'customize-chrome-link'
];

let linksIconsSortable = null;
let linksIconsOrderListenerBound = false;
let linksIconsJustReordered = false;

function normalizeLinksIconsOrder(order) {
  const normalized = Array.isArray(order)
    ? order.filter((id) => typeof id === 'string' && id)
    : [];

  DEFAULT_LINKS_ICONS_ORDER.forEach((id) => {
    if (!normalized.includes(id)) {
      normalized.push(id);
    }
  });

  return normalized;
}

function applyLinksIconsOrder(order) {
  const container = document.querySelector('.chrome-quick-icons');
  if (!container) return;

  const byId = new Map(
    Array.from(container.querySelectorAll('a[id]')).map((el) => [el.id, el])
  );
  const normalized = normalizeLinksIconsOrder(order);

  normalized.forEach((id) => {
    const el = byId.get(id);
    if (el) {
      container.appendChild(el);
      byId.delete(id);
    }
  });

  // 保留未来新增、但不在已知顺序中的图标
  byId.forEach((el) => container.appendChild(el));
}

function persistLinksIconsOrder() {
  const container = document.querySelector('.chrome-quick-icons');
  if (!container) return;

  const order = Array.from(container.querySelectorAll('a[id]')).map((el) => el.id);
  chrome.storage.sync.set({ linksIconsOrder: order }, () => {
    if (chrome.runtime.lastError) {
      console.error('Failed to save links icons order:', chrome.runtime.lastError);
    }
  });
}

function destroyLinksIconsSortable() {
  if (linksIconsSortable) {
    linksIconsSortable.destroy();
    linksIconsSortable = null;
  }
  const container = document.querySelector('.chrome-quick-icons');
  if (container) {
    container.classList.remove('is-reordering', 'reorder-enabled');
  }
}

function setupLinksIconsSortable(enabled = true) {
  const container = document.querySelector('.chrome-quick-icons');
  if (!container) return;

  destroyLinksIconsSortable();

  if (!enabled || typeof Sortable === 'undefined') {
    return;
  }

  container.classList.add('reorder-enabled');

  linksIconsSortable = new Sortable(container, {
    animation: 150,
    draggable: 'a',
    direction: 'vertical',
    distance: 4,
    ghostClass: 'chrome-quick-icons-ghost',
    chosenClass: 'chrome-quick-icons-chosen',
    dragClass: 'chrome-quick-icons-drag',
    onStart: () => {
      container.classList.add('is-reordering');
    },
    onEnd: (evt) => {
      container.classList.remove('is-reordering');
      if (evt.oldIndex === evt.newIndex) return;
      // 抑制拖拽结束后紧随的 click，避免误打开页面
      linksIconsJustReordered = true;
      setTimeout(() => {
        linksIconsJustReordered = false;
      }, 150);
      persistLinksIconsOrder();
    }
  });
}

function initLinksIconsOrder() {
  chrome.storage.sync.get(['linksIconsOrder', 'enableLinksIconsReorder'], async (result) => {
    applyLinksIconsOrder(result.linksIconsOrder);
    let enabled = result.enableLinksIconsReorder !== false;
    try {
      const allowed = await isFeatureEntitled(PRO_FEATURES.QUICK_LINKS_DRAG_TO_REORDER);
      if (!allowed) enabled = false;
    } catch (_) {
      /* keep storage preference if membership unavailable */
    }
    setupLinksIconsSortable(enabled);
  });

  if (!linksIconsOrderListenerBound) {
    linksIconsOrderListenerBound = true;
    chrome.storage.onChanged.addListener((changes, area) => {
      if (area !== 'sync') return;

      if (changes.linksIconsOrder) {
        // Avoid fighting an in-progress drag
        if (!linksIconsJustReordered) {
          applyLinksIconsOrder(changes.linksIconsOrder.newValue);
        }
      }

      if (changes.enableLinksIconsReorder) {
        const enabled = changes.enableLinksIconsReorder.newValue !== false;
        setupLinksIconsSortable(enabled);
      }
    });
  }
}

function setupSpecialLinks() {
  const specialLinks = document.querySelectorAll('.chrome-quick-icons a, .settings-icon a');
  let isProcessingClick = false;

  specialLinks.forEach(link => {
    link.addEventListener('click', async function (e) {
      e.preventDefault();
      if (isProcessingClick) return;
      // 拖拽排序刚结束时忽略点击，避免误打开页面
      if (linksIconsJustReordered) return;

      isProcessingClick = true;

      const href = this.getAttribute('href');
      let chromeUrl;
      switch (href) {
        case '#history':
          chromeUrl = 'chrome://history';
          break;
        case '#downloads':
          chromeUrl = 'chrome://downloads';
          break;
        case '#passwords':
          chromeUrl = 'chrome://settings/passwords';
          break;
        case '#extensions':
          chromeUrl = 'chrome://extensions';
          break;
        case '#chrome-web-store':
          chromeUrl = 'https://chromewebstore.google.com/';
          break;
        case '#customize-chrome':
          chromeUrl = 'chrome://settings/appearance';
          break;
        case '#settings':
          openSettingsModal();
          isProcessingClick = false;
          return;
        default:
          console.error('Unknown special link:', href);
          isProcessingClick = false;
          return;
      }

      try {
        // 直接使用 chrome.tabs.create 打开新标签页
        chrome.tabs.create({ url: chromeUrl }, (tab) => {
          if (chrome.runtime.lastError) {
            console.error('Failed to open tab:', chrome.runtime.lastError);
          }
        });
      } catch (error) {
        console.error('Error opening internal page:', error);
      } finally {
        setTimeout(() => {
          isProcessingClick = false;
        }, 1000);
      }
    });
  });
}

function updateDefaultBookmarkIndicator() {
  const defaultBookmarkId = localStorage.getItem('defaultBookmarkId');
  const allBookmarks = document.querySelectorAll('.bookmark-card, .bookmark-folder');
  allBookmarks.forEach(bookmark => {
    const indicator = bookmark.querySelector('.default-indicator');
    if (indicator) {
      indicator.remove();
    }
    if (bookmark.dataset.id === defaultBookmarkId) {
      const defaultIndicator = document.createElement('span');
      defaultIndicator.className = 'default-indicator material-icons';
      defaultIndicator.textContent = 'star';
      defaultIndicator.title = getLocalizedMessage('homepage');
      bookmark.appendChild(defaultIndicator);
    }
  });
}

function selectSidebarFolder(folderId) {
  const allFolders = document.querySelectorAll('#categories-list li');
  allFolders.forEach(folder => {
    folder.classList.remove('bg-emerald-500');
    if (folder.dataset.id === folderId) {
      folder.classList.add('bg-emerald-500');
    }
  });
}

// 确在 DOMContentLoaded 事件初始化上文菜单
document.addEventListener('DOMContentLoaded', function () {
  // ... 其他初始化代码 ...
  createBookmarkFolderContextMenu();
});




// 保留原有的DOMContentLoaded事件监听器，但移除其中的背景应用逻辑
document.addEventListener('DOMContentLoaded', function () {

  // 在页面加载完成后立即检查 folder-name 元素
  const folderNameElement = document.getElementById('folder-name');

  // 设置一个 MutationObserver 来监视 folder-name 元素的变化
  const observer = new MutationObserver((mutations) => {
    mutations.forEach((mutation) => {
    });
  });

  observer.observe(folderNameElement, { childList: true, subtree: true });

  function expandBookmarkTree(category) {
    let parent = category.parentElement;
    while (parent && parent.id !== 'categories-list') {
      if (parent.classList.contains('folder-item')) {
        const sublist = parent.nextElementSibling;
        if (sublist && sublist.tagName === 'UL') {
          sublist.style.display = 'block';
          const arrowIcon = parent.querySelector('.material-icons.ml-auto');
          if (arrowIcon) {
            arrowIcon.textContent = 'expand_less';
          }
        }
      }
      parent = parent.parentElement;
    }
  }

  function waitForFirstCategoryEdge(attemptsLeft) {
    waitForFirstCategory(attemptsLeft);
  }

  function findBookmarksByParentId(nodes, parentId) {
    if (!nodes) return [];
    let bookmarks = [];
    nodes.forEach(node => {
      if (node.parentId === parentId) {
        bookmarks.push(node);
      }
      if (node.children && node.children.length > 0) {
        bookmarks = bookmarks.concat(findBookmarksByParentId(node.children, parentId));
      }
    });
    return bookmarks;
  }


  function isEdgeBrowser() {
    return /Edg/.test(navigator.userAgent);
  }

  if (isEdgeBrowser()) {
    waitForFirstCategoryEdge(10);
  } else {
    waitForFirstCategory(10);
  }

  const toggleSidebarButton = document.getElementById('toggle-sidebar');
  const sidebarContainer = document.getElementById('sidebar-container');

  // 读保存的侧边栏状态
  const isSidebarCollapsed = localStorage.getItem('sidebarCollapsed') === 'true';

  // 初状
  function setSidebarState(isCollapsed) {
    if (isCollapsed) {
      sidebarContainer.classList.add('collapsed');
      toggleSidebarButton.textContent = '>';
      toggleSidebarButton.style.left = '2rem';
    } else {
      sidebarContainer.classList.remove('collapsed');
      toggleSidebarButton.textContent = '<';
      toggleSidebarButton.style.left = 'calc(var(--side-panel-margin, 8px) + var(--sidebar-panel-width, 16rem) - 1.25rem)';
    }
  }

  // 应用初始状态（可按设置关闭打开新标签页时的展开动画）
  chrome.storage.sync.get({ enableSidebarOpenAnimation: true }, (result) => {
    const enableAnim = result.enableSidebarOpenAnimation !== false;
    if (!enableAnim) {
      document.documentElement.classList.add('no-sidebar-open-animation');
    }

    setSidebarState(isSidebarCollapsed);

    if (!enableAnim) {
      requestAnimationFrame(() => {
        requestAnimationFrame(() => {
          document.documentElement.classList.remove('no-sidebar-open-animation');
        });
      });
    }
  });

  // 切换侧边状态的函数
  function toggleSidebar() {
    const isCollapsed = sidebarContainer.classList.toggle('collapsed');
    setSidebarState(isCollapsed);
    localStorage.setItem('sidebarCollapsed', isCollapsed);
  }

  // 添加点击事件监听器
  toggleSidebarButton.addEventListener('click', toggleSidebar);

  document.addEventListener('click', function (event) {
    if (event.target.closest('#categories-list li')) {
      updateBookmarkCards();
    }
  });

  updateBookmarkCards();

  // 注释掉这个重复的createContextMenu函数定义，使用全局已经定义的函数
  /* function createContextMenu() {
    const menu = document.createElement('div');
    menu.className = 'custom-context-menu';
    document.body.appendChild(menu);
    // ... 其余函数内容 ...
  } */

  document.addEventListener('click', function () {
    // 延迟处理点击事件，让菜单项的点击事件先执行
    setTimeout(() => {
    if (contextMenu) {
      contextMenu.style.display = 'none';
        currentBookmark = null;
      }
      
      if (bookmarkFolderContextMenu) {
        bookmarkFolderContextMenu.style.display = 'none';
        currentBookmarkFolder = null;
      }
    }, 200);
  });

  const editDialog = document.getElementById('edit-dialog');
  const editForm = document.getElementById('edit-form');
  const editNameInput = document.getElementById('edit-name');
  const editUrlInput = document.getElementById('edit-url');
  const closeButton = document.querySelector('.close-button');
  const cancelButton = document.querySelector('.cancel-button');

  function openEditDialog(bookmark) {
    const bookmarkId = bookmark.id;
    const bookmarkTitle = bookmark.title;
    const bookmarkUrl = bookmark.url;

    document.getElementById('edit-name').value = bookmarkTitle;
    document.getElementById('edit-url').value = bookmarkUrl;

    const editDialog = document.getElementById('edit-dialog');
    editDialog.style.display = 'block';

    // 设置提交事件
    document.getElementById('edit-form').onsubmit = function (event) {
      event.preventDefault();
      const newTitle = document.getElementById('edit-name').value;
      const newUrl = document.getElementById('edit-url').value;
      chrome.bookmarks.update(bookmarkId, { title: newTitle, url: newUrl }, function () {
        editDialog.style.display = 'none';

        // 更新特定的书签卡片
        updateSpecificBookmarkCard(bookmarkId, newTitle, newUrl);
      });
    };

    // 添加取消按钮的事件监听
    document.querySelector('.cancel-button').addEventListener('click', function () {
      editDialog.style.display = 'none';
    });

    // 添加关闭按钮的事件监听
    document.querySelector('.close-button').addEventListener('click', function () {
      editDialog.style.display = 'none';
    });
  }

  function updateSpecificBookmarkCard(bookmarkId, newTitle, newUrl) {
    const bookmarkCard = document.querySelector(`.bookmark-card[data-id="${bookmarkId}"]`);
    if (bookmarkCard) {
      bookmarkCard.href = newUrl;
      bookmarkCard.querySelector('.card-title').textContent = newTitle;

      // 更新 favicon 和颜色
      const img = bookmarkCard.querySelector('img');
      updateBookmarkCardColors(bookmarkCard, newUrl, img);
    }
  }

  function updateBookmarkCardColors(bookmarkCard, newUrl, img) {
    if (!bookmarkCard || !img) return;
    applyFaviconWithFallback(img, newUrl);
  }

  closeButton.onclick = function () {
    editDialog.style.display = 'none';
  };

  cancelButton.onclick = function () {
    editDialog.style.display = 'none';
  };

  window.onclick = function (event) {
    if (event.target == editDialog) {
      editDialog.style.display = 'none';
    }
  };

  function findBookmarkNodeByTitle(nodes, title) {
    for (let node of nodes) {
      if (node.title === title) {
        return node;
      } else if (node.children) {
        const result = findBookmarkNodeByTitle(node.children, title);
        if (result) {
          return result;
        }
      }
    }
    return null;
  }



  // 调用 updateBookmarkCards
  updateBookmarkCards();

  function expandToBookmark(bookmarkId) {
    setTimeout(() => {
      const bookmarkElement = document.querySelector(`#categories-list li[data-id="${bookmarkId}"]`);
      if (bookmarkElement) {
        let parent = bookmarkElement.parentElement;
        while (parent && parent.id !== 'categories-list') {
          if (parent.classList.contains('folder-item')) {
            parent.classList.add('expanded');
            const sublist = parent.querySelector('ul');
            if (sublist) sublist.style.display = 'block';
          }
          parent = parent.parentElement;
        }
        bookmarkElement.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
        bookmarkElement.style.animation = 'highlight 1s';
      }
    }, 100); // 给予一些 DOM 更新
  }

  function getFavicon(url, callback) {
    if (isChromeInternalUrl(url)) {
      callback(CHROME_BROWSER_ICON);
      return;
    }

    const domain = new URL(url).hostname;

    chrome.bookmarks.search({ url: url }, function (results) {
      if (results && results.length > 0) {
        const faviconUrl = bookmarkFaviconURL(url);
        const img = new Image();
        img.onload = function () {
          callback(faviconUrl);
        };
        img.onerror = function () {
          fetchFaviconOnline(domain, callback);
        };
        img.src = faviconUrl;
      } else {
        fetchFaviconOnline(domain, callback);
      }
    });
  }

  function fetchFaviconOnline(domain, callback) {
    const faviconUrls = [
      `https://www.google.com/s2/favicons?domain=${domain}`,
    ];

    let faviconUrl = faviconUrls[0];
    const img = new Image();
    img.onload = function () {
      cacheFavicon(domain, faviconUrl);
      callback(faviconUrl);
    };
    img.onerror = function () {
      faviconUrls.shift();
      if (faviconUrls.length > 0) {
        faviconUrl = faviconUrls[0];
        img.src = faviconUrl;
      } else {
        callback('');
      }
    };
    img.src = faviconUrl;
  }

  function cacheFavicon(domain, faviconUrl) {
    const data = {};
    data[domain] = faviconUrl;
    chrome.storage.local.set(data);
  }

  let currentCategory = null;
  // 递归获取所有书签数量的函数
  const getAllBookmarksCount = async (folderId, maxDepth = 5) => {
    let count = 0;
    let depth = 0;

    async function countBookmarks(id, currentDepth) {
      if (currentDepth > maxDepth) return 0;

      return new Promise((resolve) => {
        chrome.bookmarks.getChildren(id, async (items) => {
          let localCount = 0;

          for (const item of items) {
            if (item.url && item.url.startsWith('http')) {
              localCount++;
            } else if (currentDepth < maxDepth) {
              localCount += await countBookmarks(item.id, currentDepth + 1);
            }
          }

          resolve(localCount);
        });
      });
    }

    count = await countBookmarks(folderId, depth);
    return count;
  };
  // 1. 批量创建标签页的函数
  function createTabsInBatches(urls, groupName, batchSize = 5, delay = 100) {
    return new Promise(async (resolve) => {
      const tabIds = [];
      let currentBatch = 0;
      let canGroup = false;

      try {
        if (chrome.permissions?.contains) {
          canGroup = await new Promise((res) => {
            chrome.permissions.contains({ permissions: ['tabGroups'] }, (result) => {
              res(Boolean(result) && !chrome.runtime.lastError);
            });
          });
        }
        if (!canGroup && chrome.permissions?.request) {
          canGroup = await new Promise((res) => {
            chrome.permissions.request({ permissions: ['tabGroups'] }, (granted) => {
              res(Boolean(granted) && !chrome.runtime.lastError);
            });
          });
        }
      } catch (_) {
        canGroup = false;
      }

      function createBatch() {
        const batch = urls.slice(currentBatch, currentBatch + batchSize);
        if (batch.length === 0) {
          if (canGroup && tabIds.length > 1 && chrome.tabs.group) {
            chrome.tabs.group({ tabIds }, (groupId) => {
              if (!chrome.runtime.lastError && chrome.tabGroups?.update) {
                chrome.tabGroups.update(groupId, {
                  title: groupName,
                  color: 'cyan'
                });
              }
              resolve({ success: true });
            });
          } else {
            resolve({ success: true });
          }
          return;
        }

        Promise.all(batch.map(url =>
          new Promise((resolveTab) => {
            chrome.tabs.create({ url, active: false }, (tab) => {
              if (tab?.id != null) tabIds.push(tab.id);
              resolveTab();
            });
          })
        )).then(() => {
          currentBatch += batchSize;
          setTimeout(createBatch, delay);
        });
      }

      createBatch();
    });
  }
  function createCategoryContextMenu() {
    const menu = document.createElement('div');
    menu.className = 'custom-context-menu';
    document.body.appendChild(menu);

    // 创建基本菜单项
    const createMenuItems = async (bookmarkCount) => {
      // 检查当前文件夹是否为默认文件夹
      let isDefault = false;
      if (currentCategory?.dataset?.id) {
        try {
          const data = await chrome.storage.sync.get('defaultFolders');
          const defaultFolders = data.defaultFolders?.items || [];
          isDefault = defaultFolders.some(folder => folder.id === currentCategory.dataset.id);
        } catch (error) {
          console.error('Error checking default folder status:', error);
        }
      }

      // 书签栏 / 其他书签 / 移动设备书签等根目录：可当文件夹操作，但不能重命名或删除
      const isBookmarkRoot = currentCategory?.classList?.contains('bookmark-root-toggle');

      const menuItems = [
        {
          text: getLocalizedMessage('newFolder') || 'New Folder',
          icon: 'add_circle',
          action: () => {
            if (currentCategory?.dataset?.id) {
              openCreateFolderDialog(currentCategory.dataset.id);
            }
          }
        },
        {
          text: `${getLocalizedMessage('openAllBookmarks')} (${bookmarkCount})`,
          icon: 'open_in_new',
          action: () => {
            if (currentCategory) {
              const folderId = currentCategory.dataset.id;
              const folderTitle = currentCategory.dataset.title;

              // 递归获取所有书签 URL 的函数
              const getAllBookmarkUrls = async (folderId) => {
                return new Promise((resolve) => {
                  chrome.bookmarks.getChildren(folderId, async (items) => {
                    let urls = [];
                    for (const item of items) {
                      if (item.url) {
                        urls.push(item.url);
                      } else {
                        // 递归获取子文件夹的 URLs
                        const subUrls = await getAllBookmarkUrls(item.id);
                        urls = urls.concat(subUrls);
                      }
                    }
                    resolve(urls);
                  });
                });
              };

              // 获取并打开所有书签
              getAllBookmarkUrls(folderId).then(validUrls => {
                if (validUrls.length > 0) {
                  openMultipleTabsAndGroup(validUrls, folderTitle).then((response) => {
                    if (response?.success) {
                      console.log('Bookmarks opened in new tab group');
                    } else {
                      console.error('Error opening bookmarks:', response?.error);
                    }
                  });
                }
              });
            }
          }
        },
        ...(!isBookmarkRoot ? [
          {
            text: getLocalizedMessage('rename'),
            icon: 'edit',
            action: () => {
              if (!currentCategory) return;
              openRenameFolderDialog(currentCategory.dataset.id, currentCategory.dataset.title);
            }
          },
          {
            text: getLocalizedMessage('delete'),
            icon: 'delete',
            action: () => {
              if (!currentCategory) return;
              deleteSidebarFolder(
                currentCategory.dataset.id,
                currentCategory.dataset.title,
                currentCategory.dataset.parentId || getSelectedBookmarkRootId()
              );
            }
          }
        ] : []),
        { type: 'divider' },
        {
          text: getLocalizedMessage('importBookmarks') || 'Import Bookmarks',
          icon: 'upload',
          action: async () => {
            if (!currentCategory?.dataset?.id) return;
            const folderId = currentCategory.dataset.id;
            try {
              const stats = await pickAndImportBookmarkHtml(folderId);
              if (!stats) return;
              bookmarksCache.clear();
              await refreshBookmarkSidebar(folderId);
              await updateBookmarksDisplay(folderId);
              updateFolderName(folderId);
              const msg = chrome.i18n.getMessage(
                'importBookmarksSuccess',
                [String(stats.bookmarks), String(stats.folders)]
              ) || `Imported ${stats.bookmarks} bookmarks, ${stats.folders} folders`;
              Utilities.showToast(msg, 2500);
            } catch (error) {
              console.error('Error importing bookmarks:', error);
              if (error?.message === 'EMPTY_BOOKMARK_FILE') {
                Utilities.showToast(getLocalizedMessage('importBookmarksEmpty') || 'No bookmarks found in file');
              } else {
                Utilities.showToast(getLocalizedMessage('importBookmarksError') || 'Failed to import bookmarks');
              }
            }
          }
        },
        {
          text: getLocalizedMessage('exportBookmarks') || 'Export Bookmarks',
          icon: 'download',
          action: async () => {
            if (!currentCategory?.dataset?.id) return;
            try {
              await exportFolderAsHtml(
                currentCategory.dataset.id,
                currentCategory.dataset.title
              );
              Utilities.showToast(getLocalizedMessage('exportBookmarksSuccess') || 'Bookmarks exported');
            } catch (error) {
              console.error('Error exporting bookmarks:', error);
              Utilities.showToast(getLocalizedMessage('exportBookmarksError') || 'Failed to export bookmarks');
            }
          }
        },
        {
          text: getLocalizedMessage('aiOrganizeBookmarks') || 'AI Organize',
          icon: 'auto_awesome',
          action: async () => {
            if (!currentCategory?.dataset?.id) return;
            try {
              await organizeFolderWithAi(currentCategory.dataset.id);
            } catch (error) {
              console.error('AI organize failed:', error);
              Utilities.showToast(getAiOrganizeErrorMessage(error), 3000);
            }
          }
        },
        { type: 'divider' },
        { 
          text: isDefault ? getLocalizedMessage('removeFromDefaultFolders') : getLocalizedMessage('addToDefaultFolders'),
          icon: isDefault ? 'keep_off' : 'keep',
          action: async () => {
            if (!currentCategory?.dataset?.id) {
              console.error('No valid folder selected');
              return;
            }
            await toggleDefaultFolder(currentCategory);
          }
        }
      ];

      if (currentCategory?.dataset?.id) {
        try {
          const hasSnapshot = await hasAiOrganizeSnapshot(currentCategory.dataset.id);
          if (hasSnapshot) {
            const organizeIndex = menuItems.findIndex(
              (item) => item.icon === 'auto_awesome' && !item.type
            );
            const restoreItem = {
              text: getLocalizedMessage('aiOrganizeRestore') || 'Restore Previous Structure',
              icon: 'undo',
              action: async () => {
                if (!currentCategory?.dataset?.id) return;
                try {
                  await restoreFolderFromAiOrganize(currentCategory.dataset.id);
                } catch (error) {
                  console.error('AI organize restore failed:', error);
                  Utilities.showToast(
                    getLocalizedMessage('aiOrganizeRestoreFailed')
                      ? chrome.i18n.getMessage('aiOrganizeRestoreFailed', [String(error.message || '').slice(0, 120)])
                      : `Failed to restore folder: ${String(error.message || '').slice(0, 120)}`,
                    3000
                  );
                }
              }
            };
            if (organizeIndex >= 0) {
              menuItems.splice(organizeIndex + 1, 0, restoreItem);
            } else {
              menuItems.unshift(restoreItem);
            }
          }
        } catch (error) {
          console.warn('Failed to check AI organize snapshot for context menu:', error);
        }
      }

      // 清空现有菜单项
      menu.innerHTML = '';

      // 创建菜单项的其余代码保持不变...
      menuItems.forEach(item => {
        if (item.type === 'divider') {
          const divider = document.createElement('div');
          divider.className = 'custom-context-menu-divider';
          menu.appendChild(divider);
          return;
        }

        const menuItem = document.createElement('div');
        menuItem.className = 'custom-context-menu-item';

        const icon = document.createElement('span');
        icon.className = 'material-icons';
        icon.innerHTML = ICONS[item.icon];
        icon.style.marginRight = '8px';
        icon.style.fontSize = '18px';

        const text = document.createElement('span');
        text.textContent = item.text;

        menuItem.appendChild(icon);
        menuItem.appendChild(text);

        menuItem.addEventListener('click', async function () {
          if (item.action) {
            await item.action();
          }
          menu.style.display = 'none';
        });

        menu.appendChild(menuItem);
      });
    };

    return {
      menu: menu,
      updateMenuItems: createMenuItems
    };
  }

  const categoryContextMenu = createCategoryContextMenu();
  initFolderTreeCrud();
  initSidebarBookmarkSearch();

  document.addEventListener('contextmenu', function (event) {
    const targetCategory = event.target.closest('#categories-list li, .bookmark-root-toggle');
    if (targetCategory) {
      event.preventDefault();
      currentCategory = targetCategory;

      if (currentCategory) {
        const folderId = currentCategory.dataset.id;
        // 使用新的递归函数获取总书签数量
        getAllBookmarksCount(folderId).then(totalCount => {
          categoryContextMenu.updateMenuItems(totalCount);

          categoryContextMenu.menu.style.top = `${event.clientY}px`;
          categoryContextMenu.menu.style.left = `${event.clientX}px`;
          categoryContextMenu.menu.style.display = 'block';
        });
      }
    } else {
      categoryContextMenu.menu.style.display = 'none';
    }
  });

  document.addEventListener('click', function () {
    categoryContextMenu.menu.style.display = 'none';
  });

  const editCategoryDialog = document.getElementById('edit-category-dialog');
  const editCategoryForm = document.getElementById('edit-category-form');
  const editCategoryNameInput = document.getElementById('edit-category-name');
  const closeCategoryButton = document.querySelector('.close-category-button');
  const cancelCategoryButton = document.querySelector('.cancel-category-button');

  function openEditCategoryDialog(categoryElement) {
    const categoryId = categoryElement.dataset.id;
    const categoryTitle = categoryElement.dataset.title;

    editCategoryNameInput.value = categoryTitle;

    editCategoryDialog.style.display = 'block';

    editCategoryForm.onsubmit = function (event) {
      event.preventDefault();
      const updatedTitle = editCategoryNameInput.value;

      chrome.bookmarks.update(categoryId, {
        title: updatedTitle
      }, function (result) {
        updateCategoryUI(categoryElement, updatedTitle);
        editCategoryDialog.style.display = 'none';
      });
    };
  }

  function updateCategoryUI(categoryElement, newTitle) {
    const folderId = categoryElement.dataset.id;
    // 更新侧边栏中的文件夹名称
    const sidebarItem = document.querySelector(`#categories-list li[data-id="${folderId}"]`);
    if (sidebarItem) {
      // 更新文本内容
      const textSpan = sidebarItem.querySelector('span:not(.material-icons)');
      if (textSpan) {
        textSpan.textContent = newTitle;
      }

      // 更新 data-title 属性
      sidebarItem.setAttribute('data-title', newTitle);

      // 更新样式
      sidebarItem.classList.add('updated-folder');
      setTimeout(() => {
        sidebarItem.classList.remove('updated-folder');
      }, 2000); // 2秒后移除高亮效果
    }

    // 更新文件夹卡片（如果在当前视图中）
    const folderCard = document.querySelector(`.bookmark-folder[data-id="${folderId}"]`);
    if (folderCard) {
      const titleElement = folderCard.querySelector('.card-title');
      if (titleElement) {
        titleElement.textContent = newTitle;
      }
    }

    const bookmarksList = document.getElementById('bookmarks-list');
    const viewingId = bookmarksList?.dataset.parentId;
    if (viewingId) {
      bookmarksCache.delete(viewingId);
      bookmarksCache.delete(folderId);
      updateBookmarksDisplay(viewingId, undefined, undefined, {
        animate: false,
        updateName: true
      }).catch(() => {});
    }
  }

  closeCategoryButton.onclick = function () {
    editCategoryDialog.style.display = 'none';
  };

  cancelCategoryButton.onclick = function () {
    editCategoryDialog.style.display = 'none';
  };

  window.onclick = function (event) {
    if (event.target == editCategoryDialog) {
      editCategoryDialog.style.display = 'none';
    }
  };

  function updateBookmarksDisplay(parentId, movedItemId, newIndex) {
    return new Promise((resolve, reject) => {
      chrome.bookmarks.getSubTree(parentId, (results) => {
        if (chrome.runtime.lastError) {
          reject(chrome.runtime.lastError);
          return;
        }

        const node = results && results[0];
        if (!node) {
          reject(new Error('Folder not found'));
          return;
        }

        const bookmarksContainer = document.querySelector('.bookmarks-container');

        // 先隐藏容器
        bookmarksContainer.style.opacity = '0';
        bookmarksContainer.style.transform = 'translateY(20px)';

        // 更新缓存
        bookmarksCache.set(parentId, node.children || []);

        // 更新本地排序缓存
        bookmarkOrderCache[parentId] = (node.children || []).map(b => b.id);

        displayBookmarks(node);

        if (movedItemId) {
          highlightBookmark(movedItemId);
        }

        // 更新文件夹名称
        updateFolderName(parentId);

        // 使用 requestAnimationFrame 来确保 DOM 更新后再显示容器
        requestAnimationFrame(() => {
          requestAnimationFrame(() => {
            bookmarksContainer.style.opacity = '1';
            bookmarksContainer.style.transform = 'translateY(0)';
          });
        });

        resolve();
      });
    });
  }

  const tabsContainer = document.getElementById('tabs-container');
  const tabs = document.querySelectorAll('.tab');
  const defaultSearchEngine = localStorage.getItem('selectedSearchEngine') || 'Google';

  // 在文件的适当位置（可能在 DOMContentLoaded 事件监听器内）添加这个标志
  let isChangingSearchEngine = false;

  // 将 getSearchUrl 函数移到文件前面，在事件监听器之前定义
  function getSearchUrl(engine, query) {
    const allEngines = SearchEngineManager.getAllEngines();
    const engineConfig = allEngines.find(e => {
      // 匹配引擎名称或别名
      return e.name.toLowerCase() === engine.toLowerCase() || 
             (e.aliases && e.aliases.some(alias => alias.toLowerCase() === engine.toLowerCase()));
    });

    if (!engineConfig) {
      // 如果找不到对应的引擎配置,使用默认引擎
      const defaultEngine = SearchEngineManager.getDefaultEngine();
      return defaultEngine.url + encodeURIComponent(query);
    }

    // 确保 URL 中包含查询参数占位符
    const url = engineConfig.url.includes('%s') ? 
      engineConfig.url.replace('%s', encodeURIComponent(query)) :
      engineConfig.url + encodeURIComponent(query);

    return url;
  }



  tabs.forEach(tab => {
    tab.setAttribute('tabindex', '0');

    tab.addEventListener('click', function () {
        const selectedEngine = this.getAttribute('data-engine');
        const searchInput = document.querySelector('.search-input');
        const searchQuery = searchInput.value.trim();
        
        // 移除所有标签的激活状态
        tabs.forEach(t => t.classList.remove('active'));
        // 为当前点击的标签添加激活状态
        this.classList.add('active');

        // 如果搜索框有内容，立即执行搜索
        if (searchQuery) {
            const searchUrl = getSearchUrl(selectedEngine, searchQuery);
            window.open(searchUrl, '_blank');
            hideSuggestions();
            
            // 使用 setTimeout 延迟恢复默认搜索引擎状态
            setTimeout(restoreDefaultSearchEngine, 300);
        }
    });
  });

  new Sortable(tabsContainer, {
    animation: 150,
    onEnd: function (evt) {
      const orderedEngines = Array.from(tabsContainer.children).map(tab => tab.getAttribute('data-engine'));
      localStorage.setItem('orderedSearchEngines', JSON.stringify(orderedEngines));
    }
  });

  const savedOrder = JSON.parse(localStorage.getItem('orderedSearchEngines'));
  if (savedOrder) {
    savedOrder.forEach(engineName => {
      const tab = Array.from(tabs).find(tab => tab.getAttribute('data-engine') === engineName);
      if (tab) {
        tabsContainer.appendChild(tab);
      }
    });
  }

  const searchForm = document.getElementById('search-form');
  const searchInput = document.querySelector('.search-input');
  const searchEngineIcon = document.getElementById('search-engine-icon');

  searchInput.addEventListener('focus', function () {
    searchForm.classList.add('focused');
    if (searchInput.value.trim() === '') {
      showDefaultSuggestions();
    } else {
      const suggestions = getSuggestions(searchInput.value.trim());
      showSuggestions(suggestions);
    }
  });

  searchInput.addEventListener('blur', () => {
    const searchForm = document.querySelector('.search-form');
    searchForm.classList.remove('focused');
    // 使用 setTimeout 来延迟隐藏建议列表，允许点击建议
    setTimeout(() => {
      if (!searchForm.contains(document.activeElement)) {
        hideSuggestions();
      }
    }, 200);
  });

  if (!searchForm || !searchInput || !tabsContainer || !searchEngineIcon) {
    return;
  }

  updateSubmitButtonState();



  function updateSubmitButtonState() {
    if (searchInput.value.trim() === '') {
      tabsContainer.style.display = 'none';
    } else {
      // 只有当搜索建议列表不为空时才显示 tabs-container
      if (searchSuggestions.children.length > 0) {
        tabsContainer.style.display = 'flex';
      } else {
        tabsContainer.style.display = 'none';
      }
    }
  }

  let isSearching = false;
  let searchQueue = [];

  function debounce(func, wait) {
    let timeout;
    return function(...args) {
      clearTimeout(timeout);
      timeout = setTimeout(() => func.apply(this, args), wait);
    };
  }

  const debouncedPerformSearch = debounce(performSearch, 300);

  // Modify the search form submit event listener
  searchForm.addEventListener('submit', (e) => {
    e.preventDefault(); // Prevent default form submission
    performSearch(searchInput.value.trim());
  });

  function queueSearch() {
    const query = searchInput.value.trim();
    if (query === '') {
      return;
    }
    searchQueue.push(query);
    processSearchQueue();
  }

  function processSearchQueue() {
    if (isSearching || searchQueue.length === 0) {
      return;
    }
    
    const query = searchQueue.shift();
    debouncedPerformSearch(query);
  }
  // 修改 performSearch 函数
  function performSearch(query) {
    if (!query || typeof query !== 'string' || query.trim() === '') {
      return;
    }

    isSearching = true;

    // 获取当前激活的搜索引擎用于本次搜索
    const activeTab = document.querySelector('.tab.active');
    const currentEngine = activeTab ? activeTab.getAttribute('data-engine') : defaultSearchEngine;
    console.log('[Search] Current engine for search:', currentEngine);

    // 获取真正的默认搜索引擎
    const defaultEngine = localStorage.getItem('selectedSearchEngine') || 'google';
    let url = getSearchUrl(currentEngine, query);

    // 在打开新窗口之前先恢复默认搜索引擎
    requestAnimationFrame(() => {
      // 1. 恢复 tabs-container 中的默认选中状态
      const tabs = document.querySelectorAll('.tab');
      console.log('[Search] Found tabs:', tabs.length);

      // 清除所有临时标记
      tabs.forEach(tab => {
        delete tab.dataset.temporary;
        if (tab.getAttribute('data-engine').toLowerCase() === defaultEngine.toLowerCase()) {
          console.log('[Search] Setting active tab:', defaultEngine);
          tab.classList.add('active');
        } else {
          tab.classList.remove('active');
        }
      });

      // 根据设置决定打开方式
      chrome.storage.sync.get('openSearchInNewTab', (result) => {
        const openInNewTab = result.openSearchInNewTab !== false; // 默认为 true
        console.log('[Search] Opening URL:', url, 'in new tab:', openInNewTab);
        
        if (openInNewTab) {
          window.open(url, '_blank');
        } else {
          window.location.href = url;
        }
        
        hideSuggestions();
      });
    });

    setTimeout(() => {
      isSearching = false;
      processSearchQueue();
    }, 1000);
  }

  // 新增恢复默认搜索引擎的函数
  function restoreDefaultSearchEngine() {
    const defaultEngine = localStorage.getItem('selectedSearchEngine') || 'google';

    // 更新标签状态
    const tabs = document.querySelectorAll('.tab');
    tabs.forEach(tab => {
      if (tab.getAttribute('data-engine') === defaultEngine) {
        tab.classList.add('active');
      } else {
        tab.classList.remove('active');
      }
    });

    // 更新搜索引擎图标
    updateSearchEngineIcon(defaultEngine);
  }


  // 修改 getSearchUrl 函数,使用 SearchEngineManager 中的配置
  function getSearchUrl(engine, query) {
    const allEngines = SearchEngineManager.getAllEngines();
    const engineConfig = allEngines.find(e => {
      // 匹配引擎名称或别名
      return e.name.toLowerCase() === engine.toLowerCase() ||
        (e.aliases && e.aliases.some(alias => alias.toLowerCase() === engine.toLowerCase()));
    });

    if (!engineConfig) {
      // 如果找不到对应的引擎配置,使用默认引擎
      const defaultEngine = SearchEngineManager.getDefaultEngine();
      return defaultEngine.url + encodeURIComponent(query);
    }

    // 确保 URL 中包含查询参数占位符
    const url = engineConfig.url.includes('%s') ? 
      engineConfig.url.replace('%s', encodeURIComponent(query)) :
      engineConfig.url + encodeURIComponent(query);

    return url;
  }

  // 动态调整 textarea 度的函数
  function adjustTextareaHeight() {
    const searchInput = document.querySelector('.search-input');
    if (!searchInput) return;

    searchInput.style.height = 'auto'; // 重置高度
    const lineHeight = parseInt(getComputedStyle(searchInput).lineHeight) || 21;
    const maxHeight = 3 * lineHeight; // 最多显示 3 行
    const newHeight = Math.min(searchInput.scrollHeight, maxHeight);
    searchInput.style.height = `${newHeight}px`;
  }

  // 在输入事件中调用调整高度的函数
  searchInput.addEventListener('input', adjustTextareaHeight);

  // 初始化时调整高度
  adjustTextareaHeight();
  

  const searchSuggestions = document.getElementById('search-suggestions');

  // 防抖函
  function debounce(func, wait) {
    let timeout;
    return function (...args) {
      clearTimeout(timeout);
      timeout = setTimeout(() => func.apply(this, args), wait);
    };
  }
  async function getRecentHistory(limit = 100, maxPerDomain = 5) {
    return new Promise((resolve) => {
      chrome.history.search({ text: '', maxResults: limit * 20 }, (historyItems) => {
        const now = Date.now();
        const domainCounts = {};
        const uniqueItems = new Map();

        const recentHistory = historyItems
          // 映射并添加额外信息
          .map(item => {
            const url = new URL(item.url);
            const domain = url.hostname;
            return {
              text: item.title,
              url: item.url,
              domain: domain,
              type: 'history',
              relevance: 1,
              timestamp: item.lastVisitTime
            };
          })
          // 按时间排序（最近的优先）
          .sort((a, b) => b.timestamp - a.timestamp)
          // 去重（基于URL和标题）并限制每个域名的数量
          .filter(item => {
            const key = `${item.url}|${item.text}`;
            if (uniqueItems.has(key)) return false;
            
            domainCounts[item.domain] = (domainCounts[item.domain] || 0) + 1;
            if (domainCounts[item.domain] > maxPerDomain) return false;
            
            uniqueItems.set(key, item);
            return true;
          })
          // 应用时间衰减因子
          .map(item => {
            const daysSinceLastVisit = (now - item.timestamp) / (1000 * 60 * 60 * 24);
            item.relevance *= Math.exp(-daysSinceLastVisit / RELEVANCE_CONFIG.timeDecayHalfLife);
            return item;
          })
          // 再次排序，这次基于相关性（考虑了时间衰减）
          .sort((a, b) => b.relevance - a.relevance)
          // 限制结果数量
          .slice(0, limit);

        resolve(recentHistory);
      });
    });
  }
  // 在文件顶部定义 RELEVANCE_CONFIG
  const RELEVANCE_CONFIG = {
    titleExactMatchWeight: 6,
    urlExactMatchWeight: 1.5,
    titlePartialMatchWeight: 1.2,
    urlPartialMatchWeight: 0.3,
    timeDecayHalfLife: 60,
    fuzzyMatchThreshold: 0.6,
    fuzzyMatchWeight: 1.5,
    bookmarkRelevanceBoost: 1.2
  };
  function searchHistory(query, maxResults = 200) {
    return new Promise((resolve) => {
      const startTime = new Date().getTime() - (30 * 24 * 60 * 60 * 1000); // 搜索最近30天的历史
      chrome.history.search(
        { 
          text: query, 
          startTime: startTime,
          maxResults: maxResults 
        }, 
        (results) => {
          
          // 对历史记录进行去重
          const uniqueResults = Array.from(new Set(results.map(r => r.url)))
            .map(url => results.find(r => r.url === url));
          resolve(uniqueResults);
        }
      );
    });
  }
  // 获取搜索建议
  async function getSuggestions(query) {
    const maxHistoryResults = 200;
    const maxBookmarkResults = 50;
    const maxTotalSuggestions = 50;

    let suggestions = [{ text: query, type: 'search', relevance: Infinity }];

    // 获取设置
    const settings = await new Promise(resolve => {
      chrome.storage.sync.get(
        ['showHistorySuggestions', 'showBookmarkSuggestions'],
        resolve
      );
    });

    // 根据设置获取历史记录建议
    let historySuggestions = [];
    if (settings.showHistorySuggestions !== false) {
      const historyItems = await searchHistory(query, maxHistoryResults);
      historySuggestions = historyItems.map(item => ({
        text: item.title,
        url: item.url,
        type: 'history',
        relevance: calculateRelevance(query, item.title, item.url),
        timestamp: item.lastVisitTime
      }));
    }

    // 根据设置获取书签建议
    let bookmarkSuggestions = [];
    if (settings.showBookmarkSuggestions !== false) {
      const bookmarkItems = await new Promise(resolve => {
        chrome.bookmarks.search(query, resolve);
      });
      bookmarkSuggestions = bookmarkItems.slice(0, maxBookmarkResults).map(item => ({
        text: item.title,
        url: item.url,
        type: 'bookmark',
        relevance: calculateRelevance(query, item.title, item.url) * RELEVANCE_CONFIG.bookmarkRelevanceBoost
      }));
    }

    // 合并所有建议
    suggestions.push(
      ...historySuggestions,
      ...bookmarkSuggestions
    );

    // 对结果进行排序和去重
    const uniqueSuggestions = Array.from(new Set(suggestions.map(s => s.url)))
      .map(url => suggestions.find(s => s.url === url))
      .sort((a, b) => b.relevance - a.relevance);

    // 平衡和交替显示结果
    const balancedResults = await balanceResults(uniqueSuggestions, maxTotalSuggestions);

    return balancedResults;
  }

  function calculateRelevance(query, title, url) {
    // 基础设置
    const weights = {
      // 1. 提高完全匹配的权重，让精确结果更容易被找到
      exactTitleMatch: 200,    // 提高标题完全匹配权重
      exactUrlMatch: 150,      // 提高 URL 完全匹配权重

      // 2. 调整开头匹配权重，因为用户通常从开头输入
      titleStartsWith: 180,    // 提高标题开头匹配权重
      urlStartsWith: 150,      // 提高 URL 开头匹配权重

      // 3. 包含匹配权重适当调，避免干扰更精确的结果
      titleIncludes: 100,
      urlIncludes: 80,

      // 4. 提高分词匹配的权重，改善多关键词搜索体验
      wordMatch: 70,           // 提高分词匹配基础权重
      partialWordMatch: 40,    // 提高部分词匹配权重

      // 5. 保持模糊匹配权重较低，作为补充
      fuzzyMatch: 30
    };

    // 数据预处理
    const lowerQuery = query.toLowerCase().trim();
    const lowerTitle = (title || '').toLowerCase().trim();
    const lowerUrl = (url || '').toLowerCase().trim();
    const queryWords = lowerQuery.split(/\s+/);  // 将查询分词

    let score = 0;

    // 1. 完全匹配检查
    if (lowerTitle === lowerQuery) {
      score += weights.exactTitleMatch;
    }
    if (lowerUrl === lowerQuery) {
      score += weights.exactUrlMatch;
    }

    // 2. 开头匹配检查
    if (lowerTitle.startsWith(lowerQuery)) {
      score += weights.titleStartsWith;
    }
    if (lowerUrl.startsWith(lowerQuery)) {
      score += weights.urlStartsWith;
    }

    // 3. 包含匹配检查
    if (lowerTitle.includes(lowerQuery)) {
      score += weights.titleIncludes;
    }
    if (lowerUrl.includes(lowerQuery)) {
      score += weights.urlIncludes;
    }

    // 4. 分词匹配
    queryWords.forEach(word => {
      if (word.length > 1) {
        // 完整词匹配给予更高权重
        if (lowerTitle.includes(word)) {
          score += weights.wordMatch;
          // 词在开头给予额外加分
          if (lowerTitle.startsWith(word)) {
            score += weights.wordMatch * 0.3;
          }
        }
        if (lowerUrl.includes(word)) {
          score += weights.wordMatch * 0.6;  // URL 分词匹配权重适当提高
        }

        // 7. 添加部分词匹配逻辑
        const partialMatches = findPartialMatches(word, lowerTitle);
        if (partialMatches > 0) {
          score += weights.partialWordMatch * partialMatches * 0.5;
        }
      }
    });

    // 5. 模糊匹配（编辑距离）
    if (title) {
      const fuzzyScore = calculateFuzzyMatch(lowerQuery, lowerTitle);
      if (fuzzyScore > 0.85) {  // 提高相似度阈值
        score += weights.fuzzyMatch * Math.pow(fuzzyScore, 2); // 使用平方增加高相似度的权重
      }
    }


    // 6. 长度惩罚因子（避免过长的结果）
    const lengthPenalty = Math.max(1, Math.log2(lowerTitle.length / lowerQuery.length));
    score = score / lengthPenalty;

    // 7. 添加时间衰减因子（如果有时间戳）
    if (title && title.timestamp) {
      const daysOld = (Date.now() - title.timestamp) / (1000 * 60 * 60 * 24);
      const timeDecay = Math.exp(-daysOld / 60);  // 延长半衰期到 60 天
      score *= (0.7 + 0.3 * timeDecay);  // 保留基础分数的 70%
    }

    return Math.round(score * 100) / 100;
  }

  // 计算模糊匹配分数
  function calculateFuzzyMatch(query, text) {
    if (query.length === 0 || text.length === 0) return 0;
    if (query === text) return 1;

    const maxLength = Math.max(query.length, text.length);
    const distance = levenshteinDistance(query, text);
    return (maxLength - distance) / maxLength;
  }
  // 辅助函数：查找部分词匹配数量
  function findPartialMatches(word, text) {
    let count = 0;
    let pos = 0;
    while ((pos = text.indexOf(word.substring(0, Math.ceil(word.length * 0.7)), pos)) !== -1) {
      count++;
      pos += 1;
    }
    return count;
  }

  // Levenshtein 距离计算
  function levenshteinDistance(a, b) {
    const matrix = Array(b.length + 1).fill().map(() => Array(a.length + 1).fill(0));

    for (let i = 0; i <= a.length; i++) matrix[0][i] = i;
    for (let j = 0; j <= b.length; j++) matrix[j][0] = j;

    for (let j = 1; j <= b.length; j++) {
      for (let i = 1; i <= a.length; i++) {
        const substitutionCost = a[i - 1] === b[j - 1] ? 0 : 1;
        matrix[j][i] = Math.min(
          matrix[j][i - 1] + 1,                   // 删除
          matrix[j - 1][i] + 1,                   // 插入
          matrix[j - 1][i - 1] + substitutionCost // 替换
        );
      }
    }
    return matrix[b.length][a.length];
  }

  function updateSidebarDefaultBookmarkIndicator() {
    const defaultBookmarkId = localStorage.getItem('defaultBookmarkId');
    if (defaultBookmarkId) {
      selectSidebarFolder(defaultBookmarkId);
    }
    updateSidebarHomepageIndicators();
  }

  function updateBookmarksDisplay(parentId, movedItemId, newIndex) {
    return new Promise((resolve, reject) => {
      chrome.bookmarks.getSubTree(parentId, (results) => {
        if (chrome.runtime.lastError) {
          reject(chrome.runtime.lastError);
          return;
        }

        const node = results && results[0];
        if (!node) {
          reject(new Error('Folder not found'));
          return;
        }

        const bookmarksContainer = document.querySelector('.bookmarks-container');

        // 先隐藏容器
        bookmarksContainer.style.opacity = '0';
        bookmarksContainer.style.transform = 'translateY(20px)';

        // 更新缓存
        bookmarksCache.set(parentId, node.children || []);

        // 更新本地排序缓存
        bookmarkOrderCache[parentId] = (node.children || []).map(b => b.id);

        displayBookmarks(node);

        if (movedItemId) {
          highlightBookmark(movedItemId);
        }

        // 更新文件夹名称
        updateFolderName(parentId);

        // 使用 requestAnimationFrame 来确保 DOM 更新后再显示容器
        requestAnimationFrame(() => {
          requestAnimationFrame(() => {
            bookmarksContainer.style.opacity = '1';
            bookmarksContainer.style.transform = 'translateY(0)';
          });
        });

        resolve();
      });
    });
  }



  new Sortable(tabsContainer, {
    animation: 150,
    onEnd: function (evt) {
      const orderedEngines = Array.from(tabsContainer.children).map(tab => tab.getAttribute('data-engine'));
      localStorage.setItem('orderedSearchEngines', JSON.stringify(orderedEngines));
    }
  });


  searchInput.addEventListener('focus', function () {
    searchForm.classList.add('focused');
  });

  searchInput.addEventListener('blur', function () {
    searchForm.classList.remove('focused');
  });

  if (!searchForm || !searchInput || !tabsContainer || !searchEngineIcon) {
    return;
  }



  function updateSubmitButtonState() {
    if (searchInput.value.trim() === '') {
      tabsContainer.style.display = 'none';
    } else {
      // 只有当搜索建议列表不为空时才显示 tabs-container
      if (searchSuggestions.children.length > 0) {
        tabsContainer.style.display = 'flex';
      } else {
        tabsContainer.style.display = 'none';
      }
    }
  }



  function debounce(func, wait) {
    let timeout;
    return function(...args) {
      clearTimeout(timeout);
      timeout = setTimeout(() => func.apply(this, args), wait);
    };
  }


  function queueSearch() {
    const query = searchInput.value.trim();
    if (query === '') {
      return;
    }
    searchQueue.push(query);
    processSearchQueue();
  }

  function processSearchQueue() {
    if (isSearching || searchQueue.length === 0) {
      return;
    }
    
    const query = searchQueue.shift();
    debouncedPerformSearch(query);
  }

  function setDefaultSearchEngine(engine) {
    console.log('[Settings] Setting new default engine:', engine);
    defaultSearchEngine = engine;
    localStorage.setItem('selectedSearchEngine', engine);
  }

  // 修改 getSearchUrl 函数,使用 SearchEngineManager 中的配置
  function getSearchUrl(engine, query) {
    const allEngines = SearchEngineManager.getAllEngines();
    const engineConfig = allEngines.find(e => {
      // 匹配引擎名称或别名
      return e.name.toLowerCase() === engine.toLowerCase() ||
        (e.aliases && e.aliases.some(alias => alias.toLowerCase() === engine.toLowerCase()));
    });

    if (!engineConfig) {
      // 如果找不到对应的引擎配置,使用默认引擎
      const defaultEngine = SearchEngineManager.getDefaultEngine();
      return defaultEngine.url + encodeURIComponent(query);
    }

    // 确保 URL 中包含查询参数占位符
    const url = engineConfig.url.includes('%s') ? 
      engineConfig.url.replace('%s', encodeURIComponent(query)) :
      engineConfig.url + encodeURIComponent(query);

    return url;
  }



  // 防抖函
  function debounce(func, wait) {
    let timeout;
    return function (...args) {
      clearTimeout(timeout);
      timeout = setTimeout(() => func.apply(this, args), wait);
    };
  }
  // 添加这个函数定义
  async function getBingSuggestions(query) {
    try {
      const response = await fetch(`https://api.bing.com/osjson.aspx?query=${encodeURIComponent(query)}`);
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }
      const data = await response.json();
      return data[1].map(suggestion => ({
        text: suggestion,
        type: 'bing_suggestion',
        relevance: 1
      }));
    } catch (error) {
      return []; // 返回空数组，以便在出错时程序可以继续运行
    }
  }
  async function getRecentHistory(limit = 100, maxPerDomain = 5) {
    return new Promise((resolve) => {
      chrome.history.search({ text: '', maxResults: limit * 20 }, (historyItems) => {
        const now = Date.now();
        const domainCounts = {};
        const uniqueItems = new Map();

        const recentHistory = historyItems
          // 映射并添加额外信息
          .map(item => {
            const url = new URL(item.url);
            const domain = url.hostname;
            return {
              text: item.title,
              url: item.url,
              domain: domain,
              type: 'history',
              relevance: 1,
              timestamp: item.lastVisitTime
            };
          })
          // 按时间排序（最近的优先）
          .sort((a, b) => b.timestamp - a.timestamp)
          // 去重（基于URL和标题）并限制每个域名的数量
          .filter(item => {
            const key = `${item.url}|${item.text}`;
            if (uniqueItems.has(key)) return false;
            
            domainCounts[item.domain] = (domainCounts[item.domain] || 0) + 1;
            if (domainCounts[item.domain] > maxPerDomain) return false;
            
            uniqueItems.set(key, item);
            return true;
          })
          // 应用时间衰减因子
          .map(item => {
            const daysSinceLastVisit = (now - item.timestamp) / (1000 * 60 * 60 * 24);
            item.relevance *= Math.exp(-daysSinceLastVisit / RELEVANCE_CONFIG.timeDecayHalfLife);
            return item;
          })
          // 再次排序，这次基于相关性（考虑了时间衰减）
          .sort((a, b) => b.relevance - a.relevance)
          // 限制结果数量
          .slice(0, limit);

        resolve(recentHistory);
      });
    });
  }

  function searchHistory(query, maxResults = 200) {
    return new Promise((resolve) => {
      const startTime = new Date().getTime() - (30 * 24 * 60 * 60 * 1000); // 搜索最近30天的历史
      chrome.history.search(
        { 
          text: query, 
          startTime: startTime,
          maxResults: maxResults 
        }, 
        (results) => {
          
          // 对历史记录进行去重
          const uniqueResults = Array.from(new Set(results.map(r => r.url)))
            .map(url => results.find(r => r.url === url));
          resolve(uniqueResults);
        }
      );
    });
  }
  // 获取搜索建议
  async function getSuggestions(query) {
    const maxHistoryResults = 200;
    const maxBookmarkResults = 50;
    const maxTotalSuggestions = 50;

    let suggestions = [{ text: query, type: 'search', relevance: Infinity }];

    // 获取设置
    const settings = await new Promise(resolve => {
      chrome.storage.sync.get(
        ['showHistorySuggestions', 'showBookmarkSuggestions'],
        resolve
      );
    });

    // 根据设置获取历史记录建议
    let historySuggestions = [];
    if (settings.showHistorySuggestions !== false) {
      const historyItems = await searchHistory(query, maxHistoryResults);
      historySuggestions = historyItems.map(item => ({
        text: item.title,
        url: item.url,
        type: 'history',
        relevance: calculateRelevance(query, item.title, item.url),
        timestamp: item.lastVisitTime
      }));
    }

    // 根据设置获取书签建议
    let bookmarkSuggestions = [];
    if (settings.showBookmarkSuggestions !== false) {
      const bookmarkItems = await new Promise(resolve => {
        chrome.bookmarks.search(query, resolve);
      });
      bookmarkSuggestions = bookmarkItems.slice(0, maxBookmarkResults).map(item => ({
        text: item.title,
        url: item.url,
        type: 'bookmark',
        relevance: calculateRelevance(query, item.title, item.url) * RELEVANCE_CONFIG.bookmarkRelevanceBoost
      }));
    }

    // 合并所有建议
    suggestions.push(
      ...historySuggestions,
      ...bookmarkSuggestions
    );

    // 对结果进行排序和去重
    const uniqueSuggestions = Array.from(new Set(suggestions.map(s => s.url)))
      .map(url => suggestions.find(s => s.url === url))
      .sort((a, b) => b.relevance - a.relevance);

    // 平衡和交替显示结果
    const balancedResults = await balanceResults(uniqueSuggestions, maxTotalSuggestions);

    return balancedResults;
  }

  function calculateRelevance(query, title, url) {
    // 基础设置
    const weights = {
      exactTitleMatch: 100,    // 标题完全匹配权重
      exactUrlMatch: 80,       // URL完全匹配权重
      titleStartsWith: 70,     // 标题开头匹配权重
      urlStartsWith: 60,       // URL开头匹配权重
      titleIncludes: 50,       // 标题包含匹配权重
      urlIncludes: 40,         // URL包含匹配权重
      wordMatch: 30,           // 分词匹配权重
      fuzzyMatch: 20           // 模糊匹配权重
    };

    // 数据预处理
    const lowerQuery = query.toLowerCase().trim();
    const lowerTitle = (title || '').toLowerCase().trim();
    const lowerUrl = (url || '').toLowerCase().trim();
    const queryWords = lowerQuery.split(/\s+/);  // 将查询分词

    let score = 0;

    // 1. 完全匹配检查
    if (lowerTitle === lowerQuery) {
      score += weights.exactTitleMatch;
    }
    if (lowerUrl === lowerQuery) {
      score += weights.exactUrlMatch;
    }

    // 2. 开头匹配检查
    if (lowerTitle.startsWith(lowerQuery)) {
      score += weights.titleStartsWith;
    }
    if (lowerUrl.startsWith(lowerQuery)) {
      score += weights.urlStartsWith;
    }

    // 3. 包含匹配检查
    if (lowerTitle.includes(lowerQuery)) {
      score += weights.titleIncludes;
    }
    if (lowerUrl.includes(lowerQuery)) {
      score += weights.urlIncludes;
    }

    // 4. 分词匹配
    queryWords.forEach(word => {
      if (word.length > 1) {  // 忽略单字符词
        if (lowerTitle.includes(word)) {
          score += weights.wordMatch;
        }
        if (lowerUrl.includes(word)) {
          score += weights.wordMatch / 2;  // URL分词匹配权重较低
        }
      }
    });

    // 5. 模糊匹配（编辑距离）
    if (title) {
      const fuzzyScore = calculateFuzzyMatch(lowerQuery, lowerTitle);
      if (fuzzyScore > 0.8) {  // 相似度阈值
        score += weights.fuzzyMatch * fuzzyScore;
      }
    }

    // 6. 长度惩罚因子（避免过长的结果）
    const lengthPenalty = Math.max(1, Math.log(lowerTitle.length / lowerQuery.length));
    score = score / lengthPenalty;

    // 7. 添加时间衰减因子（如果有时间戳）
    if (title && title.timestamp) {
      const daysOld = (Date.now() - title.timestamp) / (1000 * 60 * 60 * 24);
      const timeDecay = Math.exp(-daysOld / 30);  // 30天的半衰期
      score *= timeDecay;
    }

    return Math.round(score * 100) / 100;  // 保留两位小数
  }

  // 计算模糊匹配分数
  function calculateFuzzyMatch(query, text) {
    if (query.length === 0 || text.length === 0) return 0;
    if (query === text) return 1;

    const maxLength = Math.max(query.length, text.length);
    const distance = levenshteinDistance(query, text);
    return (maxLength - distance) / maxLength;
  }

  // Levenshtein 距离计算
  function levenshteinDistance(a, b) {
    const matrix = Array(b.length + 1).fill().map(() => Array(a.length + 1).fill(0));

    for (let i = 0; i <= a.length; i++) matrix[0][i] = i;
    for (let j = 0; j <= b.length; j++) matrix[j][0] = j;

    for (let i = 1; i <= b.length; i++) {
      for (let j = 1; j <= a.length; j++) {
        const substitutionCost = a[i - 1] === b[j - 1] ? 0 : 1;
        matrix[j][i] = Math.min(
          matrix[j][i - 1] + 1,                   // 删除
          matrix[j - 1][i] + 1,                   // 插入
          matrix[j - 1][i - 1] + substitutionCost // 替换
        );
      }
    }
    return matrix[b.length][a.length];
  }

  // Levenshtein 距离函数（如果之前没有定义的话）
  function levenshteinDistance(a, b) {
    const matrix = [];

    for (let i = 0; i <= b.length; i++) {
      matrix[i] = [i];
    }

    for (let j = 0; j <= a.length; j++) {
      matrix[0][j] = j;
    }

    for (let i = 1; i <= b.length; i++) {
      for (let j = 1; j <= a.length; j++) {
        if (b.charAt(i - 1) === a.charAt(j - 1)) {
          matrix[i][j] = matrix[i - 1][j - 1];
        } else {
          matrix[i][j] = Math.min(
            matrix[i - 1][j - 1] + 1,
            matrix[i][j - 1] + 1,
            matrix[i - 1][j] + 1
          );
        }
      }
    }

    return matrix[b.length][a.length];
  }

  async function balanceResults(suggestions, maxResults) {
    const currentSuggestion = suggestions.filter(s => s.type === 'search');
    let bookmarks = suggestions.filter(s => s.type === 'bookmark');
    let histories = suggestions.filter(s => s.type === 'history');
    let bingSuggestions = suggestions.filter(s => s.type === 'bing_suggestion');

    // 应用时间衰减因子到历史记录
    const now = Date.now();
    histories = histories.map(h => {
      const daysSinceLastVisit = (now - h.timestamp) / (1000 * 60 * 60 * 24);
      if (daysSinceLastVisit < 7) { // 如果是最近7天内的记录
        h.relevance *= 1.5; // 为最近的记录提供额外的提升
      }
      h.relevance *= Math.exp(-daysSinceLastVisit / RELEVANCE_CONFIG.timeDecayHalfLife);
      return h;
    });

    // 为书签提供轻微的相关性提
    bookmarks = bookmarks.map(b => {
      b.relevance *= RELEVANCE_CONFIG.bookmarkRelevanceBoost;
      return b;
    });

    // 重新排序
    bookmarks.sort((a, b) => b.relevance - a.relevance);
    histories.sort((a, b) => b.relevance - a.relevance);
    bingSuggestions.sort((a, b) => b.relevance - a.relevance);

    const results = [...currentSuggestion];
    const maxEachType = Math.floor((maxResults - 1) / 4); // 现在我们有4种类型

    // 交替添加不同类型的建议
    for (let i = 0; i < maxEachType * 4; i++) {
      if (i % 4 === 0 && bookmarks.length > 0) {
        results.push(bookmarks.shift());
      } else if (i % 4 === 1 && histories.length > 0) {
        results.push(histories.shift());
      } else if (i % 4 === 2 && bingSuggestions.length > 0) {
        results.push(bingSuggestions.shift());
      } else if (histories.length > 0) {
        results.push(histories.shift());
      }
    }

    // 如果还有空间，添加剩余的最相关项
    while (results.length < maxResults && (bookmarks.length > 0 || histories.length > 0 || bingSuggestions.length > 0)) {
      if (bookmarks.length === 0) {
        if (histories.length === 0) {
          results.push(bingSuggestions.shift());
        } else if (bingSuggestions.length === 0) {
          results.push(histories.shift());
        } else {
          results.push(histories[0].relevance > bingSuggestions[0].relevance ? histories.shift() : bingSuggestions.shift());
        }
      } else if (histories.length === 0) {
        if (bookmarks.length === 0) {
          results.push(bingSuggestions.shift());
        } else if (bingSuggestions.length === 0) {
          results.push(bookmarks.shift());
        } else {
          results.push(bookmarks[0].relevance > bingSuggestions[0].relevance ? bookmarks.shift() : bingSuggestions.shift());
        }
      } else if (bingSuggestions.length === 0) {
        results.push(bookmarks[0].relevance > histories[0].relevance ? bookmarks.shift() : histories.shift());
      } else {
        const maxRelevance = Math.max(bookmarks[0].relevance, histories[0].relevance, bingSuggestions[0].relevance);
        if (maxRelevance === bookmarks[0].relevance) {
          results.push(bookmarks.shift());
        } else if (maxRelevance === histories[0].relevance) {
          results.push(histories.shift());
        } else {
          results.push(bingSuggestions.shift());
        }
      }
    }

    // 计算用户相关性
    const suggestionsWithUserRelevance = await calculateUserRelevance(results);

    // 重新排序，使用 userRelevance 而不是 relevance
    suggestionsWithUserRelevance.sort((a, b) => b.userRelevance - a.userRelevance);

    return suggestionsWithUserRelevance;
  }

  const USER_BEHAVIOR_KEY = 'userSearchBehavior';

  // 在文件顶部定义 MAX_BEHAVIOR_ENTRIES
  const MAX_BEHAVIOR_ENTRIES = 1000; // 你可以根据需要调整这个值

  // 获取用户行为数据
  async function getUserBehavior() {
    return new Promise((resolve) => {
      chrome.storage.local.get(USER_BEHAVIOR_KEY, (result) => {
        const behavior = result[USER_BEHAVIOR_KEY] || {};
        resolve(behavior); // 直接返回行为数据，不进行清理
      });
    });
  }

  // 保存用户行为数据
  async function saveUserBehavior(key, increment = 1) {
    const behavior = await getUserBehavior();
    const now = Date.now();

    if (!behavior[key]) {
      behavior[key] = { count: 0, lastUsed: now };
    }

    behavior[key].count += increment; // 增加计数
    behavior[key].lastUsed = now; // 更新最后用时间

    // 检查条目数并清理
    if (Object.keys(behavior).length > MAX_BEHAVIOR_ENTRIES) {
      const sortedEntries = Object.entries(behavior)
        .sort(([, a], [, b]) => a.lastUsed - b.lastUsed); // 按最后使用时间排序
      sortedEntries.slice(0, sortedEntries.length - MAX_BEHAVIOR_ENTRIES).forEach(([key]) => {
        delete behavior[key]; // 删除最旧的条目
      });
    }

    return new Promise((resolve) => {
      chrome.storage.local.set({ [USER_BEHAVIOR_KEY]: behavior }, resolve); // 直接保存行为数据
    });
  }

  // 计算用户相关性
  async function calculateUserRelevance(suggestions) {
    const behavior = await getUserBehavior();
    const now = Date.now();

    return suggestions.map(suggestion => {
      const key = suggestion.url || suggestion.text;
      const behaviorData = behavior[key];

      if (!behaviorData) return { ...suggestion, userRelevance: suggestion.relevance };

      const daysSinceLastUse = (now - behaviorData.lastUsed) / (1000 * 60 * 60 * 24);
      const recencyFactor = Math.exp(-daysSinceLastUse / 30); // 30天的半衰期
      const behaviorScore = behaviorData.count * recencyFactor;

      return {
        ...suggestion,
        userRelevance: suggestion.relevance * (1 + behaviorScore * 0.1) // 增加最多10%的权重
      };
    });
  }

  let allSuggestions = [];
  let displayedSuggestions = 0;
  const suggestionsPerLoad = 10; // 每次加载10个建议

  let isScrollListenerAttached = false;

  function showSuggestions(suggestions) {
    if (!Array.isArray(suggestions) || suggestions.length === 0) {
      hideSuggestions();
      return;
    }

    allSuggestions = suggestions;
    displayedSuggestions = 0;
    searchSuggestions.innerHTML = '';
  
    const searchForm = document.querySelector('.search-form');
    searchForm.classList.add('focused-with-suggestions');

    const suggestionsWrapper = document.querySelector('.search-suggestions-wrapper');
    if (suggestionsWrapper) {
      suggestionsWrapper.style.display = 'block';
    }
    searchSuggestions.style.display = 'block';

    // 显示 line-container
    const lineContainer = document.getElementById('line-container');
    lineContainer.style.display = 'block'; // 显示线条

    // Set a fixed height for the suggestions container
    searchSuggestions.style.maxHeight = '390px'; // Adjust this value as needed
    searchSuggestions.style.overflowY = 'auto';

    loadMoreSuggestions();

    if (!isScrollListenerAttached) {
      searchSuggestions.addEventListener('scroll', throttledHandleScroll);
      isScrollListenerAttached = true;
    }
    setTimeout(() => {
    }, 0);
  }

  function loadMoreSuggestions() {
    if (!Array.isArray(allSuggestions) || allSuggestions.length === 0) {
      return;
    }

    const remainingSuggestions = allSuggestions.length - displayedSuggestions;
    const suggestionsToAdd = Math.min(remainingSuggestions, 10);

    if (suggestionsToAdd <= 0) {
      return;
    }

    const fragment = document.createDocumentFragment();
    for (let i = displayedSuggestions; i < displayedSuggestions + suggestionsToAdd; i++) {
      const li = createSuggestionElement(allSuggestions[i]);
      fragment.appendChild(li);
    }

    searchSuggestions.appendChild(fragment);
    displayedSuggestions += suggestionsToAdd;

  }

  function throttle(func, limit) {
    let inThrottle;
    return function() {
      const args = arguments;
      const context = this;
      if (!inThrottle) {
        func.apply(context, args);
        inThrottle = true;
        setTimeout(() => inThrottle = false, limit);
      }
    }
  }

  const throttledHandleScroll = throttle(function() {
    const scrollPosition = searchSuggestions.scrollTop + searchSuggestions.clientHeight;
    const scrollHeight = searchSuggestions.scrollHeight;
    if (scrollPosition >= scrollHeight - 20 && displayedSuggestions < allSuggestions.length) {
      loadMoreSuggestions();
    }
  }, 200);  // 限制为每200毫秒最多执行一次

  function showNoMoreSuggestions() {
    const existingNoMore = searchSuggestions.querySelector('.no-more-suggestions');
    if (!existingNoMore) {
      const noMoreElement = document.createElement('li');
      noMoreElement.className = 'no-more-suggestions';
      noMoreElement.style.height = '38px'; // 设置一个固定高度，与他建议项保持一致
      noMoreElement.style.visibility = 'hidden'; // 使元素不可见，但保留空间
      searchSuggestions.appendChild(noMoreElement);
    }
  }

  // 修改创建建议元素的函数
  function createSuggestionElement(suggestion) {
    const li = document.createElement('li');
    const displayUrl = suggestion.url ? formatUrl(suggestion.url) : '';
    li.setAttribute('data-type', suggestion.type);
    if (suggestion.url) {
      li.setAttribute('data-url', suggestion.url);
    }
    const searchSvgIcon = `<svg class="suggestion-icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="20" height="20">
  <path d="M466.624 890.432a423.296 423.296 0 0 1-423.936-423.04C42.688 233.728 231.936 42.624 466.56 42.624a423.68 423.68 0 0 1 423.936 424.64 437.952 437.952 0 0 1-56.32 213.12 47.872 47.872 0 0 1-64.128 17.28 48 48 0 0 1-17.216-64.256c29.76-50.176 43.84-106.56 43.84-166.144-1.6-183.36-148.608-330.624-330.112-330.624a330.432 330.432 0 0 0-330.112 330.624 329.408 329.408 0 0 0 330.112 330.688c57.92 0 115.776-15.68 165.824-43.904a47.872 47.872 0 0 1 64.128 17.28 48 48 0 0 1-17.152 64.192 443.584 443.584 0 0 1-212.8 54.848z" fill="#334155"></path>
  <path d="M466.624 890.432a423.296 423.296 0 0 1-423.936-423.04c0-75.264 20.288-148.928 56.32-213.12a47.872 47.872 0 0 1 64.128-17.28 48 48 0 0 1 17.216 64.256 342.08 342.08 0 0 0-43.84 166.08c0 181.76 147.072 330.688 330.112 330.688a329.408 329.408 0 0 0 330.112-330.688A330.432 330.432 0 0 0 466.56 136.704c-57.856 0-115.776 15.68-165.824 43.84a47.872 47.872 0 0 1-64.128-17.216 48 48 0 0 1 17.216-64.256A436.032 436.032 0 0 1 466.56 42.688c233.088 0 422.4 189.568 422.4 424.64a422.016 422.016 0 0 1-422.4 423.104z" fill="#334155"></path>
  <path d="M934.4 981.312a44.992 44.992 0 0 1-32.832-14.08l-198.72-199.04c-18.752-18.816-18.752-48.576 0-65.792 18.752-18.816 48.512-18.816 65.728 0l198.656 199.04c18.816 18.752 18.816 48.576 0 65.792a47.68 47.68 0 0 1-32.832 14.08z" fill="#334155"></path>
</svg>`;
    // 限制建议文本的长度
    const maxTextLength = 20; // 你可以根据需要调整这个值
    const truncatedText = suggestion.text.length > maxTextLength 
      ? suggestion.text.substring(0, maxTextLength) + '...' 
      : suggestion.text;

    const safeText = escapeHtml(truncatedText);
    const safeTitle = escapeHtml(suggestion.text);
    const safeUrl = escapeHtml(displayUrl);
    const safeType = escapeHtml(suggestion.type);
    li.innerHTML = `
    ${suggestion.type === 'search' ? searchSvgIcon : '<span class="material-icons suggestion-icon"></span>'}
    <div class="suggestion-content">
      <span class="suggestion-text" title="${safeTitle}">${safeText}</span>
      ${safeUrl ? `<span class="suggestion-dash">-</span><span class="suggestion-url">${safeUrl}</span>` : ''}
    </div>
    <span class="suggestion-type">${safeType}</span>
  `;

    if (suggestion.url && suggestion.type !== 'search') {
      getFavicon(suggestion.url, (faviconUrl) => {
        const iconSpan = li.querySelector('.suggestion-icon');
        if (!iconSpan || !faviconUrl) return;
        const img = document.createElement('img');
        img.src = faviconUrl;
        img.alt = '';
        img.className = 'favicon';
        iconSpan.replaceChildren(img);
      });
    }

    li.addEventListener('click', async () => {
      if (suggestion.url) {
        // 根据设置决定打开方式
        chrome.storage.sync.get('openSearchInNewTab', (result) => {
          const openInNewTab = result.openSearchInNewTab !== false; // 默认为 true
          
          if (openInNewTab) {
            window.open(suggestion.url, '_blank');
          } else {
            window.location.href = suggestion.url;
          }
        });
        
        await saveUserBehavior(suggestion.url);
      } else {
        searchInput.value = suggestion.text;
        searchInput.focus();
        queueSearch();
        await saveUserBehavior(suggestion.text);
      }
      hideSuggestions();
    });

    return li;
  }

  function formatUrl(url) {
    try {
      const urlObj = new URL(url);
      let domain = urlObj.hostname;

      // 移除 'www.' 前缀（如果存在）
      domain = domain.replace(/^www\./, '');

      // 如果路径不只是 '/'
      let path = urlObj.pathname;
      if (path && path !== '/') {
        // 截断长路径
        path = path.length > 10 ? path.substring(0, 10) + '...' : path;
        domain += path;
      }

      return domain;
    } catch (e) {
      // 如果 URL 解析失败，返回空字符串
      return '';
    }
  }


  function getFavicon(url, callback) {
    if (isChromeInternalUrl(url)) {
      callback(CHROME_BROWSER_ICON);
      return;
    }
    const faviconUrl = bookmarkFaviconURL(url);
    const img = new Image();
    img.onload = function () {
      callback(faviconUrl);
    };
    img.onerror = function () {
      callback(''); // Return an empty string if favicon is not found
    };
    img.src = faviconUrl;
  }

  // Add this function to fetch favicon online as a fallback
  function fetchFaviconOnline(url, callback) {
    const domain = new URL(url).hostname;
    const faviconUrl = `https://www.google.com/s2/favicons?domain=${domain}&sz=32`;
    const img = new Image();
    img.onload = function () {
      cacheFavicon(domain, faviconUrl);
      callback(faviconUrl);
    };
    img.onerror = function () {
      callback('');
    };
    img.src = faviconUrl;
  }

  // Add this function to cache favicons
  function cacheFavicon(domain, faviconUrl) {
    const data = {};
    data[domain] = faviconUrl;
    chrome.storage.local.set(data);
  }

  async function showDefaultSuggestions() {
    // 首先检查设置
    const settings = await new Promise(resolve => {
      chrome.storage.sync.get(
        ['showHistorySuggestions', 'showBookmarkSuggestions'],
        resolve
      );
    });

    let suggestions = [];

    // 只有在启用了历史记录建议时才获取历史记录
    if (settings.showHistorySuggestions !== false) {
      const recentHistory = await getRecentHistory(20);
      suggestions = suggestions.concat(recentHistory.map(item => ({
        text: item.text,
        url: item.url,
        type: 'history',
        relevance: item.relevance
      })));
    } else {
      // 如果历史记录已关闭且没有搜索词，不显示任何建议
      if (!searchInput.value.trim()) {
        hideSuggestions();
        return;
      }
    }

    // 如果启用了书签建议，可以在这里添加最近的书签
    if (settings.showBookmarkSuggestions !== false) {
      const recentBookmarks = await new Promise(resolve => {
        chrome.bookmarks.getRecent(10, resolve);
      });
      
      suggestions = suggestions.concat(recentBookmarks.map(item => ({
        text: item.title,
        url: item.url,
        type: 'bookmark',
        relevance: 1
      })));
    }

    // 如果没有任何建议，则不显示建议列表
    if (suggestions.length === 0) {
      hideSuggestions();
      return;
    }

    showSuggestions(suggestions);
  }

  // 修改 handleInput 函数
  const handleInput = debounce(async () => {
    const query = searchInput.value.trim();
    showLoadingIndicator();
    
    if (query) {
      const suggestions = await getSuggestions(query);
      hideLoadingIndicator();
      // 移除 length > 1 的判断，因为我们总是想显示搜索建议
      showSuggestions(suggestions);
    } else {
      hideLoadingIndicator();
      showDefaultSuggestions();
    }
    updateSubmitButtonState();
  }, 300);

  // 同样修改 focus 事件监听器
  searchInput.addEventListener('focus', async () => {
    const searchForm = document.querySelector('.search-form');
    searchForm.classList.add('focused');
    
    if (searchInput.value.trim() === '') {
      await showDefaultSuggestions();
    } else {
      const suggestions = await getSuggestions(searchInput.value.trim());
      // 移除 length > 1 的判断
      showSuggestions(suggestions);
    }
  });

  // 处理输入事件
  searchInput.addEventListener('input', () => {
    handleInput();
    updateSubmitButtonState();
    if (searchInput.value.trim() === '') {
      showDefaultSuggestions();
    }
  });

  // 处理键盘导航
  searchInput.addEventListener('keydown', (e) => {
    const items = searchSuggestions.querySelectorAll('li');
    let index = Array.from(items).findIndex(item => item.classList.contains('keyboard-selected'));

    switch (e.key) {
      case 'ArrowDown':
        e.preventDefault();
        if (index < items.length - 1) index++;
        break;
      case 'ArrowUp':
        e.preventDefault();
        if (index > 0) index--;
        break;
      case 'Enter':
        e.preventDefault();
        if (e.metaKey || e.ctrlKey) {
          // 处理 Cmd/Ctrl + Enter
          const query = searchInput.value.trim();
          if (query) {
            requireProFeature(PRO_FEATURES.COMPARE_SEARCH).then((allowed) => {
              if (allowed) openAllSearchEngines(query);
            });
          }
        } else if (index !== -1) {
          e.stopPropagation(); // 阻止事件冒泡
          const selectedItem = items[index];
          const suggestionType = selectedItem.getAttribute('data-type');
          if (suggestionType === 'history' || suggestionType === 'bookmark') {
            const url = selectedItem.getAttribute('data-url');
            if (url) {
              window.open(url, '_blank');
              hideSuggestions();
              return;
            }
          }
          selectedItem.click();
        } else {
          performSearch(searchInput.value.trim());
        }
        return;
      default:
        return;
    }

    items.forEach(item => item.classList.remove('keyboard-selected'));
    if (index !== -1) {
      items[index].classList.add('keyboard-selected');
      // 只在选择搜索建议时更新输入框的值
      const selectedItem = items[index];
      const suggestionType = selectedItem.getAttribute('data-type');
      if (suggestionType === 'search') {
        searchInput.value = selectedItem.querySelector('.suggestion-text').textContent;
      }
    }
  })

  // 添加防抖函数
  function debounce(func, wait) {
    let timeout;
    return function executedFunction(...args) {
      const later = () => {
        clearTimeout(timeout);
        func(...args);
      };
      clearTimeout(timeout);
      timeout = setTimeout(later, wait);
    };
  }



  function hideSuggestions() {
    if (isChangingSearchEngine) {
      return; // 如果正在切换搜索引擎，不隐藏建议列表
    }
    const searchForm = document.querySelector('.search-form');
    searchForm.classList.remove('focused-with-suggestions');

    const suggestionsWrapper = document.querySelector('.search-suggestions-wrapper');
    if (suggestionsWrapper) {
      suggestionsWrapper.style.display = 'none';
    }
    if (searchSuggestions) {
      searchSuggestions.style.display = 'none';
      searchSuggestions.innerHTML = ''; // Clear the suggestions
    }

    // 隐藏 line-container
    const lineContainer = document.getElementById('line-container');
    lineContainer.style.display = 'none'; // 隐藏线条

    if (isScrollListenerAttached) {
      searchSuggestions.removeEventListener('scroll', throttledHandleScroll);
      isScrollListenerAttached = false;
    }

    // Reset suggestions-related variables
    allSuggestions = [];
    displayedSuggestions = 0;
  }

  function showLoadingIndicator() {
    const loadingIndicator = document.createElement('div');
    loadingIndicator.className = 'loading-indicator';
    loadingIndicator.innerHTML = `
    <svg class="loading-spinner" viewBox="0 0 50 50">
      <circle class="spinner-path" cx="25" cy="25" r="20" fill="none" stroke-width="4"></circle>
    </svg>
  `;
    searchSuggestions.appendChild(loadingIndicator);
  }

  function hideLoadingIndicator() {
    const loadingIndicator = searchSuggestions.querySelector('.loading-indicator');
    if (loadingIndicator) {
      loadingIndicator.remove();
    }
  }


  // 修改这个函数
  function openAllSearchEngines(query) {
    const enabledEngines = SearchEngineManager.getEnabledEngines();

    const urls = enabledEngines
      .map(engine => getSearchUrl(engine.name, query));

    if (urls.length > 0) {
      window.lastSearchTrigger = 'cmdCtrlEnter';

      openMultipleTabsAndGroup(urls, query).then((response) => {
        if (!response || !response.success) {
          console.error('打开多个标签页或创建标签组失败:', response ? response.error : '未知错误');
        }
      });
    } else {
      console.log('没有启用的搜索引擎');
    }
  }
});



// 确保在 DOMContentLoaded 时调用创建函数
document.addEventListener('DOMContentLoaded', function() {
  createSearchEngineDropdown();
  // ... 其他初始化代码 ...
});






  // 在适当时机调用此函数
  document.addEventListener('DOMContentLoaded', setVersionNumber);

  // 修改文档点击事件监听器，同时处理书签和文件夹的上下文菜单
  document.addEventListener('click', function (event) {
    // 关闭书签上下文菜单
    if (contextMenu) {
      contextMenu.style.display = 'none';
      currentBookmark = null;
    }
    
    // 关闭文件夹上下文菜单
    if (bookmarkFolderContextMenu) {
      bookmarkFolderContextMenu.style.display = 'none';
      currentBookmarkFolder = null;
    }
  });

  // 为上下文菜单添加阻止冒泡，防止点击菜单本身时关闭
  if (contextMenu) {
    contextMenu.addEventListener('click', function(event) {
      event.stopPropagation();
    });
  }

  if (bookmarkFolderContextMenu) {
    bookmarkFolderContextMenu.addEventListener('click', function(event) {
      event.stopPropagation();
    });
  }

  // 添加一个全局函数用于更新快捷链接显示状态
  function updateQuickLinksVisibility() {
    chrome.storage.sync.get(['enableQuickLinks'], function(result) {
      const quickLinksWrapper = document.querySelector('.recently-visited-links-wrapper');
      if (quickLinksWrapper) {
        quickLinksWrapper.style.display = result.enableQuickLinks !== false ? 'flex' : 'none';
      }
    });
  }

  // 监听存储变化
  chrome.storage.onChanged.addListener(function(changes, namespace) {
    if (namespace === 'sync' && changes.enableQuickLinks) {
      updateQuickLinksVisibility();
    }
  });

  // 添加搜索引擎变更事件监听
  document.addEventListener('defaultSearchEngineChanged', (event) => {
    console.log('[Search] Default engine changed:', event.detail.engine);
    // 可以在这里添加其他需要响应搜索引擎变更的逻辑
    createTemporarySearchTabs(); // 添加这行以更新临时搜索标签
  });


  // 新增辅助函数


  async function toggleDefaultFolder(folder) {
    if (!folder?.dataset?.id) {
      console.error('Invalid folder object:', folder);
      return;
    }

    const folderId = folder.dataset.id;
    // 根据不同的文件夹元素结构获取文件夹名称
    let folderName;
    if (folder.classList.contains('bookmark-folder')) {
        // 主内容区的文件夹卡片
        folderName = folder.querySelector('.card-title')?.textContent;
    } else {
        // 侧边栏的文件夹
        folderName = folder.dataset.title || folder.textContent.trim();
    }
    
    console.log('Toggle default folder:', {
        folderId,
        folderName,
        element: folder
    });

    if (!folderName) {
        console.error('Could not find folder name');
        return;
    }

    try {
        const data = await chrome.storage.sync.get('defaultFolders');
        let defaultFolders = data.defaultFolders?.items || [];
        const isDefault = defaultFolders.some(f => f.id === folderId);

        if (isDefault) {
            defaultFolders = defaultFolders.filter(f => f.id !== folderId);
            defaultFolders = defaultFolders.map((f, index) => ({
                ...f,
                order: index
            }));
            showToast(chrome.i18n.getMessage("removedFromDefaultFolders", [folderName]));
        } else {
            if (defaultFolders.length >= 8) {
                showToast(chrome.i18n.getMessage("maxDefaultFoldersReached"));
                return;
            }
            defaultFolders.push({
                id: folderId,
                name: folderName,
                order: defaultFolders.length
            });
            showToast(chrome.i18n.getMessage("addedToDefaultFolders", [folderName]));
        }

        await chrome.storage.sync.set({
            defaultFolders: {
                items: defaultFolders,
                lastUpdated: Date.now()
            }
        });

        // Pin/Unpin：只刷新标签和树上的固定指示，避免重建整棵树导致状态不同步
        await initDefaultFoldersTabs({
          refreshTree: false,
          switchFolder: false
        });

        // 如果是新添加的默认文件夹，自动切换到该文件夹
        if (!isDefault) {
            await switchToFolder(folderId);
        } else {
            // Unpin 后确保当前树节点立刻去掉固定指示
            await updateSidebarHomepageIndicators(defaultFolders.map(folder => folder.id));
        }

        // 触发更新事件（监听器只同步指示/可见性，避免重复全量初始化）
        document.dispatchEvent(new CustomEvent('defaultFoldersChanged', {
            detail: { folders: defaultFolders }
        }));

    } catch (error) {
        console.error('Error toggling default folder:', error);
        showToast('操作失败，请重试');
    }
  }





  // 监听默认文件夹变化：同步树上的固定指示与标签可见性
  document.addEventListener('defaultFoldersChanged', async (event) => {
    const folderIds = (event.detail?.folders || []).map(folder => folder.id);
    await updateSidebarHomepageIndicators(folderIds);
    updateDefaultFoldersTabsVisibility();
  });

  // 在文档加载完成后初始化
  document.addEventListener('DOMContentLoaded', async () => {
    await initDefaultFoldersTabs({ refreshTree: true, switchFolder: true });
  });



// 获取版本号并设置
function setVersionNumber() {
  const manifest = chrome.runtime.getManifest();
  const versionElement = document.querySelector('.about-version');
  
  if (versionElement && manifest) {
    // 移除 data-i18n 属性，因为我们要直接设置完整的本地化文本
    versionElement.removeAttribute('data-i18n');
    
    // 获取本地化的版本号文本并设置
    const versionText = chrome.i18n.getMessage('version', [manifest.version]);
    versionElement.textContent = versionText;
  }
}

// 确保在 DOM 加载完成后调用
document.addEventListener('DOMContentLoaded', () => {
  // 延迟一小段时间执行，确保其他初始化完成
  setTimeout(setVersionNumber, 100);
});

function updateDefaultFoldersTabsVisibility() {
  const defaultFoldersTabs = document.querySelector('.default-folders-tabs');
  const sidebarContainer = document.getElementById('sidebar-container');
  const tabsContainer = defaultFoldersTabs?.querySelector('.tabs-container');

  if (!defaultFoldersTabs || !tabsContainer) return;

  // 检查标签数量
  const folderTabs = tabsContainer.querySelectorAll('.folder-tab');
  defaultFoldersTabs.classList.toggle('show', folderTabs.length > 1);

  // 处理侧边栏状态
  if (sidebarContainer) {
    defaultFoldersTabs.classList.toggle('sidebar-expanded', !sidebarContainer.classList.contains('collapsed'));
    defaultFoldersTabs.classList.toggle('sidebar-collapsed', sidebarContainer.classList.contains('collapsed'));
  }
}

// 监听侧边栏状态变化
document.addEventListener('DOMContentLoaded', () => {
  const sidebarContainer = document.getElementById('sidebar-container');
  if (sidebarContainer) {
    const observer = new MutationObserver(updateDefaultFoldersTabsVisibility);
    observer.observe(sidebarContainer, { attributes: true, attributeFilter: ['class'] });
  }

  // 初始化状态
  updateDefaultFoldersTabsVisibility();
});

// 在标签更新时调用
document.addEventListener('defaultFoldersChanged', updateDefaultFoldersTabsVisibility);

// 在适当位置添加或修改
function openSettingsModal() {
  const settingsSidebar = document.getElementById('settings-sidebar');
  const settingsOverlay = document.getElementById('settings-overlay');

  if (settingsSidebar) {
    settingsSidebar.classList.add('open');
  }
  if (settingsOverlay) {
    settingsOverlay.classList.add('open');
  }
  document.body.style.overflow = 'hidden';
}

function closeSettingsModal() {
  const settingsSidebar = document.getElementById('settings-sidebar');
  const settingsOverlay = document.getElementById('settings-overlay');

  if (settingsSidebar) {
    settingsSidebar.classList.remove('open');
  }
  if (settingsOverlay) {
    settingsOverlay.classList.remove('open');
  }
  document.body.style.overflow = '';
}

// 确保在 DOMContentLoaded 事件中初始化设置图标点击事件
document.addEventListener('DOMContentLoaded', function() {
  // 设置图标点击事件（SettingsManager 也会绑定；此处作为兜底）
  const settingsIcon = document.querySelector('.settings-icon a');
  if (settingsIcon && !window.settingsManager) {
    settingsIcon.addEventListener('click', function(e) {
      e.preventDefault();
      openSettingsModal();
    });
  }

  const closeButton = document.querySelector('.settings-sidebar-close');
  if (closeButton && !window.settingsManager) {
    closeButton.addEventListener('click', closeSettingsModal);
  }

  const settingsOverlay = document.getElementById('settings-overlay');
  if (settingsOverlay && !window.settingsManager) {
    settingsOverlay.addEventListener('click', closeSettingsModal);
  }
});

// 添加滚动指示器功能
function initScrollIndicator() {
  const bookmarksContainer = document.querySelector('.bookmarks-container');
  const bookmarksList = document.getElementById('bookmarks-list');
  
  if (!bookmarksContainer || !bookmarksList) return;
  
  // 创建滚动指示器
  const scrollIndicator = document.createElement('div');
  scrollIndicator.className = 'scroll-indicator';
  scrollIndicator.innerHTML = `
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
      <polyline points="7 13 12 18 17 13"></polyline>
      <polyline points="7 6 12 11 17 6"></polyline>
    </svg>
  `;
  bookmarksContainer.appendChild(scrollIndicator);
  
  // 滚动状态变量
  let scrollTimeout;
  let isScrolling = false;
  
  // 检查是否需要滚动
  function checkScrollable() {
    const isScrollable = bookmarksList.scrollHeight > bookmarksList.clientHeight;
    
    if (isScrollable) {
      scrollIndicator.style.display = 'flex';
      // 添加动画类
      if (!scrollIndicator.classList.contains('animate')) {
        scrollIndicator.classList.add('animate');
        // 5秒后移除动画
        setTimeout(() => {
          scrollIndicator.classList.remove('animate');
        }, 5000);
      }
    } else {
      scrollIndicator.style.display = 'none';
    }
  }
  
  // 监听滚动事件
  bookmarksList.addEventListener('scroll', () => {
    // 如果已经滚动到底部，隐藏指示器
    const isAtBottom = bookmarksList.scrollHeight - bookmarksList.scrollTop <= bookmarksList.clientHeight + 10;
    if (isAtBottom) {
      scrollIndicator.style.opacity = '0';
    } else {
      scrollIndicator.style.opacity = '';
    }
    
    // 添加滚动中的类
    if (!isScrolling) {
      isScrolling = true;
      bookmarksList.classList.add('scrolling');
    }
    
    // 清除之前的定时器
    clearTimeout(scrollTimeout);
    
    // 设置新的定时器，滚动停止1.5秒后移除滚动中的类
    scrollTimeout = setTimeout(() => {
      isScrolling = false;
      bookmarksList.classList.remove('scrolling');
    }, 1500);
  });
  
  // 鼠标进入书签列表时，如果可滚动，添加滚动中的类
  bookmarksList.addEventListener('mouseenter', () => {
    if (bookmarksList.scrollHeight > bookmarksList.clientHeight) {
      bookmarksList.classList.add('scrolling');
      
      // 鼠标离开时，如果不在滚动，移除滚动中的类
      const handleMouseLeave = () => {
        if (!isScrolling) {
          bookmarksList.classList.remove('scrolling');
        }
        bookmarksList.removeEventListener('mouseleave', handleMouseLeave);
      };
      
      bookmarksList.addEventListener('mouseleave', handleMouseLeave);
    }
  });
  
  // 初始检查和窗口大小变化时重新检查
  checkScrollable();
  window.addEventListener('resize', _.debounce(checkScrollable, 200));
  
  // 当书签列表内容变化时重新检查
  const observer = new MutationObserver(_.debounce(checkScrollable, 200));
  observer.observe(bookmarksList, { childList: true, subtree: true });
  
  // 点击指示器滚动到下一屏
  scrollIndicator.addEventListener('click', () => {
    const currentScroll = bookmarksList.scrollTop;
    const nextScroll = currentScroll + bookmarksList.clientHeight * 0.8;
    bookmarksList.scrollTo({
      top: nextScroll,
      behavior: 'smooth'
    });
    
    // 点击时添加滚动中的类
    bookmarksList.classList.add('scrolling');
    isScrolling = true;
    
    // 清除之前的定时器
    clearTimeout(scrollTimeout);
    
    // 设置新的定时器
    scrollTimeout = setTimeout(() => {
      isScrolling = false;
      bookmarksList.classList.remove('scrolling');
    }, 1500);
  });

  // 监听触摸事件，支持触摸设备
  bookmarksList.addEventListener('touchstart', () => {
    bookmarksList.classList.add('scrolling');
    isScrolling = true;
    
    // 清除之前的定时器
    clearTimeout(scrollTimeout);
  });
  
  bookmarksList.addEventListener('touchend', () => {
    // 设置新的定时器，触摸结束后1.5秒移除滚动中的类
    clearTimeout(scrollTimeout);
    scrollTimeout = setTimeout(() => {
      isScrolling = false;
      bookmarksList.classList.remove('scrolling');
    }, 1500);
  });
  
  // 初始检查和窗口大小变化时重新检查
}

// 在DOMContentLoaded事件中调用
document.addEventListener('DOMContentLoaded', function() {
  // 初始化虚拟滚动
  initVirtualScroll();
  
  // 初始化滚动指示器
  initScrollIndicator();
  
  // 其他初始化代码...
  startPeriodicSync();
});



