<?php
/**
 * 800BUS - 画廊 v5.0
 */
require_once __DIR__ . '/includes/config.php';
require_once __DIR__ . '/includes/media_helpers.php';
session_start();
header('Cache-Control: public, max-age=300, stale-while-revalidate=60');

$keyword_raw = isset($_GET['keyword']) ? trim($_GET['keyword']) : '';
$keyword = $conn->real_escape_string($keyword_raw);
$sort = isset($_GET['sort']) ? $_GET['sort'] : 'new';
$valid_sorts = ['new', 'old', 'top'];
if (!in_array($sort, $valid_sorts, true)) {
    $sort = 'new';
}
$section = isset($_GET['section']) ? $_GET['section'] : 'all';
$valid_sections = ['all', 'good', 'bad', 'medium', 'people', 'humanity'];
if (!in_array($section, $valid_sections, true)) {
    $section = 'all';
}

$searched_user = null;
$searched_user_items = [];

if (!empty($keyword)) {
    $kw_esc = $conn->real_escape_string($keyword);
    $user_query = $conn->query(
        "SELECT id, username, email, is_admin, created_at FROM users WHERE " .
        "id = '" . (int)$kw_esc . "' OR email LIKE '%$kw_esc%' OR username LIKE '%$kw_esc%' LIMIT 1"
    );
    if ($user_query && $user_query->num_rows > 0) {
        $searched_user = $user_query->fetch_assoc();
    }
}

$page = max(1, (int)($_GET['page'] ?? 1));
$limit = 60;
$offset = ($page - 1) * $limit;

$where = "WHERE s.status = 1";

if (!empty($keyword)) {
    $kw_esc2 = $conn->real_escape_string($keyword);
    if ($searched_user) {
        $where .= " AND (s.license_plate LIKE '%$kw_esc2%' OR s.brand LIKE '%$kw_esc2%' OR s.region LIKE '%$kw_esc2%' OR s.user_id = " . (int)$searched_user['id'] . ")";
    } else {
        $where .= " AND (s.license_plate LIKE '%$kw_esc2%' OR s.brand LIKE '%$kw_esc2%' OR s.region LIKE '%$kw_esc2%' OR u.email LIKE '%$kw_esc2%')";
    }
}
if ($section !== 'all') {
    $secEsc = $conn->real_escape_string($section);
    $where .= " AND s.section = '$secEsc'";
}

$total = 0;
$count_sql = "SELECT COUNT(DISTINCT s.id) as c
        FROM submissions s
        LEFT JOIN users u ON s.user_id = u.id
        $where";
$count_res = $conn->query($count_sql);
if ($count_res) {
    $total = (int)($count_res->fetch_assoc()['c'] ?? 0);
}

if ($searched_user) {
    $user_items_sql = "SELECT s.id, s.photo_path, s.license_plate, s.region, s.brand, s.created_at,
            u.email as author_email, AVG(r.rating) as avg_rating
            FROM submissions s
            LEFT JOIN users u ON s.user_id = u.id
            LEFT JOIN ratings r ON s.id = r.submission_id
            WHERE s.status = 1 AND s.user_id = " . (int)$searched_user['id'] . "
            GROUP BY s.id ORDER BY s.id DESC";
    $user_items_res = $conn->query($user_items_sql);
    if ($user_items_res) {
        while ($row = $user_items_res->fetch_assoc()) {
            $searched_user_items[] = $row;
        }
    }
}

if ($sort === 'top') {
    $order_by = 'ORDER BY avg_rating DESC, s.id DESC';
} elseif ($sort === 'old') {
    $order_by = 'ORDER BY s.id ASC';
} else {
    $order_by = 'ORDER BY s.id DESC';
}

$sql = "SELECT s.id, s.photo_path, s.license_plate, s.region, s.brand, s.created_at,
        u.email as author_email, AVG(r.rating) as avg_rating
        FROM submissions s
        LEFT JOIN users u ON s.user_id = u.id
        LEFT JOIN ratings r ON s.id = r.submission_id
        $where
        GROUP BY s.id $order_by LIMIT $limit OFFSET $offset";

$res = $conn->query($sql);
$all_items = [];
if ($res) {
    while($row = $res->fetch_assoc()) {
        $all_items[] = $row;
    }
}

$cloud_cache_file = __DIR__ . '/cache/cloud_tags.json';
$cloud_tags = null;
if (file_exists($cloud_cache_file) && (time() - filemtime($cloud_cache_file)) < 600) {
    $cloud_tags = json_decode(file_get_contents($cloud_cache_file), true);
}
if ($cloud_tags === null) {
    $corpus = '';
    $cloud_res = $conn->query("SELECT brand, region, license_plate FROM submissions WHERE status = 1 ORDER BY id DESC LIMIT 200");
    if ($cloud_res) {
        while ($row = $cloud_res->fetch_assoc()) {
            $corpus .= " " . ($row['brand'] ?? '') . " " . ($row['region'] ?? '') . " " . ($row['license_plate'] ?? '');
        }
    }
    $cloud_tags = getCloudTags($corpus);
    if (!is_dir(__DIR__ . '/cache')) {
        @mkdir(__DIR__ . '/cache', 0755, true);
    }
    @file_put_contents($cloud_cache_file, json_encode($cloud_tags));
}

$is_logged_in = isset($_SESSION['user_id']);
$user_data = null;
if ($is_logged_in) {
    $uid = $_SESSION['user_id'];
    $u_res = $conn->query("SELECT username, is_admin FROM users WHERE id = $uid");
    $user_data = $u_res->fetch_assoc();
}
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <title><?= !empty($keyword_raw) ? '搜索：' . htmlspecialchars($keyword_raw) . ' - 800BUS | 捌佰档案站' : '画廊 - 800BUS | 捌佰档案站' ?></title>
    <style>
        * { box-sizing: border-box; margin: 0; padding: 0; }

        body {
            font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Microsoft YaHei", sans-serif;
            color: #2d3748;
            background: url('https://bg-img.800bus.cn/800bus/system/') center/cover fixed;
            min-height: 100vh;
        }

        .bg-overlay {
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: rgba(232, 238, 244, 0.88);
            z-index: -1;
        }

        /* 导航栏 */
        .nav {
            position: sticky;
            top: 0;
            width: 100%;
            height: 56px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 0 24px;
            background: rgba(255,255,255,0.85);
            backdrop-filter: blur(12px);
            border-bottom: 1px solid #cbd5e0;
            z-index: 100;
        }
        .nav .logo {
            font-size: 18px;
            font-weight: 700;
            color: #2b6cb0;
        }
        .nav .links {
            display: flex;
            align-items: center;
            gap: 4px;
        }
        .nav a {
            text-decoration: none;
            color: #4a5568;
            padding: 6px 12px;
            border-radius: 6px;
            font-size: 14px;
        }
        .nav a:hover {
            background: #e2e8f0;
        }
        .nav a.admin-tag {
            background: #fed7d7;
            color: #c53030;
        }

        /* 搜索栏 */
        .search-section {
            max-width: 1200px;
            margin: 20px auto;
            padding: 0 20px;
        }
        .search-bar {
            background: #fff;
            padding: 4px;
            border-radius: 8px;
            display: flex;
            box-shadow: 0 2px 8px rgba(0,0,0,0.08);
            border: 1px solid #cbd5e0;
            max-width: 400px;
        }
        .search-bar input {
            flex: 1;
            border: none;
            padding: 10px 14px;
            outline: none;
            font-size: 14px;
            background: transparent;
        }
        .search-bar button {
            background: #2b6cb0;
            color: #fff;
            border: none;
            padding: 8px 16px;
            border-radius: 6px;
            font-size: 14px;
            cursor: pointer;
        }

        /* 标签云 */
        .cloud-container {
            max-width: 1200px;
            margin: 16px auto 0;
            padding: 0 20px;
            display: flex;
            flex-wrap: wrap;
            gap: 6px;
        }
        .tag-cloud-item {
            text-decoration: none;
            padding: 4px 10px;
            border-radius: 4px;
            font-size: 12px;
            background: #edf2f7;
            color: #718096;
        }
        .tag-cloud-item:hover {
            background: #cbd5e0;
            color: #4a5568;
        }

        /* 筛选栏 */
        .filter-bar {
            max-width: 1200px;
            margin: 16px auto;
            padding: 0 20px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            flex-wrap: wrap;
            gap: 10px;
        }
        .filter-chips {
            display: flex;
            gap: 6px;
            flex-wrap: wrap;
        }
        .chip {
            text-decoration: none;
            color: #4a5568;
            font-size: 13px;
            padding: 6px 14px;
            border-radius: 6px;
            background: #fff;
            border: 1px solid #cbd5e0;
        }
        .chip:hover {
            border-color: #2b6cb0;
            color: #2b6cb0;
        }
        .chip.active {
            background: #2b6cb0;
            color: #fff;
            border-color: #2b6cb0;
        }
        .count-info {
            font-size: 13px;
            color: #718096;
        }

        /* 网格布局 */
        .container {
            padding: 20px;
            max-width: 1200px;
            margin: 0 auto;
        }
        .photo-grid {
            display: grid;
            grid-template-columns: repeat(2, 1fr);
            gap: 12px;
        }
        @media (min-width: 768px) {
            .photo-grid { grid-template-columns: repeat(3, 1fr); gap: 16px; }
        }
        @media (min-width: 1024px) {
            .photo-grid { grid-template-columns: repeat(4, 1fr); }
        }
        @media (min-width: 1400px) {
            .photo-grid { grid-template-columns: repeat(5, 1fr); }
        }

        .box {
            display: flex;
            flex-direction: column;
            background: #fff;
            border-radius: 8px;
            overflow: hidden;
            text-decoration: none;
            color: inherit;
            border: 1px solid #e2e8f0;
        }
        .box:hover {
            border-color: #4299e1;
        }

        .img-container {
            position: relative;
            width: 100%;
            aspect-ratio: 4/3;
            background: #edf2f7;
            display: flex;
            align-items: center;
            justify-content: center;
        }
        .box img {
            width: 100%;
            height: 100%;
            object-fit: cover;
            opacity: 0;
            transition: opacity 0.4s ease-out, filter 0.3s ease-out;
            filter: blur(8px);
        }
        .box img.loaded {
            opacity: 1;
            filter: blur(0);
        }

        .loading-spinner {
            width: 24px;
            height: 24px;
            border: 3px solid rgba(0,0,0,0.1);
            border-top: 3px solid #2b6cb0;
            border-radius: 50%;
            animation: spin 0.8s linear infinite;
        }
        @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }

        .box-text {
            padding: 12px;
            flex: 1;
            display: flex;
            flex-direction: column;
        }
        .box-title {
            font-size: 14px;
            font-weight: 600;
            margin-bottom: 6px;
            color: #2d3748;
        }
        .box-meta {
            display: flex;
            justify-content: space-between;
            align-items: center;
            font-size: 12px;
        }
        .tag-plate {
            background: #edf2f7;
            padding: 2px 6px;
            border-radius: 4px;
            font-weight: 600;
            color: #4a5568;
        }
        .tag-star {
            color: #f6e05e;
            font-weight: 700;
        }
        .box-meta-bottom {
            font-size: 11px;
            color: #718096;
            margin-top: 6px;
        }

        /* 分页 */
        .pagination {
            display: flex;
            gap: 8px;
            justify-content: center;
            margin: 24px 0;
        }
        .pagination a {
            text-decoration: none;
            color: #4a5568;
            font-size: 13px;
            padding: 6px 14px;
            border-radius: 6px;
            background: #fff;
            border: 1px solid #cbd5e0;
        }
        .pagination a:hover {
            border-color: #2b6cb0;
            color: #2b6cb0;
        }

        /* 空状态 */
        .empty-state {
            text-align: center;
            padding: 60px 20px;
            color: #718096;
        }

        /* 用户搜索结果 */
        .user-search-section {
            max-width: 1200px;
            margin: 0 auto;
            padding: 0 20px;
        }
        .user-section-title {
            font-size: 14px;
            font-weight: 700;
            color: #4a5568;
            margin-bottom: 12px;
            padding-bottom: 8px;
            border-bottom: 1px solid #e2e8f0;
            display: flex;
            align-items: center;
            gap: 8px;
        }
        .user-card {
            display: flex;
            align-items: center;
            gap: 16px;
            background: #fff;
            border: 1px solid #e2e8f0;
            border-radius: 12px;
            padding: 16px 20px;
            text-decoration: none;
            color: inherit;
            transition: all 0.2s;
            max-width: 400px;
        }
        .user-card:hover {
            border-color: #2b6cb0;
            box-shadow: 0 2px 12px rgba(43,108,176,0.1);
        }
        .user-avatar {
            width: 48px;
            height: 48px;
            border-radius: 50%;
            background: linear-gradient(135deg, #667eea, #764ba2);
            display: flex;
            align-items: center;
            justify-content: center;
            color: #fff;
            font-size: 20px;
            font-weight: 700;
            flex-shrink: 0;
        }
        .user-avatar.admin {
            background: linear-gradient(135deg, #f093fb, #f5576c);
        }
        .user-info {
            flex: 1;
            min-width: 0;
        }
        .user-name {
            font-size: 15px;
            font-weight: 700;
            color: #1a202c;
            margin-bottom: 2px;
            display: flex;
            align-items: center;
            gap: 6px;
        }
        .user-badge {
            font-size: 10px;
            font-weight: 700;
            padding: 1px 6px;
            border-radius: 4px;
            letter-spacing: 0.05em;
        }
        .user-badge-admin {
            background: #fee2e2;
            color: #c53030;
        }
        .user-badge-uploader {
            background: #ebf8ff;
            color: #2b6cb0;
        }
        .user-meta {
            font-size: 12px;
            color: #718096;
        }
        .user-stats {
            font-size: 12px;
            color: #a0aec0;
            margin-top: 2px;
        }
        .user-arrow {
            color: #cbd5e0;
            font-size: 18px;
            flex-shrink: 0;
        }

        /* 页脚 */
        footer {
            text-align: center;
            padding: 40px 20px;
            background: #edf2f7;
            border-top: 1px solid #cbd5e0;
            font-size: 13px;
            color: #718096;
        }
        footer a {
            color: #2b6cb0;
            text-decoration: none;
        }
        footer a:hover {
            text-decoration: underline;
        }
        @media (max-width: 600px) {
            footer { padding: 14px 12px; font-size: 11px; }
        }
    </style>
    <script src="includes/lazyload.js" defer></script>
</head>
<body>
<div class="bg-overlay"></div>

<nav class="nav">
    <div class="logo">800BUS</div>
    <div class="links">
        <a href="/">返回主页</a>
        <?php if($is_logged_in): ?>
            <?php if(isset($user_data['is_admin']) && $user_data['is_admin'] == 1): ?>
                <a href="admin/" class="admin-tag">后台管理</a>
            <?php endif; ?>
            <a href="user/">个人中心</a>
        <?php else: ?>
            <a href="login.php">登入系统</a>
        <?php endif; ?>
    </div>
</nav>

<div class="search-section">
    <form action="gallery.php" method="GET" class="search-bar">
        <input type="text" name="keyword" placeholder="搜索型号、地区、车牌或用户..." value="<?= htmlspecialchars($keyword_raw) ?>">
        <button type="submit">搜索</button>
    </form>
</div>

<?php if(!empty($cloud_tags)): ?>
<div class="cloud-container">
    <?php foreach($cloud_tags as $tag => $count): ?>
        <a href="gallery.php?keyword=<?= urlencode($tag) ?>&section=<?= $section ?>" class="tag-cloud-item">#<?= htmlspecialchars($tag) ?></a>
    <?php endforeach; ?>
</div>
<?php endif; ?>

<div class="filter-bar">
    <div class="filter-chips">
        <a href="gallery.php?sort=new&section=<?= urlencode($section) ?>&keyword=<?= urlencode($keyword_raw) ?>" class="chip <?= htmlspecialchars($sort == 'new' ? 'active' : '') ?>">最新</a>
            <a href="gallery.php?sort=old&section=<?= urlencode($section) ?>&keyword=<?= urlencode($keyword_raw) ?>" class="chip <?= htmlspecialchars($sort == 'old' ? 'active' : '') ?>">回溯</a>
            <a href="gallery.php?sort=top&section=<?= urlencode($section) ?>&keyword=<?= urlencode($keyword_raw) ?>" class="chip <?= htmlspecialchars($sort == 'top' ? 'active' : '') ?>">热门</a>
    </div>
    <div class="filter-chips">
        <a href="gallery.php?section=all&sort=<?= urlencode($sort) ?>&keyword=<?= urlencode($keyword_raw) ?>" class="chip <?= htmlspecialchars($section == 'all' ? 'active' : '') ?>">全部</a>
            <a href="gallery.php?section=good&sort=<?= urlencode($sort) ?>&keyword=<?= urlencode($keyword_raw) ?>" class="chip <?= htmlspecialchars($section == 'good' ? 'active' : '') ?>">好图区</a>
            <a href="gallery.php?section=bad&sort=<?= urlencode($sort) ?>&keyword=<?= urlencode($keyword_raw) ?>" class="chip <?= htmlspecialchars($section == 'bad' ? 'active' : '') ?>">屎图区</a>
            <a href="gallery.php?section=medium&sort=<?= urlencode($sort) ?>&keyword=<?= urlencode($keyword_raw) ?>" class="chip <?= htmlspecialchars($section == 'medium' ? 'active' : '') ?>">中图区</a>
            <a href="gallery.php?section=people&sort=<?= urlencode($sort) ?>&keyword=<?= urlencode($keyword_raw) ?>" class="chip <?= htmlspecialchars($section == 'people' ? 'active' : '') ?>">人物志区</a>
            <a href="gallery.php?section=humanity&sort=<?= urlencode($sort) ?>&keyword=<?= urlencode($keyword_raw) ?>" class="chip <?= htmlspecialchars($section == 'humanity' ? 'active' : '') ?>">人文区</a>
    </div>
    <div class="count-info"><?= $total ?> 条记录 · 第 <?= $page ?> 页</div>
</div>

<div class="container">
    <?php if ($searched_user): ?>
    <div class="user-search-section" style="margin-bottom: 20px;">
        <div class="user-section-title">
            相关用户
        </div>
        <a href="/user/<?= $searched_user['id'] ?>" class="user-card">
            <div class="user-avatar <?= $searched_user['is_admin'] ? 'admin' : '' ?>">
                <?php if (!empty($searched_user['email']) && strpos($searched_user['email'], '@qq.com') !== false): ?>
                <img src="http://q1.qlogo.cn/g?b=qq&nk=<?= htmlspecialchars(explode('@', $searched_user['email'])[0]) ?>&s=100" style="width:100%;height:100%;border-radius:50%;object-fit:cover;" loading="lazy" decoding="async">
                <?php else: ?>
                <?= mb_substr($searched_user['username'], 0, 1, 'UTF-8') ?>
                <?php endif; ?>
            </div>
            <div class="user-info">
                <div class="user-name">
                    <?= htmlspecialchars($searched_user['username']) ?>
                    <?php if ($searched_user['is_admin']): ?>
                    <span class="user-badge user-badge-admin">管理员</span>
                    <?php endif; ?>
                </div>
                <div class="user-meta"><?= htmlspecialchars($searched_user['email']) ?></div>
                <div class="user-stats">
                    档案数：<?= count($searched_user_items) ?> ·
                    注册时间：<?= date('Y-m-d', strtotime($searched_user['created_at'])) ?>
                </div>
            </div>
            <div class="user-arrow">›</div>
        </a>
    </div>
    <?php endif; ?>

    <?php if(count($all_items) > 0): ?>
    <div class="photo-grid">
        <?php foreach($all_items as $r): ?>
        <a href="/photo/<?= $r['id'] ?>" class="box">
            <div class="img-container">
                <div class="loading-spinner"></div>
                <?php 
                    $raw_path = $r['photo_path'] ?? '';
                    $main_path = cdn_image_url($raw_path);
                    $blur_path = cdn_blur_url($raw_path);
                    $thumb_path = cdn_thumb_url($raw_path);
                ?>
                <img
                    src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
                    data-src="<?= htmlspecialchars($thumb_path) ?>"
                    data-blur="<?= htmlspecialchars($blur_path) ?>"
                    data-fallback="<?= htmlspecialchars($main_path) ?>"
                    class="lazy-img"
                    alt="800BUS"
                    loading="lazy"
                    decoding="async"
                    onerror="this.onerror=null;var f=this.getAttribute('data-fallback');if(f&&this.src.indexOf(f)===-1)this.src=f;else this.classList.add('loaded');"
                >
            </div>
            <div class="box-text">
                <span class="box-title"><?= htmlspecialchars($r['brand'] ?: 'BUS ARCHIVE') ?></span>
                <div class="box-meta">
                    <span class="tag-plate"><?= htmlspecialchars($r['license_plate']) ?></span>
                    <span class="tag-star">★ <?= number_format($r['avg_rating'] ?: 0, 1) ?></span>
                </div>
                <div class="box-meta-bottom">
                    <span><?= htmlspecialchars($r['region'] ?: '未知') ?></span>
                    <span><?= date('y/m/d', strtotime($r['created_at'])) ?></span>
                </div>
            </div>
        </a>
        <?php endforeach; ?>
    </div>
    <?php if ($total > $limit): ?>
        <div class="pagination">
            <?php
                $qs = 'gallery.php?sort=' . urlencode($sort)
                    . '&section=' . urlencode($section)
                    . '&keyword=' . urlencode($keyword_raw);
            ?>
            <?php if ($page > 1): ?>
                <a href="<?= htmlspecialchars($qs) ?>&page=<?= urlencode($page - 1) ?>">上一页</a>
            <?php endif; ?>
            <?php if ($offset + $limit < $total): ?>
                <a href="<?= htmlspecialchars($qs) ?>&page=<?= urlencode($page + 1) ?>">下一页</a>
            <?php endif; ?>
        </div>
    <?php endif; ?>
    <?php else: ?>
    <div class="empty-state">
        <h3>暂无记录</h3>
    </div>
    <?php endif; ?>
</div>

<?php require_once __DIR__ . '/system/footer.php'; ?>

<script>
document.addEventListener("DOMContentLoaded", function() {
    var lazyImages = document.querySelectorAll(".lazy-img");
    var PLACEHOLDER = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
    
    if (!('IntersectionObserver' in window)) {
        lazyImages.forEach(function(img) {
            var blur = img.getAttribute("data-blur") || img.getAttribute("data-src");
            if (blur) {
                img.src = blur;
            }
            img.classList.add("loaded");
            var spinner = img.parentElement.querySelector(".loading-spinner");
            if (spinner) spinner.style.display = "none";
        });
    } else {
        var observer = new IntersectionObserver(function(entries, obs) {
            entries.forEach(function(entry) {
                if (!entry.isIntersecting) return;

                var img = entry.target;
                var thumbSrc = img.getAttribute("data-src");
                var blurSrc = img.getAttribute("data-blur");
                var fallbackSrc = img.getAttribute("data-fallback");
                
                if (!thumbSrc || img.dataset.loaded === '1') {
                    obs.unobserve(img);
                    return;
                }

                // 阶段1: 加载 blur 占位图
                if (blurSrc && img.src === PLACEHOLDER) {
                    var blurImg = new Image();
                    blurImg.onload = function() {
                        img.src = blurSrc;
                        // 阶段2: blur 加载完毕后，预加载高清缩略图
                        var highImg = new Image();
                        highImg.onload = function() {
                            img.src = thumbSrc;
                            img.classList.add("loaded");
                            img.dataset.loaded = '1';
                            var spinner = img.parentElement.querySelector(".loading-spinner");
                            if (spinner) spinner.style.display = "none";
                        };
                        highImg.onerror = function() {
                            if (fallbackSrc && fallbackSrc !== thumbSrc) {
                                img.src = fallbackSrc;
                            }
                            img.classList.add("loaded");
                            img.dataset.loaded = '1';
                            var spinner = img.parentElement.querySelector(".loading-spinner");
                            if (spinner) spinner.style.display = "none";
                        };
                        highImg.src = thumbSrc;
                    };
                    blurImg.onerror = function() {
                        // blur 失败，直接尝试 fallback
                        if (fallbackSrc) {
                            img.src = fallbackSrc;
                        }
                        img.classList.add("loaded");
                        img.dataset.loaded = '1';
                        var spinner = img.parentElement.querySelector(".loading-spinner");
                        if (spinner) spinner.style.display = "none";
                    };
                    blurImg.src = blurSrc;
                } else if (!blurSrc) {
                    // 无 blur，直接加载高清
                    var highImg = new Image();
                    highImg.onload = function() {
                        img.src = thumbSrc;
                        img.classList.add("loaded");
                        img.dataset.loaded = '1';
                    };
                    highImg.onerror = function() {
                        if (fallbackSrc) img.src = fallbackSrc;
                        img.classList.add("loaded");
                        img.dataset.loaded = '1';
                    };
                    highImg.src = thumbSrc;
                }

                obs.unobserve(img);
            });
        }, {
            rootMargin: "400px 0px"
        });

        lazyImages.forEach(function(img) {
            observer.observe(img);
        });
    }
});
</script>

</body>
</html>
