---
import BackToTop from "@components/common/controls/BackToTop.astro";
import OverlayWallpaper from "@components/interactive/OverlayWallpaper.astro";
import Footer from "@components/layout/Footer.astro";
import LeftSideBar from "@components/layout/LeftSideBar.astro";
import Navbar from "@components/layout/Navbar.astro";
import RightSideBar from "@components/layout/RightSideBar.astro";
import SideBar from "@components/layout/SideBar.astro";
import Live2DWidget from "@components/widget/Live2DWidget.astro";
import SpineModel from "@components/widget/SpineModel.astro";
import type { MarkdownHeading } from "astro";
import { Icon } from "astro-icon/components";
import FloatingTOC from "@/components/common/controls/FloatingTOC.astro";
import TypewriterText from "@/components/content/TypewriterText.astro";
import IconifyLoader from "@/components/misc/IconifyLoader.astro";
import ImageWrapper from "@/components/misc/ImageWrapper.astro";
import {
	backgroundWallpaper,
	live2dModelConfig,
	sidebarLayoutConfig,
	siteConfig,
} from "@/config";
import {
	BANNER_HEIGHT,
	BANNER_HEIGHT_EXTEND,
	MAIN_PANEL_OVERLAPS_BANNER_HEIGHT,
} from "@/constants/constants";
import { getBackgroundImages, isHomePage } from "@/utils/layout-utils";
import {
	generateGridClasses,
	generateMainContentClasses,
	generateRightSidebarClasses,
	generateSidebarClasses,
	getResponsiveSidebarConfig,
} from "@/utils/responsive-utils";
import Layout from "./Layout.astro";

interface Props {
	title?: string;
	banner?: string;
	description?: string;
	lang?: string;
	setOGTypeArticle?: boolean;
	postSlug?: string;
	headings?: MarkdownHeading[];
}

const backgroundImages = getBackgroundImages();

const {
	title,
	banner,
	description,
	lang,
	setOGTypeArticle,
	postSlug,
	headings = [],
} = Astro.props;

// 检查背景壁纸模式和是否允许切换
const isBannerMode = backgroundWallpaper.mode === "banner";
const isOverlayMode = backgroundWallpaper.mode === "overlay";
const isBackgroundEnabled = backgroundWallpaper.mode !== "none";
const isWallpaperSwitchable = backgroundWallpaper.switchable ?? true;

// 检查是否启用波浪动画效果
const wavesConfig = backgroundWallpaper.banner?.waves?.enable;
// 处理分设备控制的波浪动画
const wavesEnabledOnDesktop =
	typeof wavesConfig === "object" ? wavesConfig.desktop : wavesConfig;
const wavesEnabledOnMobile =
	typeof wavesConfig === "object" ? wavesConfig.mobile : wavesConfig;

// 获取波浪效果性能设置
const performanceConfig = backgroundWallpaper.banner?.waves?.performance;
const waveQuality = performanceConfig?.quality || "high";
const hardwareAcceleration = performanceConfig?.hardwareAcceleration ?? true;

// 处理分设备控制的横幅信贷显示
const creditEnableConfig = backgroundWallpaper.banner?.credit?.enable;
const creditEnabledOnDesktop =
	typeof creditEnableConfig === "object"
		? creditEnableConfig.desktop
		: creditEnableConfig;
const creditEnabledOnMobile =
	typeof creditEnableConfig === "object"
		? creditEnableConfig.mobile
		: creditEnableConfig;

const hasBannerCredit =
	isBannerMode && isBackgroundEnabled && creditEnableConfig;

// 处理分设备控制的横幅信贷文本和链接
const creditTextConfig = backgroundWallpaper.banner?.credit?.text;
const creditTextDesktop =
	typeof creditTextConfig === "object"
		? creditTextConfig.desktop
		: creditTextConfig;
const creditTextMobile =
	typeof creditTextConfig === "object"
		? creditTextConfig.mobile
		: creditTextConfig;

const creditUrlConfig = backgroundWallpaper.banner?.credit?.url;
const creditUrlDesktop =
	typeof creditUrlConfig === "object"
		? creditUrlConfig.desktop
		: creditUrlConfig;
const creditUrlMobile =
	typeof creditUrlConfig === "object"
		? creditUrlConfig.mobile
		: creditUrlConfig;

// 检查是否为首页
const isHomePageCheck = isHomePage(Astro.url.pathname);

// 随机选择副标题（当打字机关闭且为数组时）
const getRandomSubtitle = () => {
	const subtitle = backgroundWallpaper.banner?.homeText?.subtitle;
	if (Array.isArray(subtitle)) {
		const randomIndex = Math.floor(Math.random() * subtitle.length);
		return subtitle[randomIndex];
	}
	return subtitle;
};
const randomSubtitle = getRandomSubtitle();

// 主页横幅文本只在首页且全局开关为 true 时显示，不区分设备
const homeTextEnable = backgroundWallpaper.banner?.homeText?.enable;
const showHomeText = isBannerMode && !!homeTextEnable && isHomePageCheck;
// 手机端非首页不显示banner的CSS类
const mobileNonHomeBannerClass = !isHomePageCheck ? "mobile-hide-banner" : "";

// 计算主内容区域位置，考虑手机端非首页时banner被隐藏
const mainPanelTop =
	isBannerMode && isBackgroundEnabled
		? `calc(${BANNER_HEIGHT}vh - ${MAIN_PANEL_OVERLAPS_BANNER_HEIGHT}rem)`
		: "5.5rem";

// 当banner模式被禁用时，主内容区域应该始终从顶栏下面开始
// 非首页在小于1024px时会通过 mobile-main-no-banner CSS类覆盖top值为5.5rem
const finalMainPanelTop =
	isBannerMode && isBackgroundEnabled ? mainPanelTop : "5.5rem";

// 获取响应式侧边栏配置
// 传入是否为文章详情页的标志，用于控制是否显示右侧边栏
const sidebarConfig = getResponsiveSidebarConfig(postSlug !== undefined);
const { gridCols } = generateGridClasses(sidebarConfig);
const sidebarClass = generateSidebarClasses(sidebarConfig);
const rightSidebarClass = sidebarConfig.isBothSidebars
	? generateRightSidebarClasses(sidebarConfig)
	: "";
const mainContentClass = generateMainContentClasses(sidebarConfig);

// 检查是否应该启用半透明效果
const shouldEnableTransparency = isOverlayMode && isBackgroundEnabled;

// 为组件添加半透明效果的CSS类
const transparentClass = shouldEnableTransparency
	? "wallpaper-transparent"
	: "";

const navbarWidthFull = siteConfig.navbar.widthFull ?? false;
---

<Layout title={title} banner={banner} description={description} lang={lang} setOGTypeArticle={setOGTypeArticle} postSlug={postSlug}>


<!-- 全屏透明覆盖壁纸 - 如果允许切换则始终渲染，否则只渲染当前模式 -->
{(isWallpaperSwitchable || isOverlayMode) && (
	<OverlayWallpaper config={{
		src: {
			desktop: typeof backgroundImages.desktop === 'string' ? backgroundImages.desktop : '',
			mobile: typeof backgroundImages.mobile === 'string' ? backgroundImages.mobile : ''
		},
		zIndex: backgroundWallpaper.overlay?.zIndex,
		opacity: backgroundWallpaper.overlay?.opacity,
		blur: backgroundWallpaper.overlay?.blur,
	}} 
	className={isWallpaperSwitchable && !isOverlayMode ? "hidden opacity-0" : undefined} />
)}

<!-- 全局图标加载器 -->
<IconifyLoader />

<!-- 为全屏壁纸模式添加body类 -->
{shouldEnableTransparency && (
	<script>
		document.body.classList.add('wallpaper-transparent');
	</script>
)}

<!-- Navbar -->
<slot slot="head" name="head"></slot>
<div id="top-row" class="z-50 pointer-events-none relative transition-all duration-700 mx-auto" class:list={[navbarWidthFull ? "" : "max-w-[var(--page-width)] px-0 md:px-4"]}>
    <div id="navbar-wrapper" class="pointer-events-auto sticky top-0 transition-all">
        <Navbar></Navbar>
    </div>
</div>

<!-- Banner - 如果允许切换则始终渲染，否则只渲染当前模式 -->
{(isWallpaperSwitchable || isBannerMode) && (
<div id="banner-wrapper" class={`absolute z-10 w-full transition duration-700 overflow-hidden ${mobileNonHomeBannerClass}`} style={isWallpaperSwitchable ? `top: -${BANNER_HEIGHT_EXTEND}vh; display: none;` : `top: -${BANNER_HEIGHT_EXTEND}vh`}>
    <!-- 背景图片显示 -->
    <div class="relative h-full w-full">
        <!-- Mobile: use mobile-specific image -->
        <ImageWrapper 
            alt="Mobile background image of the blog" 
            class:list={["block lg:hidden object-cover h-full w-full transition duration-700 opacity-100"]}
            src={typeof backgroundImages.mobile === 'string' ? backgroundImages.mobile : (typeof backgroundImages.desktop === 'string' ? backgroundImages.desktop : '')} 
            position={backgroundWallpaper.banner?.position}
        />
        <!-- Desktop: use desktop-specific image -->
        <ImageWrapper 
            id="banner" 
            alt="Desktop background image of the blog" 
            class:list={["hidden lg:block object-cover h-full transition duration-700 opacity-100"]}
            src={typeof backgroundImages.desktop === 'string' ? backgroundImages.desktop : (typeof backgroundImages.mobile === 'string' ? backgroundImages.mobile : '')} 
            position={backgroundWallpaper.banner?.position}
        />
    </div>
    
    <!-- Home page text overlay - 始终渲染以便切换模式时控制显示 -->
    {(isWallpaperSwitchable || showHomeText) && homeTextEnable && (
        <div class={`banner-text-overlay absolute inset-0 z-20 flex items-center justify-center ${!showHomeText ? 'hidden' : ''}`}>
            <div class="w-4/5 lg:w-3/4 text-center mb-0">
                <div class="flex flex-col">
                    {backgroundWallpaper.banner?.homeText?.title && (
                        <h1 class="banner-title font-bold text-white mb-2 lg:mb-4 leading-tight" style={{ fontSize: backgroundWallpaper.banner.homeText.titleSize || "3rem" }}>
                            {backgroundWallpaper.banner.homeText.title}
                        </h1>
                    )}
                    {backgroundWallpaper.banner?.homeText?.subtitle && (
                        <h2 id="banner-subtitle" class="banner-subtitle text-white/90 leading-snug" style={{ fontSize: backgroundWallpaper.banner.homeText.subtitleSize || "1.5rem" }} data-subtitles={JSON.stringify(backgroundWallpaper.banner.homeText.subtitle)}>
                            {backgroundWallpaper.banner.homeText.typewriter?.enable ? (
                                <TypewriterText 
                                    text={backgroundWallpaper.banner.homeText.subtitle}
                                    speed={backgroundWallpaper.banner.homeText.typewriter.speed}
                                    deleteSpeed={backgroundWallpaper.banner.homeText.typewriter.deleteSpeed}
                                    pauseTime={backgroundWallpaper.banner.homeText.typewriter.pauseTime}
                                />
                            ) : (
                                randomSubtitle
                            )}
                        </h2>
                    )}
                </div>
            </div>
        </div>
    )}
    
    <script is:inline>
        function setRandomSubtitle() {
            const subtitleElement = document.getElementById('banner-subtitle');
            if (!subtitleElement) return;
            
            const subtitlesData = subtitleElement.dataset.subtitles;
            if (!subtitlesData) return;
            
            try {
                const subtitles = JSON.parse(subtitlesData);
                // Only randomize if it's an array and typewriter is NOT enabled (check for typewriter class)
                if (Array.isArray(subtitles) && subtitles.length > 0 && !subtitleElement.querySelector('.typewriter')) {
                    // Use a global variable to persist the subtitle across Swup navigations
                    // This variable will be reset on full page reload (F5), meeting the requirement
                    if (!window.fireflyCachedSubtitle) {
                        const randomIndex = Math.floor(Math.random() * subtitles.length);
                        window.fireflyCachedSubtitle = subtitles[randomIndex];
                    }
                    subtitleElement.textContent = window.fireflyCachedSubtitle;
                }
            } catch (e) {
                console.error("Failed to parse subtitles", e);
            }
        }

        // Run on initial load
        setRandomSubtitle();
    </script>
    
    <!-- Water waves effect - 始终渲染以便动态切换 -->
    {(wavesEnabledOnDesktop || wavesEnabledOnMobile) ? (
    <div class={`waves absolute -bottom-[1px] h-[10vh] max-h-[9.375rem] min-h-[3.125rem] w-full md:h-[15vh] 
        ${!wavesEnabledOnMobile ? 'hidden' : ''} ${!wavesEnabledOnDesktop ? 'md:hidden' : ''} ${wavesEnabledOnDesktop ? 'md:block' : ''}`} 
        id="header-waves" 
        style={`transform: translateZ(0); will-change: fill; ${hardwareAcceleration ? 'transform: translateZ(0);' : ''}`}
        data-wave-quality={waveQuality}
        data-hardware-acceleration={hardwareAcceleration}>
        <svg
            class="waves"
            xmlns="http://www.w3.org/2000/svg"
            xmlns:xlink="http://www.w3.org/1999/xlink"
            viewBox="0 20 150 32"
            preserveAspectRatio="none"
            shape-rendering={waveQuality === 'low' ? 'optimizeSpeed' : 'auto'}
            style={`transform: translateZ(0); backface-visibility: hidden; ${hardwareAcceleration ? 'will-change: transform;' : ''}`}
        >
            <defs>
                <path
                    id="gentle-wave"
                    d="M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v48h-352z"
                >
                </path>
            </defs>
            <g class="parallax" style={`transform: translateZ(0); ${hardwareAcceleration ? 'will-change: transform;' : ''}`}>
                <use
                    xlink:href="#gentle-wave"
                    x="48"
                    y="0"
                    class={`opacity-25 fill-[var(--page-bg)] ${waveQuality === 'low' ? 'wave-low-quality' : ''}`}
                    style={`animation-delay: -2s; animation-duration: ${waveQuality === 'low' ? '10s' : waveQuality === 'medium' ? '8s' : '7s'}; animation-name: ${waveQuality === 'low' ? 'wave-slow' : waveQuality === 'medium' ? 'wave' : 'wave'}; ${hardwareAcceleration ? 'will-change: transform;' : ''}`}
                ></use>
                <use
                    xlink:href="#gentle-wave"
                    x="48"
                    y="3"
                    class={`opacity-50 fill-[var(--page-bg)] ${waveQuality === 'low' ? 'wave-low-quality' : ''}`}
                    style={`animation-delay: -3s; animation-duration: ${waveQuality === 'low' ? '15s' : waveQuality === 'medium' ? '12s' : '10s'}; animation-name: ${waveQuality === 'low' ? 'wave-slow' : waveQuality === 'medium' ? 'wave' : 'wave'}; ${hardwareAcceleration ? 'will-change: transform;' : ''}`}
                ></use>
                <use
                    xlink:href="#gentle-wave"
                    x="48"
                    y="5"
                    class={`opacity-75 fill-[var(--page-bg)] ${waveQuality === 'low' ? 'wave-low-quality' : ''}`}
                    style={`animation-delay: -4s; animation-duration: ${waveQuality === 'low' ? '20s' : waveQuality === 'medium' ? '16s' : '13s'}; animation-name: ${waveQuality === 'low' ? 'wave-slow' : waveQuality === 'medium' ? 'wave' : 'wave'}; ${hardwareAcceleration ? 'will-change: transform;' : ''}`}
                ></use>
                <use
                    xlink:href="#gentle-wave"
                    x="48"
                    y="7"
                    class={`fill-[var(--page-bg)] ${waveQuality === 'low' ? 'wave-low-quality' : ''}`}
                    style={`animation-delay: -5s; animation-duration: ${waveQuality === 'low' ? '30s' : waveQuality === 'medium' ? '25s' : '20s'}; animation-name: ${waveQuality === 'low' ? 'wave-slow' : waveQuality === 'medium' ? 'wave' : 'wave'}; ${hardwareAcceleration ? 'will-change: transform;' : ''}`}
                ></use>
            </g>
        </svg>
    </div>
    ) : null}
</div>
)}

<!-- Main content -->
<div class={`absolute w-full z-30 pointer-events-none ${mobileNonHomeBannerClass ? 'mobile-main-no-banner' : ''} ${!(isBannerMode && isBackgroundEnabled) ? 'no-banner-layout' : ''} ${transparentClass}`} style={`top: ${finalMainPanelTop}`}>
    <!-- The pointer-events-none here prevent blocking the click event of the TOC -->
    <div class="relative max-w-[var(--page-width)] mx-auto pointer-events-auto">
        <div id="main-grid" class={`transition duration-700 w-full left-0 right-0 grid ${gridCols} grid-rows-[auto_1fr_auto] lg:grid-rows-[auto] mx-auto gap-4 px-2 md:px-4 ${!sidebarConfig.mobileShowSidebar ? 'mobile-no-sidebar' : ''}`}
        >
            <!-- Background image credit - Desktop -->
            {hasBannerCredit && creditEnabledOnDesktop && <a 
                href={creditUrlDesktop || "#"} 
                id="banner-credit-desktop" 
                target={creditUrlDesktop ? "_blank" : "_self"}
                rel={creditUrlDesktop ? "noopener" : ""}
                aria-label="Visit image source"
                class:list={[
                    "group onload-animation transition-all absolute justify-center items-center rounded-full " +
                    "px-3 right-4 -top-[3.25rem] bg-black/60 hover:bg-black/70 h-9 hidden md:flex", 
                    {"hover:pr-9 active:bg-black/80": creditUrlDesktop}
                ]}
            >
                <Icon class="text-white/75 text-[1.25rem] mr-1" name="material-symbols:copyright-outline-rounded" ></Icon>
                <div class="text-white/75 text-xs">{creditTextDesktop}</div>
                {creditUrlDesktop && <Icon class:list={["transition absolute text-[oklch(0.75_0.14_var(--hue))] right-4 text-[0.75rem] opacity-0 group-hover:opacity-100"]}
                      name="fa6-solid:arrow-up-right-from-square">
                </Icon>}
            </a>}

            <!-- Background image credit - Mobile -->
            {hasBannerCredit && creditEnabledOnMobile && <a 
                href={creditUrlMobile || "#"} 
                id="banner-credit-mobile" 
                target={creditUrlMobile ? "_blank" : "_self"}
                rel={creditUrlMobile ? "noopener" : ""}
                aria-label="Visit image source"
                class:list={[
                    "group onload-animation transition-all absolute justify-center items-center rounded-full " +
                    "px-3 right-4 -top-[3.25rem] bg-black/60 hover:bg-black/70 h-9 flex md:hidden", 
                    {"hover:pr-9 active:bg-black/80": creditUrlMobile}
                ]}
            >
                <Icon class="text-white/75 text-[1.25rem] mr-1" name="material-symbols:copyright-outline-rounded" ></Icon>
                <div class="text-white/75 text-xs">{creditTextMobile}</div>
                {creditUrlMobile && <Icon class:list={["transition absolute text-[oklch(0.75_0.14_var(--hue))] right-4 text-[0.75rem] opacity-0 group-hover:opacity-100"]}
                      name="fa6-solid:arrow-up-right-from-square">
                </Icon>}
            </a>}


            {/* 渲染侧边栏 - 根据配置决定使用单侧或双侧边栏 */}
            <div id="left-sidebar-wrapper" class="contents">
                {sidebarConfig.isBothSidebars ? (
                    <>
                        {/* 左侧边栏 */}
                        {sidebarConfig.hasLeftComponents && (sidebarConfig.mobileShowSidebar || sidebarConfig.tabletShowSidebar || sidebarConfig.desktopShowSidebar) && (
                            <LeftSideBar class={`${sidebarClass} ${transparentClass}`} headings={headings}></LeftSideBar>
                        )}
                    </>
                ) : (
                    <>
                        {/* 单侧边栏布局 */}
                        {(sidebarConfig.mobileShowSidebar || sidebarConfig.tabletShowSidebar || sidebarConfig.desktopShowSidebar) && (
                            <SideBar class={`${sidebarClass} ${transparentClass}`} headings={headings}></SideBar>
                        )}
                    </>
                )}
            </div>
                    
            {/* 主内容区 - 始终渲染，确保 Swup 容器存在 */}
            <main id="swup-container" class={`${mainContentClass} transition-main`}>
                {/* 携带网格布局类名，用于JS更新父容器 */}
                <div id="grid-class-carrier" data-grid-class={gridCols} class="hidden"></div>
                <div id="content-wrapper" class="onload-animation transition-leaving">
                    <slot></slot>
                    <div class="footer col-span-2 onload-animation hidden lg:block">
                        <Footer></Footer>
                    </div>
                </div>
            </main>
            
            {/* 右侧边栏 - 仅双侧边栏模式 */}
            {/* 
                如果全局配置为双侧栏(position: both)，则使用静态容器(不被swup替换)，避免闪烁。
                如果全局配置为单侧栏(position: left)，则使用动态容器(被swup替换)，以便在文章页显示右侧栏。
                注意：为了满足swup要求所有containers必须存在，我们在两种模式下都必须渲染 #right-sidebar-dynamic。
            */}
            {sidebarLayoutConfig.position === "both" ? (
                <>
                    <div id="right-sidebar-static" class="contents">
                        {sidebarConfig.isBothSidebars && sidebarConfig.hasRightComponents && (sidebarConfig.mobileShowSidebar || sidebarConfig.tabletShowSidebar || sidebarConfig.desktopShowSidebar) && (
                            <RightSideBar class={`${rightSidebarClass} ${transparentClass}`} headings={headings}></RightSideBar>
                        )}
                    </div>
                    <div id="right-sidebar-dynamic" class="hidden"></div>
                </>
            ) : (
                <div id="right-sidebar-dynamic" class="contents">
                    {sidebarConfig.isBothSidebars && sidebarConfig.hasRightComponents && (sidebarConfig.mobileShowSidebar || sidebarConfig.tabletShowSidebar || sidebarConfig.desktopShowSidebar) && (
                        <RightSideBar class={`${rightSidebarClass} ${transparentClass}`} headings={headings}></RightSideBar>
                    )}
                </div>
            )}

            <div class="footer col-span-2 onload-animation block lg:hidden">
                <Footer></Footer>
            </div>
        </div>

        <BackToTop></BackToTop>
        <SpineModel></SpineModel>
        {live2dModelConfig.enable && <Live2DWidget config={live2dModelConfig} />}
    </div>
</div>

<!-- 悬浮TOC组件 -->
<FloatingTOC headings={headings}></FloatingTOC>


</Layout>

<style is:global>
  /* 在低于1200px时隐藏右侧边栏 */
  @media (max-width: 1199px) {
    #right-sidebar {
      display: none !important;
    }
    
    /* 同时调整网格布局为两列 */
    #main-grid {
      grid-template-columns: 17.5rem 1fr !important;
    }
  }
  
  /* 在1024px-1199px之间，确保平板端也正确显示 */
  @media (min-width: 1024px) and (max-width: 1199px) {
    #main-grid {
      grid-template-columns: 17.5rem 1fr !important;
    }
  }
  

  
  /* 右侧栏平滑过渡 */
  #right-sidebar {
    transition: opacity 0.35s ease-in-out, 
                transform 0.35s ease-in-out;
  }

  /* 横幅文字阴影 - 更柔和的扩散效果 */
  .banner-title {
    text-shadow: 0 4px 24px rgba(0, 0, 0, 0.6);
  }
  
  .banner-subtitle {
    text-shadow: 0 2px 16px rgba(0, 0, 0, 0.6);
  }
</style>

