<!-- ============================================
   从零开始学 Agent - 自定义 HTML Head
   ============================================ -->

<!-- 阅读进度条 -->
<style>
  #reading-progress {
    position: fixed;
    top: 0;
    left: 0;
    width: 0%;
    height: 3px;
    background: linear-gradient(90deg, #3783eb, #00d4ff);
    z-index: 10000;
    transition: width 0.1s ease-out;
    box-shadow: 0 0 8px rgba(55, 131, 235, 0.4);
  }
  
  /* 回到顶部按钮 */
  #back-to-top {
    position: fixed;
    bottom: 2rem;
    right: 2rem;
    width: 42px;
    height: 42px;
    border-radius: 50%;
    background: var(--links, #3783eb);
    color: #fff;
    border: none;
    cursor: pointer;
    font-size: 1.2rem;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    transform: translateY(20px);
    transition: opacity 0.3s ease, transform 0.3s ease, background 0.2s ease;
    z-index: 999;
    box-shadow: 0 2px 12px rgba(0,0,0,0.15);
  }
  #back-to-top.visible {
    opacity: 1;
    transform: translateY(0);
  }
  #back-to-top:hover {
    background: var(--links, #3783eb);
    filter: brightness(1.15);
    box-shadow: 0 4px 16px rgba(0,0,0,0.2);
  }

  /* 代码块语言标签 */
  .content pre {
    position: relative;
  }
  .code-lang-tag {
    position: absolute;
    top: 0;
    right: 0;
    padding: 2px 10px;
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: rgba(255,255,255,0.85);
    background: rgba(0,0,0,0.25);
    border-radius: 0 8px 0 6px;
    pointer-events: none;
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  }

  /* 信息提示框 (使用 blockquote + emoji 约定) */
  .content blockquote.admonition-tip {
    border-left-color: #10b981;
    background: rgba(16, 185, 129, 0.06);
  }
  .content blockquote.admonition-warning {
    border-left-color: #f59e0b;
    background: rgba(245, 158, 11, 0.06);
  }
  .content blockquote.admonition-danger {
    border-left-color: #ef4444;
    background: rgba(239, 68, 68, 0.06);
  }
  .content blockquote.admonition-info {
    border-left-color: #3b82f6;
    background: rgba(59, 130, 246, 0.06);
  }

  /* 暗色主题适配 */
  .navy #reading-progress,
  .coal #reading-progress,
  .ayu #reading-progress {
    background: linear-gradient(90deg, #5ba3f5, #00d4ff);
  }
  .navy .code-lang-tag,
  .coal .code-lang-tag,
  .ayu .code-lang-tag {
    background: rgba(255,255,255,0.12);
    color: rgba(255,255,255,0.7);
  }
  .navy .content blockquote.admonition-tip,
  .coal .content blockquote.admonition-tip,
  .ayu .content blockquote.admonition-tip {
    background: rgba(16, 185, 129, 0.08);
  }
  .navy .content blockquote.admonition-warning,
  .coal .content blockquote.admonition-warning,
  .ayu .content blockquote.admonition-warning {
    background: rgba(245, 158, 11, 0.08);
  }
  .navy .content blockquote.admonition-danger,
  .coal .content blockquote.admonition-danger,
  .ayu .content blockquote.admonition-danger {
    background: rgba(239, 68, 68, 0.08);
  }
  .navy .content blockquote.admonition-info,
  .coal .content blockquote.admonition-info,
  .ayu .content blockquote.admonition-info {
    background: rgba(59, 130, 246, 0.08);
  }

  /* 章节标题锚点链接 */
  .content h2:hover .header-anchor,
  .content h3:hover .header-anchor {
    opacity: 1;
  }
  .header-anchor {
    opacity: 0;
    transition: opacity 0.2s ease;
    margin-left: 0.3em;
    color: var(--links);
    text-decoration: none;
    font-size: 0.85em;
  }

  /* 估计阅读时间标签 */
  .reading-time {
    display: inline-block;
    margin-top: 0.5em;
    padding: 0.3em 0.8em;
    font-size: 0.85rem;
    color: #666;
    background: rgba(0,0,0,0.04);
    border-radius: 20px;
    font-weight: 500;
  }
  .navy .reading-time,
  .coal .reading-time,
  .ayu .reading-time {
    color: #aaa;
    background: rgba(255,255,255,0.06);
  }

  /* 语言切换按钮 */
  .lang-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0 8px;
    color: var(--icons);
    transition: color 0.3s ease;
    text-decoration: none;
  }
  .lang-toggle:hover {
    color: var(--icons-hover);
  }
</style>

<script>
document.addEventListener('DOMContentLoaded', function() {
  // === 1. 阅读进度条 ===
  var progressBar = document.createElement('div');
  progressBar.id = 'reading-progress';
  document.body.prepend(progressBar);

  function updateProgress() {
    var scrollTop = window.scrollY || document.documentElement.scrollTop;
    var docHeight = document.documentElement.scrollHeight - window.innerHeight;
    var progress = docHeight > 0 ? (scrollTop / docHeight) * 100 : 0;
    progressBar.style.width = Math.min(progress, 100) + '%';
  }

  // === 2. 回到顶部按钮 ===
  var backBtn = document.createElement('button');
  backBtn.id = 'back-to-top';
  backBtn.innerHTML = '&#8679;';
  backBtn.title = document.documentElement.lang === 'zh' || document.documentElement.lang === 'zh-CN' ? '回到顶部' : 'Back to top';
  document.body.appendChild(backBtn);

  function toggleBackToTop() {
    var scrollTop = window.scrollY || document.documentElement.scrollTop;
    if (scrollTop > 400) {
      backBtn.classList.add('visible');
    } else {
      backBtn.classList.remove('visible');
    }
  }

  backBtn.addEventListener('click', function() {
    window.scrollTo({ top: 0, behavior: 'smooth' });
  });

  // 合并 scroll 事件
  var scrollTicking = false;
  window.addEventListener('scroll', function() {
    if (!scrollTicking) {
      window.requestAnimationFrame(function() {
        updateProgress();
        toggleBackToTop();
        scrollTicking = false;
      });
      scrollTicking = true;
    }
  });

  // 初始化
  updateProgress();
  toggleBackToTop();

  // === 3. 代码块语言标签 ===
  var codeBlocks = document.querySelectorAll('.content pre code');
  codeBlocks.forEach(function(code) {
    var classes = code.className.split(/\s+/);
    var lang = '';
    classes.forEach(function(cls) {
      if (cls.startsWith('language-')) {
        lang = cls.replace('language-', '');
      }
    });
    if (lang && lang !== 'text' && lang !== 'plaintext') {
      var langMap = {
        'python': 'Python', 'py': 'Python',
        'javascript': 'JS', 'js': 'JS',
        'typescript': 'TS', 'ts': 'TS',
        'bash': 'Bash', 'sh': 'Shell', 'shell': 'Shell', 'zsh': 'Shell',
        'json': 'JSON', 'yaml': 'YAML', 'yml': 'YAML',
        'toml': 'TOML', 'sql': 'SQL',
        'html': 'HTML', 'css': 'CSS',
        'rust': 'Rust', 'go': 'Go', 'java': 'Java',
        'dockerfile': 'Docker', 'docker': 'Docker',
        'markdown': 'MD', 'md': 'MD',
        'xml': 'XML', 'graphql': 'GraphQL',
        'mermaid': 'Mermaid'
      };
      var displayLang = langMap[lang.toLowerCase()] || lang.toUpperCase();
      var tag = document.createElement('span');
      tag.className = 'code-lang-tag';
      tag.textContent = displayLang;
      code.parentElement.appendChild(tag);
    }
  });

  // === 4. 信息提示框自动分类 ===
  var blockquotes = document.querySelectorAll('.content blockquote');
  blockquotes.forEach(function(bq) {
    var firstP = bq.querySelector('p');
    if (!firstP) return;
    var text = firstP.textContent || '';
    if (text.match(/^[\s]*[💡🔑✨]/)) {
      bq.classList.add('admonition-tip');
    } else if (text.match(/^[\s]*[⚠️🔶]/)) {
      bq.classList.add('admonition-warning');
    } else if (text.match(/^[\s]*[🚨❌⛔]/)) {
      bq.classList.add('admonition-danger');
    } else if (text.match(/^[\s]*[📖ℹ️📝📌🔗]/)) {
      bq.classList.add('admonition-info');
    }
  });

  // === 5. 估计阅读时间 ===
  var content = document.querySelector('.content');
  if (content) {
    var text = content.textContent || '';
    var charCount = text.replace(/\s/g, '').length;
    var isZh = document.documentElement.lang === 'zh' || document.documentElement.lang === 'zh-CN';
    // 中文约 500 字/分钟，英文约 200 词/分钟（词数 ≈ 字符数 / 5）
    var readingMinutes = isZh
      ? Math.max(1, Math.ceil(charCount / 500))
      : Math.max(1, Math.ceil(charCount / 1000));
    var h1 = content.querySelector('h1');
    if (h1 && readingMinutes > 2) {
      var timeTag = document.createElement('span');
      timeTag.className = 'reading-time';
      timeTag.textContent = isZh
        ? '预计阅读 ' + readingMinutes + ' 分钟'
        : 'Est. ' + readingMinutes + ' min read';
      h1.insertAdjacentElement('afterend', timeTag);
    }
  }

  // === 6. 右侧页内目录（TOC）===
  (function buildTOC() {
    var content = document.querySelector('.content main') || document.querySelector('.content');
    if (!content) return;

    // 收集 h2 / h3 标题
    var headings = content.querySelectorAll('h2, h3');
    if (headings.length < 2) return; // 标题太少不显示

    // 创建 TOC 容器
    var toc = document.createElement('nav');
    toc.id = 'page-toc';
    toc.setAttribute('aria-label', '页内目录');

    var isZhPage = document.documentElement.lang === 'zh' || document.documentElement.lang === 'zh-CN';

    // 标题行（包含折叠按钮）
    var titleEl = document.createElement('div');
    titleEl.className = 'toc-title';
    var titleText = isZhPage ? '本节目录' : 'On This Page';
    titleEl.innerHTML =
      '<span class="toc-title-text"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><line x1="3" y1="6" x2="21" y2="6"/><line x1="3" y1="12" x2="15" y2="12"/><line x1="3" y1="18" x2="18" y2="18"/></svg>' + titleText + '</span>' +
      '<button class="toc-collapse-btn" type="button" aria-label="' + (isZhPage ? '收起目录' : 'Collapse TOC') + '" title="' + (isZhPage ? '收起目录' : 'Collapse TOC') + '">' +
      '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="13 17 18 12 13 7"/><polyline points="6 17 11 12 6 7"/></svg>' +
      '</button>';
    toc.appendChild(titleEl);

    // 折叠态的打开按钮（悬浮在右上角）
    var openBtn = document.createElement('button');
    openBtn.id = 'page-toc-open';
    openBtn.type = 'button';
    openBtn.setAttribute('aria-label', isZhPage ? '展开目录' : 'Open TOC');
    openBtn.title = isZhPage ? '展开目录' : 'Open TOC';
    openBtn.innerHTML = '<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><line x1="3" y1="6" x2="21" y2="6"/><line x1="3" y1="12" x2="15" y2="12"/><line x1="3" y1="18" x2="18" y2="18"/></svg>';

    var ul = document.createElement('ul');

    headings.forEach(function(h) {
      // 确保标题有 id（mdBook 通常会自动生成）
      if (!h.id) return;
      var li = document.createElement('li');
      var a = document.createElement('a');
      a.href = '#' + h.id;
      a.textContent = h.textContent.replace(/\s*#\s*$/, '').trim(); // 去掉末尾的锚点符号
      a.className = h.tagName === 'H2' ? 'toc-h2' : 'toc-h3';
      a.dataset.target = h.id;

      a.addEventListener('click', function(e) {
        e.preventDefault();
        var target = document.getElementById(this.dataset.target);
        if (target) {
          target.scrollIntoView({ behavior: 'smooth', block: 'start' });
        }
      });

      li.appendChild(a);
      ul.appendChild(li);
    });

    toc.appendChild(ul);
    document.body.appendChild(toc);
    document.body.appendChild(openBtn);

    // === 折叠/展开逻辑 ===
    var TOC_COLLAPSED_KEY = 'page-toc-collapsed';
    function applyCollapsed(collapsed) {
      if (collapsed) {
        toc.classList.add('toc-collapsed');
        openBtn.classList.add('toc-open-visible');
        document.body.classList.add('page-toc-collapsed');
      } else {
        toc.classList.remove('toc-collapsed');
        openBtn.classList.remove('toc-open-visible');
        document.body.classList.remove('page-toc-collapsed');
      }
    }
    // 读取持久化状态
    var savedCollapsed = false;
    try { savedCollapsed = localStorage.getItem(TOC_COLLAPSED_KEY) === '1'; } catch (e) {}
    applyCollapsed(savedCollapsed);

    var collapseBtn = titleEl.querySelector('.toc-collapse-btn');
    if (collapseBtn) {
      collapseBtn.addEventListener('click', function() {
        applyCollapsed(true);
        try { localStorage.setItem(TOC_COLLAPSED_KEY, '1'); } catch (e) {}
      });
    }
    openBtn.addEventListener('click', function() {
      applyCollapsed(false);
      try { localStorage.setItem(TOC_COLLAPSED_KEY, '0'); } catch (e) {}
    });

    // 延迟显示（等页面渲染完）
    requestAnimationFrame(function() {
      toc.classList.add('toc-visible');
    });

    // 高亮当前可见标题（IntersectionObserver）
    var tocLinks = toc.querySelectorAll('a[data-target]');
    var activeId = null;

    function setActive(id) {
      if (id === activeId) return;
      activeId = id;
      tocLinks.forEach(function(a) {
        if (a.dataset.target === id) {
          a.classList.add('toc-active');
        } else {
          a.classList.remove('toc-active');
        }
      });
    }

    if ('IntersectionObserver' in window) {
      var observer = new IntersectionObserver(function(entries) {
        // 找到最靠近顶部且可见的标题
        var visible = [];
        entries.forEach(function(entry) {
          if (entry.isIntersecting) visible.push(entry.target.id);
        });
        if (visible.length > 0) setActive(visible[0]);
      }, {
        rootMargin: '-60px 0px -70% 0px',
        threshold: 0
      });

      headings.forEach(function(h) {
        if (h.id) observer.observe(h);
      });
    } else {
      // 降级：scroll 事件
      window.addEventListener('scroll', function() {
        var scrollTop = window.scrollY + 80;
        var current = null;
        headings.forEach(function(h) {
          if (h.id && h.offsetTop <= scrollTop) current = h.id;
        });
        if (current) setActive(current);
      }, { passive: true });
    }
  })();

  // === 7. 左侧书籍目录折叠 ===
  (function initSidebarCollapse() {
    var scrollbox = document.querySelector('#sidebar mdbook-sidebar-scrollbox, #sidebar .sidebar-scrollbox');
    if (!scrollbox) return;

    var isZhPage = document.documentElement.lang === 'zh' || document.documentElement.lang === 'zh-CN';
    var STORAGE_KEY = 'sidebar-collapsed-items';
    var collapsedItems = {};

    try {
      collapsedItems = JSON.parse(localStorage.getItem(STORAGE_KEY) || '{}');
    } catch (e) {
      collapsedItems = {};
    }

    function saveCollapsedItems() {
      try {
        localStorage.setItem(STORAGE_KEY, JSON.stringify(collapsedItems));
      } catch (e) {}
    }

    function getItemKey(li, index) {
      var link = li.querySelector(':scope > a');
      if (link && link.getAttribute('href')) {
        return link.getAttribute('href');
      }
      return 'sidebar-item-' + index;
    }

    function getSectionWrapper(li) {
      var next = li.nextElementSibling;
      if (next && next.querySelector(':scope > ol.section, :scope > ul.section')) {
        return next;
      }
      if (li.querySelector(':scope > ol.section, :scope > ul.section')) {
        return li;
      }
      return null;
    }

    function getSectionList(wrapper) {
      return wrapper ? wrapper.querySelector(':scope > ol.section, :scope > ul.section') : null;
    }

    function setCollapsed(li, wrapper, collapsed, key, shouldSave) {
      li.classList.toggle('sidebar-item-collapsed', collapsed);
      wrapper.classList.toggle('sidebar-section-collapsed', collapsed);
      var button = li.querySelector(':scope > .sidebar-collapse-toggle');
      if (button) {
        button.setAttribute('aria-expanded', collapsed ? 'false' : 'true');
        button.title = collapsed
          ? (isZhPage ? '展开目录' : 'Expand section')
          : (isZhPage ? '收起目录' : 'Collapse section');
        button.setAttribute('aria-label', button.title);
      }
      if (shouldSave) {
        collapsedItems[key] = collapsed;
        saveCollapsedItems();
      }
    }

    function enhanceSidebar() {
      var chapter = scrollbox.querySelector('ol.chapter');
      if (!chapter || chapter.dataset.collapseReady === '1') return !!chapter;

      var chapterItems = chapter.querySelectorAll('li.chapter-item');
      var collapsibleItems = [];
      chapterItems.forEach(function(li) {
        var wrapper = getSectionWrapper(li);
        if (wrapper && getSectionList(wrapper)) {
          collapsibleItems.push(li);
        }
      });

      collapsibleItems.forEach(function(li, index) {
        var wrapper = getSectionWrapper(li);
        var section = getSectionList(wrapper);
        var link = li.querySelector(':scope > a');
        if (!wrapper || !section || !link || li.querySelector(':scope > .sidebar-collapse-toggle')) return;

        var key = getItemKey(li, index);
        li.classList.add('sidebar-collapsible');
        wrapper.classList.add('sidebar-section-wrapper');

        var toggle = document.createElement('button');
        toggle.type = 'button';
        toggle.className = 'sidebar-collapse-toggle';
        toggle.innerHTML = '<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"></polyline></svg>';
        link.insertAdjacentElement('beforebegin', toggle);

        var isActiveChapter = link.classList.contains('active') || li.classList.contains('active');
        var hasActiveChild = !!section.querySelector('li.active, a.active');
        var hasSavedState = Object.prototype.hasOwnProperty.call(collapsedItems, key);
        var shouldCollapse = hasSavedState ? collapsedItems[key] : !(isActiveChapter || hasActiveChild);
        setCollapsed(li, wrapper, shouldCollapse, key, false);

        toggle.addEventListener('click', function(e) {
          e.preventDefault();
          e.stopPropagation();
          setCollapsed(li, wrapper, !li.classList.contains('sidebar-item-collapsed'), key, true);
        });
      });

      chapter.dataset.collapseReady = '1';
      return true;
    }

    if (enhanceSidebar()) return;

    var observer = new MutationObserver(function() {
      if (enhanceSidebar()) observer.disconnect();
    });
    observer.observe(scrollbox, { childList: true, subtree: true });
  })();

  // === 8. 中英文切换按钮 ===
  // 通过替换 URL 路径中的语言段（/zh/ ↔ /en/）实现切换，
  // 本地开发（serve.sh）和部署环境（GitHub Pages）使用完全相同的逻辑。
  var rightButtons = document.querySelector('.right-buttons');
  if (rightButtons) {
    var langToggle = document.createElement('a');
    langToggle.className = 'lang-toggle';
    langToggle.title = 'Switch Language / 切换语言';
    langToggle.setAttribute('aria-label', 'Switch Language');
    langToggle.style.cursor = 'pointer';

    var currentLang = document.documentElement.lang;
    var isZh = currentLang.startsWith('zh');

    langToggle.innerHTML = '<i class="fa fa-language"></i> <span class="lang-text" style="font-size: 0.85em; font-weight: bold; margin-left: 2px;">' + (isZh ? 'EN' : '中') + '</span>';

    /**
     * 根据当前路径计算目标语言路径。
     * 将路径中的语言段 /zh/ 或 /en/ 替换为目标语言段。
     */
    function calcTargetPath(pathname, toZh) {
      var from = toZh ? 'en' : 'zh';
      var to   = toZh ? 'zh' : 'en';
      var re = new RegExp('((?:^|/)' + from + '(?=/|$))');
      if (re.test(pathname)) {
        return pathname.replace(re, function(m) {
          return m.replace(from, to);
        });
      }
      return null;
    }

    /**
     * 获取目标语言的首页路径（用于目标页面不存在时的回退）。
     */
    function getFallbackRoot(pathname, toZh) {
      var from = toZh ? 'en' : 'zh';
      var to   = toZh ? 'zh' : 'en';
      var re = new RegExp('((?:^|/)' + from + ')(?=/|$).*');
      if (re.test(pathname)) {
        return pathname.replace(re, function(m, p1) {
          return p1.replace(from, to) + '/';
        });
      }
      return toZh ? '../zh/' : '../en/';
    }

    langToggle.addEventListener('click', function(e) {
      e.preventDefault();
      var currentPath = window.location.pathname;
      var toZh = !isZh;

      var targetPath = calcTargetPath(currentPath, toZh);
      var fallbackPath = getFallbackRoot(currentPath, toZh);

      if (!targetPath || targetPath === currentPath) {
        window.location.href = fallbackPath;
        return;
      }

      // 用 fetch HEAD 请求预检目标页面是否存在，404 则回退到目标语言首页
      fetch(targetPath, { method: 'HEAD' })
        .then(function(res) {
          window.location.href = res.ok ? targetPath : fallbackPath;
        })
        .catch(function() {
          // 网络错误时直接跳转（如本地服务不支持 HEAD 请求）
          window.location.href = targetPath;
        });
    });

    rightButtons.insertBefore(langToggle, rightButtons.firstChild);
  }
});
</script>
