---
import GoogleAnalytics from "@components/analytics/GoogleAnalytics.astro";
import MicrosoftClarity from "@components/analytics/MicrosoftClarity.astro";
import FancyboxManager from "@components/effects/FancyboxManager.astro";
import KatexManager from "@components/effects/KatexManager.astro";
import SakuraEffect from "@components/effects/SakuraEffect.astro";
import FontManager from "@components/interactive/FontManager.astro";
import ConfigCarrier from "@components/layout/ConfigCarrier.astro";
import MusicPlayer from "@components/widget/MusicPlayer.astro";

import {
	backgroundWallpaper,
	expressiveCodeConfig,
	profileConfig,
	siteConfig,
} from "@/config";
import {
	BANNER_HEIGHT,
	BANNER_HEIGHT_EXTEND,
	BANNER_HEIGHT_HOME,
	PAGE_WIDTH,
} from "@/constants/constants";
import { defaultFavicons } from "@/constants/icon";
import type { Favicon } from "@/types/config";
import { getDefaultBackground, isHomePage } from "@/utils/layout-utils";
import { url } from "@/utils/url-utils";

import "@/styles/navbar.css";
import "@/styles/layout-styles.css";
import "@/styles/waves.css";

interface Props {
	title?: string;
	banner?: string;
	description?: string;
	lang?: string;
	setOGTypeArticle?: boolean;
	postSlug?: string;
}

let { title, banner, description, lang, setOGTypeArticle, postSlug } =
	Astro.props;

// apply a class to the body element to decide the height of the banner, only used for initial page load
// Swup can update the body for each page visit, but it's after the page transition, causing a delay for banner height change
// so use Swup hooks instead to change the height immediately when a link is clicked
const isHomePageCheck = isHomePage(Astro.url.pathname);

// defines global css variables
// why doing this in Layout instead of GlobalStyles: https://github.com/withastro/astro/issues/6728#issuecomment-1502203757
const configHue = siteConfig.themeColor.hue;

// 获取导航栏透明模式配置
const navbarTransparentMode =
	backgroundWallpaper.banner?.navbar?.transparentMode || "semi";
// 判断是否应该显示顶部高光效果（只在full和semifull模式下显示）
const shouldShowTopHighlight =
	navbarTransparentMode === "full" || navbarTransparentMode === "semifull";

if (!banner || typeof banner !== "string" || banner.trim() === "") {
	banner = getDefaultBackground();
}

// TODO don't use post cover as banner for now
banner = getDefaultBackground();

const enableBanner = backgroundWallpaper.mode === "banner";

let pageTitle: string;
if (title) {
	pageTitle = `${title} - ${siteConfig.title}`;
} else {
	pageTitle = siteConfig.subtitle
		? `${siteConfig.title} - ${siteConfig.subtitle}`
		: siteConfig.title;
}

let ogImageUrl: string | undefined;
if (siteConfig.generateOgImages && postSlug) {
	ogImageUrl = new URL(`/og/${postSlug}.png`, Astro.site).toString();
}

const favicons: Favicon[] =
	siteConfig.favicon.length > 0 ? siteConfig.favicon : defaultFavicons;

// const siteLang = siteConfig.lang.replace('_', '-')
if (!lang) {
	lang = `${siteConfig.lang}`;
}
const siteLang = lang.replace("_", "-");

// 使用固定的banner偏移量，position配置用于图片定位
const bannerOffset = `${BANNER_HEIGHT_EXTEND / 2}vh`;
---

<!doctype html>
<html lang={siteLang} class="bg-[var(--page-bg)] text-[14px] md:text-[16px]">
  <head>
      {siteConfig.analytics?.googleAnalyticsId && (
              <GoogleAnalytics analyticsId={siteConfig.analytics.googleAnalyticsId} />
      )}
      {siteConfig.analytics?.microsoftClarityId && (
              <MicrosoftClarity clarityId={siteConfig.analytics.microsoftClarityId} />
      )}

    <title>{pageTitle}</title>

    <meta charset="UTF-8" />
    <meta
      name="description"
      content={description || siteConfig.description || pageTitle}
    />
    {
      siteConfig.keywords && siteConfig.keywords.length > 0 && (
        <meta name="keywords" content={siteConfig.keywords.join(", ")} />
      )
    }
    <meta name="author" content={profileConfig.name} />

    <meta property="og:site_name" content={siteConfig.title} />
    <meta property="og:url" content={Astro.url} />
    <meta property="og:title" content={pageTitle} />
    <meta
      property="og:description"
      content={description || siteConfig.description || pageTitle}
    />
    {ogImageUrl && <meta property="og:image" content={ogImageUrl} />}
    {
      setOGTypeArticle ? (
        <meta property="og:type" content="article" />
      ) : (
        <meta property="og:type" content="website" />
      )
    }

    <meta name="twitter:card" content="summary_large_image" />
    <meta property="twitter:url" content={Astro.url} />
    <meta name="twitter:title" content={pageTitle} />
    <meta
      name="twitter:description"
      content={description || siteConfig.description || pageTitle}
    />

    <meta name="viewport" content="width=device-width" />
    <meta name="generator" content={Astro.generator} />
    {
      favicons.map((favicon) => (
        <link
          rel="icon"
          href={favicon.src.startsWith("/") ? url(favicon.src) : favicon.src}
          sizes={favicon.sizes}
          media={favicon.theme && `(prefers-color-scheme: ${favicon.theme})`}
        />
      ))
    }

    <!-- Set the theme before the page is rendered to avoid a flash -->
    <script
      is:inline
      define:vars={{
        BANNER_HEIGHT_EXTEND,
        PAGE_WIDTH,
        configHue,
        defaultMode: siteConfig.themeColor.defaultMode ?? "light",
        defaultWallpaperMode: backgroundWallpaper.mode,
        isWallpaperSwitchable:
          backgroundWallpaper.switchable ?? true,
        darkTheme: expressiveCodeConfig.darkTheme,
        lightTheme: expressiveCodeConfig.lightTheme,
        baseUrl: import.meta.env.BASE_URL,
      }}
    >
      // 主题初始化 - 与setting-utils.ts保持一致
      const LIGHT_MODE = "light";
      const DARK_MODE = "dark";
      const SYSTEM_MODE = "system";

      // 获取存储的主题，如果没有则使用默认值
      const theme = localStorage.getItem("theme") || defaultMode;

      // 获取系统主题
      function getSystemTheme() {
        return window.matchMedia("(prefers-color-scheme: dark)").matches
          ? DARK_MODE
          : LIGHT_MODE;
      }

      // 解析主题（如果是system模式，则获取系统主题）
      function resolveTheme(themeValue) {
        if (themeValue === SYSTEM_MODE) {
          return getSystemTheme();
        }
        return themeValue;
      }

      const resolvedTheme = resolveTheme(theme);
      const isDark = resolvedTheme === DARK_MODE;

      // 应用主题
      if (isDark) {
        document.documentElement.classList.add("dark");
      } else {
        document.documentElement.classList.remove("dark");
      }

      // Set the theme for Expressive Code
      document.documentElement.setAttribute(
        "data-theme",
        isDark ? darkTheme : lightTheme
      );

      // Load the hue from local storage
      const hue = localStorage.getItem("hue") || configHue;
      document.documentElement.style.setProperty("--hue", hue);

      // calculate the --banner-height-extend, which needs to be a multiple of 4 to avoid blurry text
      // 使用更准确的窗口高度计算
      function calculateBannerHeightExtend() {
        let offset = Math.floor(
          window.innerHeight * (BANNER_HEIGHT_EXTEND / 100)
        );
        offset = offset - (offset % 4);
        document.documentElement.style.setProperty(
          "--banner-height-extend",
          `${offset}px`
        );
      }

      // 立即设置初始值
      calculateBannerHeightExtend();

      // 在下一帧重新计算精确值（仅在值变化时更新，避免闪烁）
      requestAnimationFrame(() => {
        const oldValue = parseInt(
          document.documentElement.style.getPropertyValue(
            "--banner-height-extend"
          )
        );
        calculateBannerHeightExtend();
        const newValue = parseInt(
          document.documentElement.style.getPropertyValue(
            "--banner-height-extend"
          )
        );
        // 如果值变化了，再更新一次确保准确
        if (Math.abs(oldValue - newValue) > 4) {
          // 如果有明显变化，延迟一帧再更新，避免闪烁
          requestAnimationFrame(calculateBannerHeightExtend);
        }
      });

      // 初始化壁纸模式 - 在页面渲染前应用
      const WALLPAPER_BANNER = "banner";
      const WALLPAPER_OVERLAY = "overlay";
      const WALLPAPER_NONE = "none";
      const wallpaperMode = isWallpaperSwitchable
        ? localStorage.getItem("wallpaperMode") || defaultWallpaperMode
        : defaultWallpaperMode;

      // 设置data-wallpaper-mode属性
      document.documentElement.setAttribute(
        "data-wallpaper-mode",
        wallpaperMode
      );

      // 立即执行函数来处理DOM
      (function applyWallpaperMode() {
        // 使用 requestAnimationFrame 确保在下一帧之前执行
        requestAnimationFrame(function () {
          // 根据模式隐藏显示对应元素
          if (
            wallpaperMode === WALLPAPER_NONE ||
            wallpaperMode === WALLPAPER_OVERLAY
          ) {
            // 隐藏横幅
            if (document.body) {
              document.body.classList.remove("enable-banner");
              document.body.classList.add("no-banner-layout");
            }
          } else {
            if (document.body) {
              document.body.classList.add("enable-banner");
              document.body.classList.remove("no-banner-layout");
            }
          }

          // 全屏壁纸模式
          if (wallpaperMode === WALLPAPER_OVERLAY) {
            if (document.body) {
              document.body.classList.add("wallpaper-transparent");
            }
          } else {
            if (document.body) {
              document.body.classList.remove("wallpaper-transparent");
            }
          }

          // 处理banner和overlay wallpaper的显示
          const bannerWrapper = document.getElementById("banner-wrapper");
          const overlayWallpaper = document.querySelector(
            "[data-overlay-wallpaper]"
          );

          // 检查当前是否为首页
          const isHomePage =
            window.location.pathname === baseUrl || 
            (baseUrl !== '/' && window.location.pathname === baseUrl.replace(/\/$/, '')) ||
            window.location.pathname === "/";

          if (wallpaperMode === WALLPAPER_OVERLAY) {
            // 全屏壁纸透明模式：显示全屏壁纸，隐藏banner
            if (bannerWrapper) {
              bannerWrapper.style.display = "none";
            }
            if (overlayWallpaper) {
              overlayWallpaper.style.display = "block";
              overlayWallpaper.classList.remove("hidden", "opacity-0");
              overlayWallpaper.classList.add("opacity-100");
            }
          } else if (wallpaperMode === WALLPAPER_NONE) {
            // 纯色背景：隐藏所有壁纸
            if (bannerWrapper) {
              bannerWrapper.style.display = "none";
            }
            if (overlayWallpaper) {
              overlayWallpaper.style.display = "none";
              overlayWallpaper.classList.add("hidden", "opacity-0");
            }
          } else {
            // banner模式：显示banner，隐藏全屏壁纸
            if (bannerWrapper) {
              const isMobile = window.innerWidth < 1024;
              // 移动端非首页时隐藏banner（初始状态直接隐藏，不需要动画）
              // 桌面端始终显示banner
              if (isMobile && !isHomePage) {
                bannerWrapper.style.display = "none";
                bannerWrapper.classList.add("mobile-hide-banner");
              } else {
                bannerWrapper.style.display = "block";
                bannerWrapper.classList.remove("mobile-hide-banner");
              }
            }
            if (overlayWallpaper) {
              overlayWallpaper.style.display = "none";
              overlayWallpaper.classList.add("hidden", "opacity-0");
            }
          }

          // 处理主内容区域位置
          const mainContentWrapper = document.querySelector(
            ".absolute.w-full.z-30"
          );
          if (mainContentWrapper) {
            const isMobile = window.innerWidth < 1024;
            // 只在移动端非首页时调整主内容位置
            if (isMobile && !isHomePage) {
              mainContentWrapper.classList.add("mobile-main-no-banner");
            } else {
              mainContentWrapper.classList.remove("mobile-main-no-banner");
            }
          }

          // 处理credit元素
          const creditDesktop = document.getElementById(
            "banner-credit-desktop"
          );
          const creditMobile = document.getElementById("banner-credit-mobile");
          if (
            wallpaperMode === WALLPAPER_OVERLAY ||
            wallpaperMode === WALLPAPER_NONE
          ) {
            if (creditDesktop) creditDesktop.style.display = "none";
            if (creditMobile) creditMobile.style.display = "none";
          } else {
            if (creditDesktop) creditDesktop.style.display = "";
            if (creditMobile) creditMobile.style.display = "";
          }

          // 处理banner homeText元素
          const bannerTextOverlay = document.querySelector(
            ".banner-text-overlay"
          );
          if (bannerTextOverlay) {
            const isHomePage =
              window.location.pathname === baseUrl || 
              (baseUrl !== '/' && window.location.pathname === baseUrl.replace(/\/$/, '')) ||
              window.location.pathname === "/";
            if (wallpaperMode === WALLPAPER_BANNER && isHomePage) {
              bannerTextOverlay.classList.remove("hidden");
            } else {
              bannerTextOverlay.classList.add("hidden");
            }
          }
        });
      })();
    </script>
    <style
      define:vars={{
        configHue,
        "page-width": `${PAGE_WIDTH}rem`,
      }}
    ></style>
    <!-- defines global css variables. This will be applied to <html> <body> and some other elements idk why -->

    <slot name="head" />

    <link
      rel="alternate"
      type="application/rss+xml"
      title={profileConfig.name}
      href={`${Astro.site}rss.xml`}
    />

    <!-- Font Manager -->
    <FontManager />
  </head>
  <body
    class="min-h-screen"
    class:list={[
      { "lg:is-home": isHomePageCheck, "enable-banner": enableBanner },
      ...(siteConfig.font.enable && siteConfig.font.selected
        ? (Array.isArray(siteConfig.font.selected)
            ? siteConfig.font.selected
            : [siteConfig.font.selected]
          ).map((fontId) => `font-${fontId}-enabled`)
        : []),
    ]}
  >

    <!-- 页面顶部渐变高光效果 - 只在full和semifull模式下显示 -->
    {shouldShowTopHighlight && <div class="top-gradient-highlight" />}
    <ConfigCarrier />
    <slot />

    <!-- Music Player -->
    <MusicPlayer />

    <!-- increase the page height during page transition to prevent the scrolling animation from jumping -->
    <div id="page-height-extend" class="hidden h-[300vh]"></div>

    <!-- Sakura Effect -->
    <SakuraEffect />

    <!-- Fancybox Manager -->
    <FancyboxManager />
    
    <!-- KaTeX Manager -->
    <KatexManager />
  </body>
</html>

<style
  is:global
  define:vars={{
    bannerOffset,
    "banner-height-home": `${BANNER_HEIGHT_HOME}vh`,
    "banner-height": `${BANNER_HEIGHT}vh`,
  }}
>
  @tailwind components;
  @layer components {
    .enable-banner.is-home #banner-wrapper {
      @apply h-[var(--banner-height-home)] translate-y-[var(--banner-height-extend)];
    }
    .enable-banner #banner-wrapper {
      @apply h-[var(--banner-height-home)];
    }

    .enable-banner.is-home #banner {
      @apply h-[var(--banner-height-home)] translate-y-0;
    }
    .enable-banner #banner {
      @apply h-[var(--banner-height-home)] translate-y-[var(--bannerOffset)];
    }
    .enable-banner.is-home #main-grid {
      @apply translate-y-[var(--banner-height-extend)];
    }
    .enable-banner #top-row {
      @apply h-[calc(var(--banner-height-home)_-_4.5rem)] transition-all duration-300;
    }
    .enable-banner.is-home #sidebar-sticky {
      @apply top-[calc(1rem_-_var(--banner-height-extend))];
    }
    .enable-banner.is-home #left-sidebar-sticky {
      @apply top-[calc(1rem_-_var(--banner-height-extend))];
    }
    .enable-banner.is-home #right-sidebar-sticky {
      @apply top-[calc(1rem_-_var(--banner-height-extend))];
    }
    .navbar-hidden {
      @apply opacity-0 -translate-y-16;
    }
  }
</style>

<script>
  import { pathsEqual, url } from "@/utils/url-utils";
  import {
    BANNER_HEIGHT,
    BANNER_HEIGHT_HOME,
    BANNER_HEIGHT_EXTEND,
    // MAIN_PANEL_OVERLAPS_BANNER_HEIGHT,
  } from "@/constants/constants";
  import { backgroundWallpaper, expressiveCodeConfig, siteConfig } from "@/config";

  /* Preload fonts */
  // (async function() {
  // 	try {
  // 		await Promise.all([
  // 			document.fonts.load("400 1em Roboto"),
  // 			document.fonts.load("700 1em Roboto"),
  // 		]);
  // 		document.body.classList.remove("hidden");
  // 	} catch (error) {
  // 		console.log("Failed to load fonts:", error);
  // 	}
  // })();

  /* TODO This is a temporary solution for style flicker issue when the transition is activated */
  /* issue link: https://github.com/withastro/astro/issues/8711, the solution get from here too */
  /* update: fixed in Astro 3.2.4 */
  /*
function disableAnimation() {
	const css = document.createElement('style')
	css.appendChild(
		document.createTextNode(
			`*{
              -webkit-transition:none!important;
              -moz-transition:none!important;
              -o-transition:none!important;
              -ms-transition:none!important;
              transition:none!important
              }`
		)
	)
	document.head.appendChild(css)

	return () => {
		// Force restyle
		;(() => window.getComputedStyle(document.body))()

		// Wait for next tick before removing
		setTimeout(() => {
			document.head.removeChild(css)
		}, 1)
	}
}
*/

  const bannerEnabled = !!document.getElementById("banner-wrapper");

  function setClickOutsideToClose(panel: string, ignores: string[]) {
      document.addEventListener("click", (event) => {
          let panelDom = document.getElementById(panel);
          if (!panelDom) return;
          let tDom = event.target;
          if (!(tDom instanceof Node)) return; // Ensure the event target is an HTML Node
          for (let ig of ignores) {
              let ie = document.getElementById(ig);
              if (ie == tDom || ie?.contains(tDom)) {
                  return;
              }
          }
          panelDom.classList.add("float-panel-closed");
      });
  }
  setClickOutsideToClose("display-setting", [
    "display-setting",
    "display-settings-switch",
  ]);
  setClickOutsideToClose("nav-menu-panel", [
    "nav-menu-panel",
    "nav-menu-switch",
  ]);
  setClickOutsideToClose("search-panel", [
    "search-panel",
    "search-bar",
    "search-switch",
  ]);
  setClickOutsideToClose("wallpaper-mode-panel", [
    "wallpaper-mode-panel",
    "wallpaper-mode-switch",
  ]);
  setClickOutsideToClose("theme-mode-panel", [
    "theme-mode-panel",
    "scheme-switch",
  ]);

  function initCustomScrollbar() {
    // 只处理katex元素的滚动条，使用浏览器原生滚动条
    const katexElements = document.querySelectorAll(
      ".katex-display:not([data-scrollbar-initialized])"
    ) as NodeListOf<HTMLElement>;
    katexElements.forEach((element) => {
      if (!element.parentNode) return;

      const container = document.createElement("div");
      container.className = "katex-display-container";
      element.parentNode.insertBefore(container, element);
      container.appendChild(element);

      // 使用浏览器原生滚动条，无自定义样式
      container.style.cssText = `
			overflow-x: auto;
		`;

      element.setAttribute("data-scrollbar-initialized", "true");
    });
  }

  function showBanner() {
    const isBannerMode = backgroundWallpaper.mode === "banner";
    if (!isBannerMode) return;

    // 使用requestAnimationFrame优化DOM操作
    requestAnimationFrame(() => {
      // Handle single image banner (desktop)
      const banner = document.getElementById("banner");
      if (banner) {
        banner.classList.remove("opacity-0", "scale-105");
      }

      // Handle mobile single image banner - 使用与电脑端相同的逻辑
      const mobileBanner = document.querySelector(
        '.block.lg\\:hidden[alt="Mobile banner image of the blog"]'
      );
      if (mobileBanner) {
        // 移动端使用与电脑端相同的初始化逻辑
        mobileBanner.classList.remove("opacity-0", "scale-105");
        mobileBanner.classList.add("opacity-100");
      }
    });
  }

  const setup = () => {
    // TODO: temp solution to change the height of the banner
    /*
	window.swup.hooks.on('animation:out:start', () => {
		const path = window.location.pathname
		const body = document.querySelector('body')
		if (path[path.length - 1] === '/' && !body.classList.contains('is-home')) {
			body.classList.add('is-home')
		} else if (path[path.length - 1] !== '/' && body.classList.contains('is-home')) {
			body.classList.remove('is-home')
		}
	})
*/
    window.swup.hooks.on("link:click", () => {
      // Remove the delay for the first time page load
      document.documentElement.style.setProperty("--content-delay", "0ms");

      // 添加页面切换保护，防止导航栏闪烁
      document.documentElement.classList.add("is-page-transitioning");

      // 简化navbar处理逻辑
      if (bannerEnabled) {
        const navbar = document.getElementById("navbar-wrapper");
        if (navbar && document.body.classList.contains("lg:is-home")) {
          const threshold = window.innerHeight * (BANNER_HEIGHT / 100) - 88;
          if (document.documentElement.scrollTop >= threshold) {
            navbar.classList.add("navbar-hidden");
          }
        }
      }
    });
    window.swup.hooks.on("content:replace", () => {
      // 更新主网格布局类名
      const gridClassCarrier = document.getElementById("grid-class-carrier");
      if (gridClassCarrier) {
        const gridClass = gridClassCarrier.getAttribute("data-grid-class");
        const mainGrid = document.getElementById("main-grid");
        if (mainGrid && gridClass) {

          const currentClasses = mainGrid.className.split(" ");
          const newClasses = currentClasses.filter(c => !c.startsWith("lg:grid-cols-") && !c.startsWith("md:grid-cols-") && !c.startsWith("grid-cols-"));
          
          // 添加新的网格类
          const gridClasses = gridClass.split(" ");
          mainGrid.className = [...newClasses, ...gridClasses].join(" ");
        }
      }

      // 只处理katex元素的容器，使用浏览器原生滚动条
      initCustomScrollbar();
      
      // 重新初始化图标加载器
      import("@/utils/icon-loader").then(({ initIconLoader }) => {
        initIconLoader();
      });

      // 检查当前页面是否为文章页面（有TOC元素）
      const tocWrapper = document.getElementById("toc-wrapper");
      const isArticlePage = tocWrapper !== null;

      // 只在文章页面重新初始化桌面端 TOC 组件
      if (isArticlePage) {
        const tocElement = document.querySelector("table-of-contents");
        if (tocElement && typeof (tocElement as any).init === "function") {
          setTimeout(() => {
            (tocElement as any).init();
          }, 100);
        }
      }

      // 重新初始化semifull模式的滚动检测
      const navbar = document.getElementById("navbar");
      if (navbar) {
        const transparentMode = navbar.getAttribute("data-transparent-mode");

        if (transparentMode === "semifull") {
          // 重新调用初始化函数来重新绑定滚动事件
          if (
            typeof (window as any).initSemifullScrollDetection === "function"
          ) {
            (window as any).initSemifullScrollDetection();
          }
        }
      }

    });
    window.swup.hooks.on("visit:start", (visit: { to: { url: string } }) => {
      // change banner height immediately when a link is clicked
      const bodyElement = document.querySelector("body");
      const isHomePage = pathsEqual(visit.to.url, url("/"));

      if (isHomePage) {
        bodyElement!.classList.add("lg:is-home");
      } else {
        bodyElement!.classList.remove("lg:is-home");
      }

      // Control banner text visibility based on page
      const bannerTextOverlay = document.querySelector(".banner-text-overlay");
      if (bannerTextOverlay) {
        if (isHomePage) {
          bannerTextOverlay.classList.remove("hidden");
        } else {
          bannerTextOverlay.classList.add("hidden");
        }
      }

      // Control navbar transparency based on page
      const navbar = document.getElementById("navbar");
      if (navbar) {
        navbar.setAttribute("data-is-home", isHomePage.toString());

        // 重新初始化semifull模式的滚动检测
        const transparentMode = navbar.getAttribute("data-transparent-mode");
        if (transparentMode === "semifull") {
          // 重新调用初始化函数来重新绑定滚动事件
          if (
            typeof (window as any).initSemifullScrollDetection === "function"
          ) {
            (window as any).initSemifullScrollDetection();
          }
        }
      }

      // Control mobile banner visibility based on page with improved staging animation
      // 只在移动端（1024px以下）处理banner隐藏
      const isMobile = window.innerWidth < 1024;
      
      // 在移动端禁用文章列表容器的过渡动画，防止与主内容区位置变化冲突
      if (isMobile) {
        const postListContainer = document.getElementById("post-list-container");
        if (postListContainer) {
          postListContainer.style.transition = "none";
        }
      }

      const bannerWrapper = document.getElementById("banner-wrapper");
      const mainContentWrapper = document.querySelector(
        ".absolute.w-full.z-30"
      ) as HTMLElement | null;

      if (isMobile && bannerWrapper && mainContentWrapper) {
        if (isHomePage) {
          // 首页：禁用主内容区域的过渡动画，防止文章列表下移
          mainContentWrapper.style.transition = "none";
          
          // 先显示banner，然后移除隐藏类让其优雅出现
          bannerWrapper.style.display = "";
          setTimeout(() => {
            bannerWrapper.classList.remove("mobile-hide-banner");
          }, 100);
          setTimeout(() => {
            mainContentWrapper.classList.remove("mobile-main-no-banner");
            // 在移除类之后立即恢复过渡动画（下次导航时使用）
            setTimeout(() => {
              mainContentWrapper.style.transition = "";
            }, 50);
          }, 150);
        } else {
          // 非首页：分阶段隐藏，先隐藏banner，再移动内容
          bannerWrapper.classList.add("mobile-hide-banner");
          // 延迟移动内容，让banner先完全消失
          setTimeout(() => {
            mainContentWrapper.classList.add("mobile-main-no-banner");
          }, 100);
        }
      } else if (!isMobile && bannerWrapper) {
        // 桌面端：确保banner正常显示
        bannerWrapper.style.display = "";
        bannerWrapper.classList.remove("mobile-hide-banner");
        if (mainContentWrapper) {
          mainContentWrapper.classList.remove("mobile-main-no-banner");
        }
      }

      // increase the page height during page transition to prevent the scrolling animation from jumping
      const heightExtend = document.getElementById("page-height-extend");
      if (heightExtend) {
        heightExtend.classList.remove("hidden");
      }

      // Hide the TOC while scrolling back to top
      let toc = document.getElementById("toc-wrapper");
      if (toc) {
        toc.classList.add("toc-not-ready");
      }
    });
    window.swup.hooks.on("page:view", () => {
      // hide the temp high element when the transition is done
      const heightExtend = document.getElementById("page-height-extend");
      if (heightExtend) {
        heightExtend.classList.remove("hidden");
      }

      // 确保页面滚动到顶部，使用平滑滚动避免侧边栏闪烁
      window.scrollTo({
        top: 0,
        behavior: "smooth",
      });

      // 在移动端恢复文章列表容器的过渡动画（在主内容区位置动画完成后）
      const isMobile = window.innerWidth < 1024;
      if (isMobile) {
        setTimeout(() => {
          const postListContainer = document.getElementById("post-list-container");
          if (postListContainer) {
            postListContainer.style.transition = "";
          }
        }, 600); // 等待主内容区动画完成（0.4s + 0.1s delay + 100ms buffer）
      }

      // 同步主题状态 - 解决从首页进入文章页面时代码块渲染问题
      const storedTheme = localStorage.getItem("theme") || siteConfig.themeColor.defaultMode || "light";
      let isDark = false;
      
      // 处理 system 模式
      if (storedTheme === "system") {
        isDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
      } else {
        isDark = storedTheme === "dark";
      }
      
      const expectedTheme = isDark
        ? expressiveCodeConfig.darkTheme
        : expressiveCodeConfig.lightTheme;
      const currentTheme = document.documentElement.getAttribute("data-theme");

      // 如果主题不匹配，静默更新（不触发事件，避免重新加载效果）
      if (currentTheme !== expectedTheme) {
        document.documentElement.setAttribute("data-theme", expectedTheme);
      }

      // 检查当前页面是否为文章页面，如果是则触发自定义事件用于初始化评论系统
      setTimeout(() => {
        if (document.getElementById("tcomment")) {
          // 触发自定义事件，通知评论系统页面已完全加载
          const pageLoadedEvent = new CustomEvent("firefly:page:loaded", {
            detail: {
              path: window.location.pathname,
              timestamp: Date.now(),
            },
          });
          document.dispatchEvent(pageLoadedEvent);
          console.log(
            "Layout: 触发 firefly:page:loaded 事件，路径:",
            window.location.pathname
          );
        }
      }, 300);
    });
    window.swup.hooks.on("visit:end", (_visit: { to: { url: string } }) => {
      setTimeout(() => {
        const heightExtend = document.getElementById("page-height-extend");
        if (heightExtend) {
          heightExtend.classList.add("hidden");
        }

        // Just make the transition looks better
        const toc = document.getElementById("toc-wrapper");
        if (toc) {
          toc.classList.remove("toc-not-ready");
        }

        // 移除页面切换保护，恢复过渡动画
        document.documentElement.classList.remove("is-page-transitioning");
      }, 200);
    });


  };
  if (window?.swup?.hooks) {
    setup();
  } else {
    document.addEventListener("swup:enable", setup);
  }

  let backToTopBtn = document.getElementById("back-to-top-btn");
  let toc = document.getElementById("toc-wrapper");
  let navbar = document.getElementById("navbar-wrapper");

  // 优化的滚动处理函数
  function scrollFunction() {
    const scrollTop = document.documentElement.scrollTop;
    const bannerHeight = window.innerHeight * (BANNER_HEIGHT / 100);

    // 使用批量DOM操作优化性能
    const operations: (() => void)[] = [];

    if (backToTopBtn) {
      operations.push(() => {
        if (scrollTop > bannerHeight) {
          backToTopBtn.classList.remove("hide");
        } else {
          backToTopBtn.classList.add("hide");
        }
      });
    }

    if (bannerEnabled && toc) {
      operations.push(() => {
        if (scrollTop > bannerHeight) {
          toc.classList.remove("toc-hide");
        } else {
          toc.classList.add("toc-hide");
        }
      });
    }

    if (bannerEnabled && navbar) {
      operations.push(() => {
        const isHome =
          document.body.classList.contains("lg:is-home") &&
          window.innerWidth >= 1024;
        const currentBannerHeight = isHome ? BANNER_HEIGHT_HOME : BANNER_HEIGHT;
        const threshold = window.innerHeight * (currentBannerHeight / 100) - 88;

        if (scrollTop >= threshold) {
          navbar.classList.add("navbar-hidden");
        } else {
          navbar.classList.remove("navbar-hidden");
        }
      });
    }

    // 批量执行DOM操作
    if (operations.length > 0) {
      requestAnimationFrame(() => {
        operations.forEach((op) => op());
      });
    }
  }

  // 使用优化的滚动性能处理
  let scrollTimeout: number;
  window.addEventListener(
    "scroll",
    () => {
      if (scrollTimeout) {
        cancelAnimationFrame(scrollTimeout);
      }
      scrollTimeout = requestAnimationFrame(scrollFunction);
    },
    { passive: true }
  );

  window.onresize = () => {
    // calculate the --banner-height-extend, which needs to be a multiple of 4 to avoid blurry text
    let offset = Math.floor(window.innerHeight * (BANNER_HEIGHT_EXTEND / 100));
    offset = offset - (offset % 4);
    document.documentElement.style.setProperty(
      "--banner-height-extend",
      `${offset}px`
    );
  };

  // 页面加载完成后初始化banner和katex容器
  if (document.readyState === "loading") {
    document.addEventListener("DOMContentLoaded", () => {
      showBanner();
      initCustomScrollbar();
    });
  } else {
    showBanner();
    initCustomScrollbar();
  }

  // Initialize wallpaper mode
  import { initWallpaperMode, initThemeListener } from "@/utils/setting-utils";
  import { initIconLoader } from "@/utils/icon-loader";
  if (document.readyState === "loading") {
    document.addEventListener("DOMContentLoaded", () => {
      initWallpaperMode();
      initThemeListener();
      initIconLoader();
    });
  } else {
    initWallpaperMode();
    initThemeListener();
    initIconLoader();
  }
</script>
