<?php

require_once __DIR__ . '/common.php';

admin_require_login();

$pdo       = db();
$adminUser = admin_current_user();
$siteTitle = get_setting('site.title', '六柱博客');

$errors = [];
$infos  = [];

$type = isset($_GET['type']) ? trim((string)$_GET['type']) : 'all';
$allowedTypes = ['all', 'image', 'attachment', 'video'];
if (!in_array($type, $allowedTypes, true)) {
    $type = 'all';
}

$q = isset($_GET['q']) ? trim((string)$_GET['q']) : '';

$perPage = 50;
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
if ($page < 1) {
    $page = 1;
}

function format_bytes(int $bytes): string
{
    if ($bytes <= 0) return '0 B';
    $units = ['B','KB','MB','GB'];
    $i = 0;
    $value = $bytes;
    while ($value >= 1024 && $i < count($units) - 1) {
        $value /= 1024;
        $i++;
    }
    return sprintf($value >= 10 ? '%.0f %s' : '%.1f %s', $value, $units[$i]);
}

function is_safe_media_path(string $path): bool
{
    $path = trim($path);
    if ($path === '') return false;
    if (strpos($path, '/uploads/') === 0 || strpos($path, 'uploads/') === 0) {
        return true;
    }
    return false;
}

function ensure_media_files_table(PDO $pdo): void
{
    try {
        $stmt = $pdo->query("SELECT name FROM sqlite_master WHERE type='table' AND name='media_files' LIMIT 1");
        $exists = $stmt && $stmt->fetchColumn();
        if ($exists) {
            return;
        }
        $pdo->exec("
            CREATE TABLE IF NOT EXISTS media_files (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                type TEXT NOT NULL,
                path TEXT NOT NULL,
                original_name TEXT,
                size INTEGER NOT NULL DEFAULT 0,
                mime TEXT,
                uploader_id INTEGER,
                created_at INTEGER NOT NULL
            );
        ");
        $pdo->exec("CREATE INDEX IF NOT EXISTS idx_media_files_type ON media_files(type);");
        $pdo->exec("CREATE INDEX IF NOT EXISTS idx_media_files_created_at ON media_files(created_at);");
    } catch (Throwable $e) {
        
    }
}

function ensure_media_ignored_table(PDO $pdo): void
{
    try {
        $stmt = $pdo->query("SELECT name FROM sqlite_master WHERE type='table' AND name='media_files_ignored' LIMIT 1");
        $exists = $stmt && $stmt->fetchColumn();
        if ($exists) {
            return;
        }
        $pdo->exec("
            CREATE TABLE IF NOT EXISTS media_files_ignored (
                path TEXT PRIMARY KEY,
                created_at INTEGER NOT NULL
            );
        ");
    } catch (Throwable $e) {
        
    }
}

function guess_mime_by_ext(string $ext, string $type): string
{
    $ext = strtolower($ext);
    if ($type === 'image') {
        $map = ['jpg' => 'image/jpeg', 'jpeg' => 'image/jpeg', 'png' => 'image/png', 'gif' => 'image/gif', 'webp' => 'image/webp'];
        return $map[$ext] ?? 'image/*';
    }
    if ($type === 'video') {
        $map = ['mp4' => 'video/mp4', 'webm' => 'video/webm', 'ogg' => 'video/ogg'];
        return $map[$ext] ?? 'video/*';
    }
    $map = [
        'pdf' => 'application/pdf',
        'doc' => 'application/msword',
        'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
        'xls' => 'application/vnd.ms-excel',
        'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
        'ppt' => 'application/vnd.ms-powerpoint',
        'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
        'txt' => 'text/plain',
        'md' => 'text/markdown',
        'zip' => 'application/zip',
        'rar' => 'application/vnd.rar',
        '7z' => 'application/x-7z-compressed',
    ];
    return $map[$ext] ?? 'application/octet-stream';
}

function sync_media_from_uploads(PDO $pdo): int
{
    $targets = [
        ['type' => 'image', 'subdir' => 'editor_images'],
        ['type' => 'image', 'subdir' => 'article_icons'],
        ['type' => 'attachment', 'subdir' => 'attachments'],
        ['type' => 'video', 'subdir' => 'videos'],
    ];

    $existing = [];
    $ignored = [];
    try {
        $stmt = $pdo->query("SELECT path FROM media_files WHERE path LIKE '/uploads/%'");
        $rows = $stmt ? $stmt->fetchAll(PDO::FETCH_COLUMN, 0) : [];
        if ($rows) {
            foreach ($rows as $p) {
                $existing[(string)$p] = true;
            }
        }
    } catch (Throwable $e) {
        
    }
    try {
        $stmt = $pdo->query("SELECT path FROM media_files_ignored");
        $rows = $stmt ? $stmt->fetchAll(PDO::FETCH_COLUMN, 0) : [];
        if ($rows) {
            foreach ($rows as $p) {
                $ignored[(string)$p] = true;
            }
        }
    } catch (Throwable $e) {
        
    }

    $inserted = 0;
    $insert = $pdo->prepare("
        INSERT INTO media_files (type, path, original_name, size, mime, uploader_id, created_at)
        VALUES (:type, :path, :original_name, :size, :mime, :uploader_id, :created_at)
    ");

    foreach ($targets as $t) {
        $type = $t['type'];
        $subdir = $t['subdir'];
        $dir = BASE_PATH . DIRECTORY_SEPARATOR . 'uploads' . DIRECTORY_SEPARATOR . $subdir;
        if (!is_dir($dir)) {
            continue;
        }
        try {
            $it = new DirectoryIterator($dir);
            foreach ($it as $fileinfo) {
                if ($fileinfo->isDot() || !$fileinfo->isFile()) {
                    continue;
                }
                $filename = $fileinfo->getFilename();
                if ($filename === '') {
                    continue;
                }
                $rel = 'uploads/' . $subdir . '/' . $filename;
                $url = '/' . str_replace('\\', '/', $rel);
                if (isset($existing[$url]) || isset($ignored[$url])) {
                    continue;
                }
                $size = (int)$fileinfo->getSize();
                $mtime = (int)$fileinfo->getMTime();
                $ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
                $mime = '';
                if (function_exists('finfo_open')) {
                    $finfo = @finfo_open(FILEINFO_MIME_TYPE);
                    if ($finfo) {
                        $mime = (string)@finfo_file($finfo, $fileinfo->getPathname());
                        @finfo_close($finfo);
                    }
                }
                if ($mime === '' || $mime === 'application/octet-stream') {
                    $mime = guess_mime_by_ext($ext, $type);
                }
                try {
                    $insert->execute([
                        ':type' => $type,
                        ':path' => $url,
                        ':original_name' => $filename,
                        ':size' => $size,
                        ':mime' => $mime,
                        ':uploader_id' => null,
                        ':created_at' => $mtime > 0 ? $mtime : time(),
                    ]);
                    $existing[$url] = true;
                    $inserted++;
                } catch (Throwable $e) {
                    
                }
            }
        } catch (Throwable $e) {
            
        }
    }

    return $inserted;
}

ensure_media_files_table($pdo);
ensure_media_ignored_table($pdo);

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if (!admin_csrf_check($_POST['csrf_token'] ?? null)) {
        $errors[] = '请求已失效，请刷新页面后重试。';
    } else {
        $action = trim((string)($_POST['action'] ?? ''));
        $deleteId = (int)($_POST['delete_id'] ?? 0);
        $ids = [];
        if ($deleteId > 0) {
            $ids[] = $deleteId;
        } elseif ($action === 'delete_selected') {
            $raw = $_POST['ids'] ?? [];
            if (is_array($raw)) {
                foreach ($raw as $rid) {
                    $id = (int)$rid;
                    if ($id > 0) $ids[] = $id;
                }
            }
        }

        if ($ids) {
            try {
                $placeholders = implode(',', array_fill(0, count($ids), '?'));
                $stmt = $pdo->prepare("SELECT id, path FROM media_files WHERE id IN ($placeholders)");
                $stmt->execute($ids);
                $rows = $stmt->fetchAll() ?: [];

                $deleted = 0;
                $deleteFailed = 0;
                ensure_media_ignored_table($pdo);
                $stmtIgnore = $pdo->prepare("INSERT OR IGNORE INTO media_files_ignored (path, created_at) VALUES (:path, :created_at)");
                foreach ($rows as $row) {
                    $path = (string)($row['path'] ?? '');
                    if ($path !== '') {
                        try {
                            $stmtIgnore->execute([
                                ':path' => $path,
                                ':created_at' => time(),
                            ]);
                        } catch (Throwable $e) {
                            
                        }
                    }
                    if ($path !== '' && is_safe_media_path($path)) {
                        $fsPath = BASE_PATH . DIRECTORY_SEPARATOR . ltrim($path, '/\\');
                        if (is_file($fsPath)) {
                            if (!@unlink($fsPath)) {
                                $deleteFailed++;
                            }
                        }
                    }
                }

                $stmt = $pdo->prepare("DELETE FROM media_files WHERE id IN ($placeholders)");
                $stmt->execute($ids);
                $deleted = $stmt->rowCount();

                if ($deleted > 0) {
                    $infos[] = '已删除 ' . $deleted . ' 个文件。';
                    admin_log('media_delete', '删除媒体文件数量=' . $deleted);
                    if ($deleteFailed > 0) {
                        $errors[] = '有 ' . $deleteFailed . ' 个文件未能从磁盘删除（可能权限不足），已从列表移除。';
                    }
                } else {
                    $errors[] = '未找到要删除的文件。';
                }
            } catch (Throwable $e) {
                $errors[] = '删除失败：' . $e->getMessage();
            }
        } else {
            $errors[] = '未选择任何文件。';
        }
    }
}

$synced = 0;
ensure_media_files_table($pdo);
ensure_media_ignored_table($pdo);
try {
    $synced = sync_media_from_uploads($pdo);
    if ($synced > 0) {
        $infos[] = '已从上传目录同步 ' . $synced . ' 个文件。';
    }
} catch (Throwable $e) {
    
}

$debugInfo = null;
if (isset($_GET['debug']) && (string)$_GET['debug'] === '1') {
    $debugInfo = [
        'script' => __FILE__,
        'base_path' => defined('BASE_PATH') ? BASE_PATH : '',
        'db_path' => defined('DB_PATH') ? DB_PATH : '',
        'type' => $type,
        'q' => $q,
        'page' => $page,
        'media_count' => 0,
        'items_count' => 0,
        'total' => 0,
        'total_pages' => 0,
        'where_sql' => '',
        'params' => '',
        'dir_images' => '',
        'dir_images_exists' => 'no',
        'dir_images_count' => 0,
        'dir_article_icons' => '',
        'dir_article_icons_exists' => 'no',
        'dir_article_icons_count' => 0,
        'dir_attachments' => '',
        'dir_attachments_exists' => 'no',
        'dir_attachments_count' => 0,
        'dir_videos' => '',
        'dir_videos_exists' => 'no',
        'dir_videos_count' => 0,
    ];

    try {
        $debugInfo['media_count'] = (int)$pdo->query("SELECT COUNT(*) FROM media_files")->fetchColumn();
    } catch (Throwable $e) {
        $debugInfo['media_count'] = -1;
    }

    $dirImages = BASE_PATH . DIRECTORY_SEPARATOR . 'uploads' . DIRECTORY_SEPARATOR . 'editor_images';
    $dirArticleIcons = BASE_PATH . DIRECTORY_SEPARATOR . 'uploads' . DIRECTORY_SEPARATOR . 'article_icons';
    $dirAttachments = BASE_PATH . DIRECTORY_SEPARATOR . 'uploads' . DIRECTORY_SEPARATOR . 'attachments';
    $dirVideos = BASE_PATH . DIRECTORY_SEPARATOR . 'uploads' . DIRECTORY_SEPARATOR . 'videos';
    $debugInfo['dir_images'] = $dirImages;
    $debugInfo['dir_article_icons'] = $dirArticleIcons;
    $debugInfo['dir_attachments'] = $dirAttachments;
    $debugInfo['dir_videos'] = $dirVideos;

    if (is_dir($dirImages)) {
        $debugInfo['dir_images_exists'] = 'yes';
        try {
            $debugInfo['dir_images_count'] = iterator_count(new FilesystemIterator($dirImages, FilesystemIterator::SKIP_DOTS));
        } catch (Throwable $e) {
            $debugInfo['dir_images_count'] = -1;
        }
    }
    if (is_dir($dirArticleIcons)) {
        $debugInfo['dir_article_icons_exists'] = 'yes';
        try {
            $debugInfo['dir_article_icons_count'] = iterator_count(new FilesystemIterator($dirArticleIcons, FilesystemIterator::SKIP_DOTS));
        } catch (Throwable $e) {
            $debugInfo['dir_article_icons_count'] = -1;
        }
    }
    if (is_dir($dirAttachments)) {
        $debugInfo['dir_attachments_exists'] = 'yes';
        try {
            $debugInfo['dir_attachments_count'] = iterator_count(new FilesystemIterator($dirAttachments, FilesystemIterator::SKIP_DOTS));
        } catch (Throwable $e) {
            $debugInfo['dir_attachments_count'] = -1;
        }
    }
    if (is_dir($dirVideos)) {
        $debugInfo['dir_videos_exists'] = 'yes';
        try {
            $debugInfo['dir_videos_count'] = iterator_count(new FilesystemIterator($dirVideos, FilesystemIterator::SKIP_DOTS));
        } catch (Throwable $e) {
            $debugInfo['dir_videos_count'] = -1;
        }
    }
}

$where = [];
$params = [];
if ($type !== 'all') {
    $where[] = 'm.type = :type';
    $params[':type'] = $type;
}
if ($q !== '') {
    $where[] = '(m.original_name LIKE :kw OR m.path LIKE :kw)';
    $params[':kw'] = '%' . $q . '%';
}
$whereSql = $where ? ('WHERE ' . implode(' AND ', $where)) : '';

$total = 0;
$totalPages = 1;
$items = [];
try {
    $stmt = $pdo->prepare("SELECT COUNT(*) FROM media_files m $whereSql");
    $stmt->execute($params);
    $total = (int)$stmt->fetchColumn();
    $totalPages = max(1, (int)ceil($total / $perPage));
    if ($page > $totalPages) {
        $page = $totalPages;
    }
    $offset = ($page - 1) * $perPage;
    $limit = max(1, (int)$perPage);
    $offset = max(0, (int)$offset);
    $sql = "
        SELECT m.*, u.nickname AS uploader_name, u.email AS uploader_email
        FROM media_files m
        LEFT JOIN users u ON u.id = m.uploader_id
        $whereSql
        ORDER BY m.created_at DESC, m.id DESC
        LIMIT $limit OFFSET $offset
    ";
    $stmt = $pdo->prepare($sql);
    foreach ($params as $k => $v) {
        $stmt->bindValue($k, $v, PDO::PARAM_STR);
    }
    $stmt->execute();
    $items = $stmt->fetchAll() ?: [];
} catch (Throwable $e) {
    $items = [];
    if ($debugInfo) {
        $debugInfo['items_error'] = $e->getMessage();
    }
}

if ($debugInfo) {
    $debugInfo['items_count'] = is_array($items) ? count($items) : -1;
    $debugInfo['total'] = $total;
    $debugInfo['total_pages'] = $totalPages;
    $debugInfo['where_sql'] = $whereSql;
    $debugInfo['params'] = $params ? json_encode($params, JSON_UNESCAPED_UNICODE) : '';
}

function build_query(array $extra = []): string
{
    $base = [];
    $type = isset($_GET['type']) ? trim((string)$_GET['type']) : 'all';
    $q = isset($_GET['q']) ? trim((string)$_GET['q']) : '';
    if ($type && $type !== 'all') $base['type'] = $type;
    if ($q !== '') $base['q'] = $q;
    $base = array_merge($base, $extra);
    foreach ($base as $k => $v) {
        if ($v === null || $v === '') {
            unset($base[$k]);
        }
    }
    return $base ? ('?' . http_build_query($base)) : '';
}

?><!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>文件 - <?php echo h($siteTitle); ?></title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <style>
        html, body { height:100%;  margin:0; padding:0; }
        body { margin:0; padding:0; font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",system-ui,sans-serif; background:#020617; color:#e5e7eb; }
        a { color:#60a5fa; text-decoration:none; }
        a:hover { text-decoration:underline; }
        .topbar { background:#0f172a; border-bottom:1px solid #1f2937; padding:18px 16px 6px; display:flex; align-items:flex-start; justify-content:space-between;  margin:0;  margin-top:-12px; }
        .topbar-title { font-size:16px; font-weight:600; }
        .topbar-user { font-size:13px; color:#9ca3af; }
        .topbar-nav a { margin-left:10px; font-size:13px; }
        .page { max-width:1200px; margin:0 auto; padding:16px; }
        .card { background:#020617; border-radius:6px; border:1px solid #1f2937; padding:12px 14px; }
        .card-title { font-size:14px; font-weight:600; margin-bottom:8px; }
        .filters { display:flex; align-items:center; gap:10px; flex-wrap:wrap; margin-bottom:10px; }
        .filters a { padding:4px 8px; border-radius:999px; border:1px solid #1f2937; font-size:12px; }
        .filters a.active { background:#1d4ed8; border-color:#3b82f6; color:#e5e7eb; }
        .search-box { display:flex; gap:6px; align-items:center; }
        .search-box input { padding:4px 6px; border-radius:4px; border:1px solid #374151; background:#020617; color:#e5e7eb; font-size:12px; }
        .upload-box { display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin-bottom:10px; }
        .upload-box input[type="file"] { font-size:12px; color:#e5e7eb; }
        .upload-box select { padding:4px 6px; border-radius:4px; border:1px solid #374151; background:#020617; color:#e5e7eb; font-size:12px; }
        .upload-hint { font-size:12px; color:#9ca3af; }
        .btn { border-radius:999px; border:1px solid #3b82f6; background:#1d4ed8; color:#e5e7eb; font-size:12px; padding:4px 10px; cursor:pointer; }
        table { width:100%; border-collapse:collapse; font-size:13px; }
        th, td { border-bottom:1px solid #1f2937; padding:6px 4px; text-align:left; vertical-align:middle; }
        th { color:#9ca3af; font-weight:500; }
        .small-text { font-size:12px; color:#9ca3af; }
        .errors { background:#7f1d1d; border:1px solid #fecaca; color:#fee2e2; padding:6px 8px; border-radius:4px; font-size:12px; margin-bottom:10px; }
        .success { background:#14532d; border:1px solid #22c55e; color:#bbf7d0; padding:6px 8px; border-radius:4px; font-size:12px; margin-bottom:10px; }
        .preview-img { width:40px; height:40px; object-fit:cover; border-radius:4px; border:1px solid #1f2937; }
        .type-badge { font-size:11px; padding:2px 6px; border-radius:999px; background:#111827; color:#e5e7eb; }
        .pagination { display:flex; flex-wrap:wrap; gap:6px; margin-top:10px; }
        .pagination a, .pagination span { border:1px solid #1f2937; border-radius:999px; padding:3px 8px; font-size:12px; }
        .pagination .active { background:#1d4ed8; color:#e5e7eb; border-color:#3b82f6; }
        .pagination .disabled { color:#9ca3af; }
        .btn-link { background:transparent; border:none; color:#60a5fa; cursor:pointer; padding:0; font-size:13px; }
    </style>
</head>
<body style="margin:0;padding:0;"><div class="topbar">
        <div class="topbar-title">文件</div>
        <div class="topbar-user">
            管理员：<?php echo h($adminUser['nickname'] ?? $adminUser['email'] ?? ''); ?>
            <span class="topbar-nav">
                <a href="index.php">仪表盘</a>
                <a href="articles.php">文章</a>
                <a href="categories.php">分类</a>
                <a href="tags.php">&#26631;&#31614;</a>
                <a href="comments.php">评论</a>
                <a href="links.php">友链</a>
                <a href="media.php">文件</a>
                <a href="users.php">会员</a>
                <a href="sensitive_words.php">敏感词</a>
                <a href="stats.php">流量</a>
                <a href="security.php">防护</a>
                <a href="logs.php">日志</a>
                <a href="settings.php">设置</a>
                <a href="backup_sqlite.php">&#25968;&#25454;</a>
                <a href="../index.php">前台</a>
                <a href="../logout.php">退出</a>
            </span>
        </div>
    </div>

    <div class="page">
        <?php if ($debugInfo): ?>
            <div class="card" style="margin-bottom:10px;">
                <div class="card-title">调试信息</div>
                <div class="small-text">script: <?php echo h($debugInfo['script']); ?></div>
                <div class="small-text">base_path: <?php echo h($debugInfo['base_path']); ?></div>
                <div class="small-text">db_path: <?php echo h($debugInfo['db_path']); ?></div>
                <div class="small-text">type: <?php echo h((string)$debugInfo['type']); ?></div>
                <div class="small-text">q: <?php echo h((string)$debugInfo['q']); ?></div>
                <div class="small-text">page: <?php echo h((string)$debugInfo['page']); ?></div>
                <div class="small-text">media_count: <?php echo h((string)$debugInfo['media_count']); ?></div>
                <div class="small-text">items_count: <?php echo h((string)$debugInfo['items_count']); ?></div>
                <div class="small-text">total: <?php echo h((string)$debugInfo['total']); ?></div>
                <div class="small-text">total_pages: <?php echo h((string)$debugInfo['total_pages']); ?></div>
                <div class="small-text">where_sql: <?php echo h((string)$debugInfo['where_sql']); ?></div>
                <div class="small-text">params: <?php echo h((string)$debugInfo['params']); ?></div>
                <?php if (!empty($debugInfo['items_error'])): ?>
                    <div class="small-text">items_error: <?php echo h((string)$debugInfo['items_error']); ?></div>
                <?php endif; ?>
                <div class="small-text">images_dir: <?php echo h($debugInfo['dir_images']); ?> (<?php echo h($debugInfo['dir_images_exists']); ?> / <?php echo h((string)$debugInfo['dir_images_count']); ?>)</div>
                <div class="small-text">article_icons_dir: <?php echo h($debugInfo['dir_article_icons']); ?> (<?php echo h($debugInfo['dir_article_icons_exists']); ?> / <?php echo h((string)$debugInfo['dir_article_icons_count']); ?>)</div>
                <div class="small-text">attachments_dir: <?php echo h($debugInfo['dir_attachments']); ?> (<?php echo h($debugInfo['dir_attachments_exists']); ?> / <?php echo h((string)$debugInfo['dir_attachments_count']); ?>)</div>
                <div class="small-text">videos_dir: <?php echo h($debugInfo['dir_videos']); ?> (<?php echo h($debugInfo['dir_videos_exists']); ?> / <?php echo h((string)$debugInfo['dir_videos_count']); ?>)</div>
            </div>
        <?php endif; ?>
        <?php if ($errors): ?>
            <div class="errors">
                <?php foreach ($errors as $err): ?>
                    <div><?php echo h($err); ?></div>
                <?php endforeach; ?>
            </div>
        <?php endif; ?>
        <?php if ($infos): ?>
            <div class="success">
                <?php foreach ($infos as $msg): ?>
                    <div><?php echo h($msg); ?></div>
                <?php endforeach; ?>
            </div>
        <?php endif; ?>

        <div class="card">
            <div class="card-title">上传文件列表</div>

            <form id="media-upload-form" class="upload-box" action="#" method="post" enctype="multipart/form-data">
                <input type="hidden" name="csrf_token" value="<?php echo h(csrf_token()); ?>">
                <input type="file" id="media-upload-file" name="file" required>
                <select id="media-upload-type" name="upload_type">
                    <option value="image" <?php echo $type === 'image' ? 'selected' : ''; ?>>图片</option>
                    <option value="attachment" <?php echo $type === 'attachment' ? 'selected' : ''; ?>>附件</option>
                    <option value="video" <?php echo $type === 'video' ? 'selected' : ''; ?>>视频</option>
                </select>
                <button class="btn" type="submit">上传</button>
                <span class="upload-hint" id="media-upload-hint"></span>
                <span class="upload-hint" id="media-upload-tip"></span>
            </form>

            <div class="filters">
                <?php
                $tabs = [
                    'all' => '全部',
                    'image' => '图片',
                    'attachment' => '附件',
                    'video' => '视频',
                ];
                foreach ($tabs as $k => $label) {
                    $link = build_query(['type' => $k === 'all' ? null : $k, 'page' => null]);
                    $active = ($type === $k) ? 'active' : '';
                    echo '<a class="' . $active . '" href="media.php' . h($link) . '">' . h($label) . '</a>';
                }
                ?>
                <form class="search-box" method="get" action="media.php">
                    <?php if ($type !== 'all'): ?><input type="hidden" name="type" value="<?php echo h($type); ?>"><?php endif; ?>
                    <input type="text" name="q" value="<?php echo h($q); ?>" placeholder="搜索文件名">
                    <button class="btn" type="submit">搜索</button>
                </form>
            </div>

            <form method="post" action="media.php<?php echo h(build_query(['page' => $page])); ?>">
                <input type="hidden" name="csrf_token" value="<?php echo h(admin_csrf_token()); ?>">

                <?php if ($items): ?>
                    <div class="small-text" style="margin-bottom:6px;">共 <?php echo (int)$total; ?> 个文件</div>
                    <table>
                        <thead>
                            <tr>
                                <th style="width:30px;"><input type="checkbox" id="check-all"></th>
                                <th>预览</th>
                                <th>文件名</th>
                                <th>类型</th>
                                <th>大小</th>
                                <th>上传者</th>
                                <th>上传时间</th>
                                <th>链接</th>
                                <th>操作</th>
                            </tr>
                        </thead>
                        <tbody>
                            <?php foreach ($items as $it): ?>
                                <?php
                                $path = (string)($it['path'] ?? '');
                                $orig = (string)($it['original_name'] ?? '');
                                $typeLabel = (string)($it['type'] ?? '');
                                $typeMap = ['image' => '图片', 'attachment' => '附件', 'video' => '视频'];
                                $typeText = $typeMap[$typeLabel] ?? $typeLabel;
                                $uploader = (string)($it['uploader_name'] ?? $it['uploader_email'] ?? '');
                                if ($uploader === '') $uploader = '未知';
                                ?>
                                <tr>
                                    <td><input type="checkbox" name="ids[]" value="<?php echo (int)$it['id']; ?>"></td>
                                    <td>
                                        <?php if ($typeLabel === 'image' && $path !== ''): ?>
                                            <img class="preview-img" src="<?php echo h($path); ?>" alt="">
                                        <?php else: ?>
                                            <span class="small-text">—</span>
                                        <?php endif; ?>
                                    </td>
                                    <td><?php echo h($orig !== '' ? $orig : $path); ?></td>
                                    <td><span class="type-badge"><?php echo h($typeText); ?></span></td>
                                    <td><?php echo h(format_bytes((int)($it['size'] ?? 0))); ?></td>
                                    <td><?php echo h($uploader); ?></td>
                                    <td><?php echo !empty($it['created_at']) ? date('Y-m-d H:i', (int)$it['created_at']) : '-'; ?></td>
                                    <td>
                                        <?php if ($path !== ''): ?>
                                            <a href="<?php echo h($path); ?>" target="_blank">打开</a>
                                        <?php else: ?>
                                            -
                                        <?php endif; ?>
                                    </td>
                                    <td>
                                        <button type="submit" class="btn-link" name="delete_id" value="<?php echo (int)$it['id']; ?>" onclick="return confirm('确定删除该文件？')">删除</button>
                                    </td>
                                </tr>
                            <?php endforeach; ?>
                        </tbody>
                    </table>

                    <div style="margin-top:8px;">
                        <button type="submit" class="btn" name="action" value="delete_selected" onclick="return confirm('确定删除选中文件？')">删除选中</button>
                    </div>

                    <?php if ($totalPages > 1): ?>
                        <div class="pagination">
                            <?php
                            $base = 'media.php' . build_query(['page' => null]);
                            $base .= (strpos($base, '?') !== false ? '&page=' : '?page=');
                            $range = 2;
                            $start = max(1, $page - $range);
                            $end = min($totalPages, $page + $range);
                            ?>
                            <?php if ($page > 1): ?>
                                <a href="<?php echo h($base . ($page - 1)); ?>">上一页</a>
                            <?php else: ?>
                                <span class="disabled">上一页</span>
                            <?php endif; ?>
                            <?php if ($start > 1): ?>
                                <a href="<?php echo h($base . '1'); ?>">1</a>
                                <?php if ($start > 2): ?><span class="disabled">...</span><?php endif; ?>
                            <?php endif; ?>
                            <?php for ($i = $start; $i <= $end; $i++): ?>
                                <?php if ($i === $page): ?>
                                    <span class="active"><?php echo $i; ?></span>
                                <?php else: ?>
                                    <a href="<?php echo h($base . $i); ?>"><?php echo $i; ?></a>
                                <?php endif; ?>
                            <?php endfor; ?>
                            <?php if ($end < $totalPages): ?>
                                <?php if ($end < $totalPages - 1): ?><span class="disabled">...</span><?php endif; ?>
                                <a href="<?php echo h($base . $totalPages); ?>"><?php echo $totalPages; ?></a>
                            <?php endif; ?>
                            <?php if ($page < $totalPages): ?>
                                <a href="<?php echo h($base . ($page + 1)); ?>">下一页</a>
                            <?php else: ?>
                                <span class="disabled">下一页</span>
                            <?php endif; ?>
                        </div>
                    <?php endif; ?>
                <?php else: ?>
                    <p class="small-text">暂无上传文件。</p>
                <?php endif; ?>
            </form>
        </div>
    </div>

    <script>
        (function () {
            var checkAll = document.getElementById('check-all');
            if (!checkAll) return;
            checkAll.addEventListener('change', function () {
                var boxes = document.querySelectorAll('input[name="ids[]"]');
                boxes.forEach(function (b) { b.checked = checkAll.checked; });
            });
        })();

        (function () {
            var form = document.getElementById('media-upload-form');
            if (!form) return;
            var fileInput = document.getElementById('media-upload-file');
            var typeSelect = document.getElementById('media-upload-type');
            var hint = document.getElementById('media-upload-hint');
            var tip = document.getElementById('media-upload-tip');

            function updateAccept() {
                var type = typeSelect.value;
                var accept = '';
                var hintText = '';
                if (type === 'image') {
                    accept = 'image/*';
                    hintText = '图片 ≤ 2MB，JPG/PNG/GIF/WEBP';
                } else if (type === 'video') {
                    accept = 'video/*';
                    hintText = '视频 ≤ 50MB，MP4/WEBM/OGG';
                } else {
                    accept = '.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.txt,.md,.zip,.rar,.7z';
                    hintText = '附件 ≤ 10MB，PDF/DOC/XLS/PPT/TXT/MD/ZIP/RAR/7Z';
                }
                fileInput.setAttribute('accept', accept);
                if (hint) hint.textContent = hintText;
            }

            typeSelect.addEventListener('change', updateAccept);
            updateAccept();

            form.addEventListener('submit', function (e) {
                e.preventDefault();
                if (!fileInput.files || !fileInput.files[0]) {
                    if (tip) tip.textContent = '请选择文件';
                    return;
                }
                var type = typeSelect.value;
                var url = type === 'image'
                    ? '../upload_image.php'
                    : (type === 'video' ? '../upload_video.php' : '../upload_file.php');

                var fd = new FormData();
                fd.append('file', fileInput.files[0]);
                var tokenInput = form.querySelector('input[name="csrf_token"]');
                if (tokenInput) fd.append('csrf_token', tokenInput.value);

                if (tip) tip.textContent = '上传中...';
                fetch(url, { method: 'POST', body: fd })
                    .then(function (res) { return res.json(); })
                    .then(function (data) {
                        if (data && data.errno === 0) {
                            if (tip) tip.textContent = '上传成功';
                            setTimeout(function () {
                                location.href = 'media.php?type=' + encodeURIComponent(type);
                            }, 300);
                        } else {
                            var msg = (data && data.message) ? data.message : '上传失败';
                            if (tip) tip.textContent = msg;
                        }
                    })
                    .catch(function () {
                        if (tip) tip.textContent = '上传失败';
                    });
            });
        })();
    </script>
</body>
</html>
