<?php
declare(strict_types=1);

$lockFile = dirname(__DIR__) . DIRECTORY_SEPARATOR . 'install' . DIRECTORY_SEPARATOR . 'install.lock';
if (!is_file($lockFile)) {
    header('Location: ../install/', true, 302);
    exit;
}
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>香橙个人网盘系统</title>
    <script src="../assets/vendor/tailwind/tailwindcss-3.4.17.js"></script>
    <link rel="stylesheet" href="../assets/vendor/remixicon/remixicon.css">
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        /* 自定义滚动条 */
        ::-webkit-scrollbar {
            width: 6px;
            height: 6px;
        }
        ::-webkit-scrollbar-track {
            background: #f1f1f1;
            border-radius: 3px;
        }
        ::-webkit-scrollbar-thumb {
            background: #c1c1c1;
            border-radius: 3px;
        }
        ::-webkit-scrollbar-thumb:hover {
            background: #a1a1a1;
        }

        /* 动画过渡 */
        .fade-in {
            animation: fadeIn 0.2s ease-out;
        }
        @keyframes fadeIn {
            from { opacity: 0; transform: translateY(-4px); }
            to { opacity: 1; transform: translateY(0); }
        }

        .slide-in {
            animation: slideIn 0.2s ease-out;
        }
        @keyframes slideIn {
            from { opacity: 0; transform: scale(0.95); }
            to { opacity: 1; transform: scale(1); }
        }

        /* 选中状态 */
        .file-item.selected {
            background-color: #eff6ff !important;
        }

        .file-row:hover {
            background-color: #f9fafb;
        }

        #file-list,
        .file-item,
        .file-item * {
            -webkit-user-select: none;
            -moz-user-select: none;
            user-select: none;
        }

        /* 右键菜单 */
        .context-menu {
            position: fixed;
            z-index: 1000;
            min-width: 160px;
        }

        /* 拖拽上传 */
        .drop-zone.drag-over {
            background-color: #eff6ff;
            border: 2px dashed #3b82f6;
        }

        .upload-zone.drag-over {
            border-color: #3b82f6;
            background-color: #eff6ff;
        }

        button:not(:disabled),
        button:not(:disabled) *,
        .file-item,
        .file-item *,
        .folder-item,
        .folder-item *,
        .upload-zone,
        .upload-zone *,
        #nav-all,
        #nav-all *,
        #nav-recent,
        #nav-recent *,
        input[type="checkbox"],
        select {
            cursor: pointer;
        }

        button:disabled,
        button:disabled * {
            cursor: not-allowed;
        }

        /* Toast 提示 */
        .toast {
            animation: toastIn 0.3s ease-out;
        }
        @keyframes toastIn {
            from { opacity: 0; transform: translateY(20px); }
            to { opacity: 1; transform: translateY(0); }
        }
    </style>
</head>
<body class="bg-gray-50 min-h-screen md:h-screen flex flex-col md:overflow-hidden">
    <!-- Toast 容器 -->
    <div id="toast-container" class="fixed bottom-6 right-6 z-50 space-y-2"></div>

    <!-- 右键菜单 -->
    <div id="context-menu" class="context-menu hidden bg-white rounded-lg shadow-xl border border-gray-200 py-2 slide-in">
        <button onclick="handleContextAction('open')" class="w-full px-4 py-2 text-left hover:bg-gray-50 flex items-center gap-2 text-sm">
            <i class="ri-folder-open-line"></i> 打开
        </button>
        <button onclick="handleContextAction('download')" class="w-full px-4 py-2 text-left hover:bg-gray-50 flex items-center gap-2 text-sm">
            <i class="ri-download-line"></i> 下载
        </button>
        <button onclick="handleContextAction('rename')" class="w-full px-4 py-2 text-left hover:bg-gray-50 flex items-center gap-2 text-sm">
            <i class="ri-edit-line"></i> 重命名
        </button>
        <div class="border-t border-gray-100 my-1"></div>
        <button onclick="handleContextAction('delete')" class="w-full px-4 py-2 text-left hover:bg-red-50 text-red-500 flex items-center gap-2 text-sm">
            <i class="ri-delete-bin-line"></i> 删除
        </button>
    </div>

    <!-- 新建文件夹弹窗 -->
    <div id="new-folder-modal" class="fixed inset-0 bg-black/50 z-50 hidden items-center justify-center p-4">
        <div class="bg-white rounded-xl shadow-2xl p-6 w-full max-w-sm fade-in">
            <h3 class="text-lg font-semibold mb-4">新建文件夹</h3>
            <input type="text" id="new-folder-name" placeholder="输入文件夹名称" 
                   class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 mb-4">
            <div class="flex justify-end gap-3">
                <button onclick="closeModal('new-folder-modal')" class="px-4 py-2 text-gray-600 hover:bg-gray-100 rounded-lg">取消</button>
                <button onclick="createNewFolder()" class="px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600">创建</button>
            </div>
        </div>
    </div>

    <!-- 重命名弹窗 -->
    <div id="rename-modal" class="fixed inset-0 bg-black/50 z-50 hidden items-center justify-center p-4">
        <div class="bg-white rounded-xl shadow-2xl p-6 w-full max-w-sm fade-in">
            <h3 class="text-lg font-semibold mb-4">重命名</h3>
            <input type="text" id="rename-input" placeholder="输入新名称" 
                   class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 mb-4">
            <div class="flex justify-end gap-3">
                <button onclick="closeModal('rename-modal')" class="px-4 py-2 text-gray-600 hover:bg-gray-100 rounded-lg">取消</button>
                <button onclick="confirmRename()" class="px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600">确定</button>
            </div>
        </div>
    </div>

    <!-- 上传弹窗 -->
    <div id="upload-modal" class="fixed inset-0 bg-black/50 z-50 hidden items-center justify-center p-4">
        <div class="bg-white rounded-xl shadow-2xl w-full max-w-lg max-h-[90vh] overflow-y-auto fade-in">
            <div class="px-6 py-4 border-b border-gray-100 flex items-center justify-between">
                <h3 class="text-lg font-semibold text-gray-800">上传文件</h3>
                <button onclick="closeUploadModal()" class="p-2 hover:bg-gray-100 rounded-lg transition-colors" type="button">
                    <i class="ri-close-line text-gray-500 text-xl"></i>
                </button>
            </div>
            <div class="p-6">
                <div id="upload-zone" class="upload-zone border-2 border-dashed border-gray-300 rounded-xl p-8 text-center cursor-pointer hover:border-blue-500 transition-colors">
                    <i class="ri-upload-cloud-2-line text-5xl text-gray-400 mb-4"></i>
                    <p class="text-gray-600 mb-2">拖拽文件到此处上传</p>
                    <p class="text-sm text-gray-400 mb-4">或点击选择文件</p>
                    <button id="upload-select-btn" class="bg-blue-500 hover:bg-blue-600 text-white px-6 py-2 rounded-lg transition-colors" type="button">
                        选择文件
                    </button>
                    <input type="file" class="hidden" id="upload-file-input" multiple>
                </div>
                <div id="upload-list" class="mt-6 space-y-3 max-h-56 overflow-y-auto"></div>
            </div>
            <div class="px-6 py-4 border-t border-gray-100 flex justify-end gap-3">
                <button onclick="clearUploadQueue()" id="upload-clear-btn" class="px-4 py-2 text-gray-600 hover:bg-gray-100 rounded-lg transition-colors" type="button">
                    清空
                </button>
                <button onclick="closeUploadModal()" class="px-4 py-2 text-gray-600 hover:bg-gray-100 rounded-lg transition-colors" type="button">
                    取消
                </button>
                <button onclick="startQueuedUpload()" id="upload-start-btn" class="px-4 py-2 bg-blue-500 hover:bg-blue-600 text-white rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed" type="button">
                    开始上传
                </button>
            </div>
        </div>
    </div>

    <!-- 设置弹窗 -->
    <div id="settings-modal" class="fixed inset-0 bg-black/50 z-50 hidden items-center justify-center p-4">
        <div class="bg-white rounded-xl shadow-2xl w-full max-w-2xl max-h-[90vh] overflow-y-auto fade-in">
            <div class="px-6 py-4 border-b border-gray-100 flex items-center justify-between">
                <h3 class="text-lg font-semibold text-gray-800">设置</h3>
                <button onclick="closeModal('settings-modal')" class="p-2 hover:bg-gray-100 rounded-lg transition-colors" type="button">
                    <i class="ri-close-line text-gray-500 text-xl"></i>
                </button>
            </div>
            <div class="px-6 pt-4 border-b border-gray-100">
                <div class="flex gap-2 overflow-x-auto">
                    <button id="settings-account-tab" onclick="switchSettingsTab('account')" class="px-4 py-2 text-sm rounded-t-lg bg-blue-50 text-blue-600 font-medium" type="button">
                        <i class="ri-lock-password-line mr-1"></i> 修改密码
                    </button>
                    <button id="settings-maintenance-tab" onclick="switchSettingsTab('maintenance')" class="px-4 py-2 text-sm rounded-t-lg text-gray-600 hover:bg-gray-50" type="button">
                        <i class="ri-database-2-line mr-1"></i> 数据维护
                    </button>
                    <button id="settings-factory-tab" onclick="switchSettingsTab('factory')" class="px-4 py-2 text-sm rounded-t-lg text-gray-600 hover:bg-gray-50" type="button">
                        <i class="ri-restart-line mr-1"></i> 恢复出厂
                    </button>
                    <button id="settings-about-tab" onclick="switchSettingsTab('about')" class="px-4 py-2 text-sm rounded-t-lg text-gray-600 hover:bg-gray-50" type="button">
                        <i class="ri-information-line mr-1"></i> 关于
                    </button>
                </div>
            </div>
            <div id="settings-account-panel">
                <form onsubmit="changePassword(event)" class="p-6">
                    <div class="space-y-4">
                        <div>
                            <label for="current-password" class="block text-sm font-medium text-gray-700 mb-2">当前密码</label>
                            <input type="password" id="current-password" autocomplete="current-password" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" required>
                        </div>
                        <div>
                            <label for="new-password" class="block text-sm font-medium text-gray-700 mb-2">新密码</label>
                            <input type="password" id="new-password" autocomplete="new-password" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" required>
                        </div>
                        <div>
                            <label for="confirm-password" class="block text-sm font-medium text-gray-700 mb-2">确认新密码</label>
                            <input type="password" id="confirm-password" autocomplete="new-password" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" required>
                        </div>
                    </div>
                    <div class="flex justify-end gap-3 mt-6">
                        <button onclick="closeModal('settings-modal')" class="px-4 py-2 text-gray-600 hover:bg-gray-100 rounded-lg transition-colors" type="button">取消</button>
                        <button id="change-password-btn" class="px-4 py-2 bg-blue-500 hover:bg-blue-600 text-white rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed" type="submit">保存</button>
                    </div>
                </form>
            </div>
            <div id="settings-maintenance-panel" class="hidden p-6">
                <div id="maintenance-loading" class="hidden py-10 text-center text-gray-500">
                    <i class="ri-loader-4-line text-2xl align-middle"></i>
                    <span class="ml-2">加载中</span>
                </div>
                <div id="maintenance-content" class="space-y-5">
                    <div class="grid grid-cols-1 sm:grid-cols-2 gap-x-8 gap-y-3 text-sm">
                        <div class="flex items-center justify-between border-b border-gray-100 pb-2">
                            <span class="text-gray-500">文件</span>
                            <span id="maint-file-count" class="font-medium text-gray-800">-</span>
                        </div>
                        <div class="flex items-center justify-between border-b border-gray-100 pb-2">
                            <span class="text-gray-500">文件夹</span>
                            <span id="maint-folder-count" class="font-medium text-gray-800">-</span>
                        </div>
                        <div class="flex items-center justify-between border-b border-gray-100 pb-2">
                            <span class="text-gray-500">回收站项目</span>
                            <span id="maint-trash-count" class="font-medium text-gray-800">-</span>
                        </div>
                        <div class="flex items-center justify-between border-b border-gray-100 pb-2">
                            <span class="text-gray-500">回收站占用</span>
                            <span id="maint-trash-size" class="font-medium text-gray-800">-</span>
                        </div>
                        <div class="flex items-center justify-between border-b border-gray-100 pb-2">
                            <span class="text-gray-500">已用空间</span>
                            <span id="maint-used-size" class="font-medium text-gray-800">-</span>
                        </div>
                        <div class="flex items-center justify-between border-b border-gray-100 pb-2">
                            <span class="text-gray-500">数据库大小</span>
                            <span id="maint-db-size" class="font-medium text-gray-800">-</span>
                        </div>
                    </div>
                    <div class="border-t border-gray-100 pt-4 flex flex-wrap items-center justify-end gap-3">
                        <button onclick="loadMaintenanceStats()" class="px-4 py-2 text-gray-600 hover:bg-gray-100 rounded-lg transition-colors" type="button">
                            <i class="ri-refresh-line mr-1"></i> 刷新统计
                        </button>
                        <button onclick="emptyTrash()" id="empty-trash-btn" class="px-4 py-2 bg-red-500 hover:bg-red-600 text-white rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed" type="button">
                            <i class="ri-delete-bin-6-line mr-1"></i> 清空回收站
                        </button>
                    </div>
                </div>
            </div>
            <div id="settings-factory-panel" class="hidden p-6">
                <div class="border border-red-200 bg-red-50 rounded-lg p-4 mb-5 text-sm text-red-700">
                    恢复出厂设置会删除安装状态、数据库、配置文件和所有上传文件。执行后系统会回到未安装状态，需要重新安装后才能继续使用。
                </div>
                <form onsubmit="factoryReset(event)" class="space-y-4">
                    <div>
                        <label for="factory-password" class="block text-sm font-medium text-gray-700 mb-2">登录密码</label>
                        <input type="password" id="factory-password" autocomplete="current-password" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-red-500" required>
                    </div>
                    <div class="flex justify-end gap-3">
                        <button onclick="closeModal('settings-modal')" class="px-4 py-2 text-gray-600 hover:bg-gray-100 rounded-lg transition-colors" type="button">取消</button>
                        <button id="factory-reset-btn" class="px-4 py-2 bg-red-500 hover:bg-red-600 text-white rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed" type="submit">
                            确认恢复出厂
                        </button>
                    </div>
                </form>
            </div>
            <div id="settings-about-panel" class="hidden p-6">
                <div class="space-y-3 text-sm">
                    <div class="flex items-center justify-between border-b border-gray-100 pb-2">
                        <span class="text-gray-500">系统名称</span>
                        <span class="font-medium text-gray-800">香橙个人网盘系统</span>
                    </div>
                    <div class="flex items-center justify-between border-b border-gray-100 pb-2">
                        <span class="text-gray-500">版本号</span>
                        <span class="font-medium text-gray-800">1.0</span>
                    </div>
                    <div class="flex items-center justify-between border-b border-gray-100 pb-2">
                        <span class="text-gray-500">官网</span>
                        <a href="https://gerenwangpan.com" target="_blank" rel="noopener noreferrer" class="font-medium text-blue-600 hover:text-blue-700">gerenwangpan.com</a>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <!-- 顶部导航栏 -->
    <header class="bg-white border-b border-gray-200 px-4 md:px-6 py-3 flex items-center justify-between shadow-sm flex-shrink-0">
        <div class="flex items-center gap-3">
            <i class="ri-cloud-line text-2xl text-blue-500"></i>
            <h1 class="text-lg md:text-xl font-semibold text-gray-800">香橙个人网盘系统</h1>
        </div>
        <div class="flex items-center gap-3">
            <button onclick="openModal('settings-modal')" class="bg-gray-100 hover:bg-gray-200 text-gray-700 px-3 py-2 rounded-lg flex items-center gap-2 transition-colors" type="button">
                <i class="ri-settings-3-line"></i>
                设置
            </button>
        </div>
    </header>

    <div class="flex flex-col md:flex-row flex-1 md:overflow-hidden">
        <!-- 侧边栏 -->
        <aside class="w-full md:w-64 bg-white border-b md:border-b-0 md:border-r border-gray-200 p-3 md:p-4 flex md:flex-col flex-shrink-0">
            <div class="flex md:block gap-2 md:gap-0 overflow-x-auto md:overflow-visible md:mb-6 w-full md:w-auto">
                <div id="nav-all" onclick="navigateTo('root')" class="flex items-center gap-2 px-3 py-2 bg-blue-50 text-blue-600 rounded-lg md:mb-2 cursor-pointer font-medium whitespace-nowrap">
                    <i class="ri-hard-drive-2-line"></i>
                    <span>全部文件</span>
                </div>
                <div id="nav-recent" class="flex items-center gap-2 px-3 py-2 rounded-lg md:mb-2 cursor-pointer text-gray-600 hover:bg-gray-50 whitespace-nowrap">
                    <i class="ri-time-line text-gray-400"></i>
                    <span>最近使用</span>
                </div>
            </div>

            <div class="hidden md:block flex-1 overflow-y-auto">
                <h3 class="text-sm font-medium text-gray-500 mb-2 px-3">我的文件夹</h3>
                <div id="sidebar-folders" class="space-y-1">
                    <!-- 侧边栏文件夹由JS渲染 -->
                </div>
            </div>
            
            <!-- 存储空间显示 -->
            <div class="hidden md:block pt-4 border-t border-gray-200 mt-4">
                <div class="px-3">
                    <div class="flex items-center justify-between mb-2 text-sm">
                        <span class="text-gray-600">剩余空间</span>
                        <span id="storage-text" class="text-gray-500">0 B / 0 B</span>
                    </div>
                    <div class="w-full bg-gray-200 rounded-full h-2">
                        <div id="storage-bar" class="bg-blue-500 h-2 rounded-full transition-all duration-500" style="width: 0%"></div>
                    </div>
                </div>
            </div>
        </aside>

        <!-- 主内容区 -->
        <main id="main-content" class="flex-1 overflow-auto p-4 md:p-6 drop-zone">
            <!-- 面包屑导航和工具栏 -->
            <div class="flex flex-col md:flex-row md:items-center justify-between gap-3 mb-4">
                <div class="flex items-center gap-3 min-w-0 overflow-hidden">
                    <button id="back-btn" onclick="goBack()" class="flex items-center gap-1.5 px-2.5 py-1.5 text-sm text-gray-600 hover:text-gray-900 hover:bg-gray-100 rounded-lg transition-colors disabled:opacity-40 disabled:cursor-not-allowed" type="button">
                        <i class="ri-arrow-left-line"></i>
                        返回
                    </button>
                    <div id="breadcrumb" class="flex items-center gap-1 text-sm text-gray-600 min-w-0">
                        <!-- 面包屑由JS渲染 -->
                    </div>
                </div>
                <!-- 排序 -->
                <div class="flex items-center gap-2 justify-between md:justify-end">
                    <button onclick="refreshCurrentFolder()" class="p-1.5 text-gray-600 hover:bg-gray-100 rounded-lg transition-colors" type="button" title="刷新">
                        <i class="ri-refresh-line text-base"></i>
                    </button>
                    <span class="text-sm text-gray-500">排序：</span>
                    <select id="sort-select" onchange="sortFiles()" class="px-3 py-1.5 border border-gray-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-blue-500">
                        <option value="name-asc">名称 ↑</option>
                        <option value="name-desc">名称 ↓</option>
                        <option value="size-asc">大小 ↑</option>
                        <option value="size-desc">大小 ↓</option>
                        <option value="time-asc">修改时间 ↑</option>
                        <option value="time-desc" selected>修改时间 ↓</option>
                    </select>
                </div>
            </div>

            <!-- 文件工具栏 -->
            <div class="flex flex-col lg:flex-row lg:items-center justify-between gap-3 mb-4">
                <div class="relative w-full lg:flex-1 lg:max-w-md">
                    <input type="text" id="search-input" placeholder="搜索文件..." 
                           class="w-full pl-10 pr-9 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent">
                    <i class="ri-search-line absolute left-3 top-1/2 -translate-y-1/2 text-gray-400"></i>
                    <button id="clear-search" onclick="clearSearch()" class="absolute right-3 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600 hidden" type="button">
                        <i class="ri-close-line"></i>
                    </button>
                </div>
                <div class="grid grid-cols-3 sm:flex items-center gap-2">
                    <button id="batch-select-btn" onclick="toggleSelectionMode()" class="bg-gray-100 hover:bg-gray-200 text-gray-700 px-3 sm:px-4 py-2 rounded-lg flex items-center justify-center gap-2 transition-colors text-sm sm:text-base" type="button">
                        <i class="ri-checkbox-multiple-line"></i>
                        <span class="hidden sm:inline">批量选择</span>
                        <span class="sm:hidden">批量</span>
                    </button>
                    <button onclick="openModal('new-folder-modal')" class="bg-gray-100 hover:bg-gray-200 text-gray-700 px-3 sm:px-4 py-2 rounded-lg flex items-center justify-center gap-2 transition-colors text-sm sm:text-base" type="button">
                        <i class="ri-folder-add-line"></i>
                        <span class="hidden sm:inline">新建文件夹</span>
                        <span class="sm:hidden">新建</span>
                    </button>
                    <button onclick="openUploadModal()" class="bg-blue-500 hover:bg-blue-600 text-white px-3 sm:px-4 py-2 rounded-lg flex items-center justify-center gap-2 transition-colors text-sm sm:text-base" type="button">
                        <i class="ri-upload-cloud-line"></i>
                        <span class="hidden sm:inline">上传文件</span>
                        <span class="sm:hidden">上传</span>
                    </button>
                </div>
            </div>

            <!-- 选中操作栏 -->
            <div id="selection-bar" class="hidden bg-blue-50 border border-blue-200 rounded-lg px-4 py-3 mb-4 flex-col sm:flex-row sm:items-center justify-between gap-3">
                <span class="text-blue-700 font-medium">已选择 <span id="selected-count">0</span> 个项目</span>
                <div class="flex flex-wrap gap-2">
                    <button onclick="downloadSelected()" class="px-3 py-1.5 bg-white border border-blue-300 text-blue-600 rounded-lg text-sm hover:bg-blue-50">
                        <i class="ri-download-line"></i> 下载
                    </button>
                    <button onclick="deleteSelected()" class="px-3 py-1.5 bg-red-500 text-white rounded-lg text-sm hover:bg-red-600">
                        <i class="ri-delete-bin-line"></i> 删除
                    </button>
                    <button onclick="clearSelection()" class="px-3 py-1.5 text-gray-600 hover:bg-white/50 rounded-lg text-sm">
                        取消选择
                    </button>
                </div>
            </div>

            <!-- 文件列表 -->
            <div class="rounded-lg border border-gray-200 overflow-hidden">
                <!-- 列表表头 -->
                <div class="hidden md:block bg-gray-100">
                    <div class="grid grid-cols-12 gap-4 px-4 py-3 text-sm font-medium text-gray-500">
                        <div id="select-all-col" class="hidden col-span-1 items-center gap-2">
                            <input type="checkbox" id="select-all" onchange="toggleSelectAll()" class="w-4 h-4 rounded">
                        </div>
                        <div id="file-name-header" class="col-span-6">文件名</div>
                        <div class="col-span-2">大小</div>
                        <div class="col-span-3">修改时间</div>
                        <div class="col-span-1">操作</div>
                    </div>
                </div>
                <!-- 文件列表内容 -->
                <div id="file-list" class="bg-white min-h-[400px]">
                    <!-- 文件列表由JS渲染 -->
                </div>
            </div>

            <!-- 空状态 -->
            <div id="empty-state" class="hidden flex flex-col items-center justify-center py-20 text-gray-400">
                <i class="ri-folder-open-line text-6xl mb-4"></i>
                <p class="text-lg">文件夹为空</p>
                <p class="text-sm mt-2">拖拽文件到此处或点击上传按钮添加文件</p>
            </div>

            <!-- 搜索无结果 -->
            <div id="search-empty" class="hidden flex flex-col items-center justify-center py-20 text-gray-400">
                <i class="ri-search-line text-6xl mb-4"></i>
                <p class="text-lg">未找到匹配的文件</p>
                <p class="text-sm mt-2">尝试使用其他关键词搜索</p>
            </div>
        </main>
    </div>

    <script>
        /*
         * 旧的前端模拟数据逻辑已禁用，真实目录功能由 app.js 接管。
         *
        // ==================== 数据层 ====================
        const fileSystem = {
            root: {
                id: 'root',
                name: '全部文件',
                type: 'folder',
                parentId: null,
                modified: '2024-01-15 14:30',
                children: [
                    {
                        id: 'folder-1',
                        name: '文档',
                        type: 'folder',
                        parentId: 'root',
                        modified: '2024-01-15 14:30',
                        children: [
                            { id: 'file-1-1', name: '工作报告.docx', type: 'file', parentId: 'folder-1', size: 2621440, modified: '2024-01-15 14:30' },
                            { id: 'file-1-2', name: '项目计划.pdf', type: 'file', parentId: 'folder-1', size: 1887436, modified: '2024-01-14 10:20' },
                            {
                                id: 'folder-1-1',
                                name: '会议记录',
                                type: 'folder',
                                parentId: 'folder-1',
                                modified: '2024-01-10 09:00',
                                children: [
                                    { id: 'file-1-1-1', name: '周会纪要.md', type: 'file', parentId: 'folder-1-1', size: 46080, modified: '2024-01-10 09:00' },
                                    { id: 'file-1-1-2', name: '产品评审.docx', type: 'file', parentId: 'folder-1-1', size: 911360, modified: '2024-01-08 16:30' }
                                ]
                            }
                        ]
                    },
                    {
                        id: 'folder-2',
                        name: '图片',
                        type: 'folder',
                        parentId: 'root',
                        modified: '2024-01-12 16:45',
                        children: [
                            { id: 'file-2-1', name: '风景照片.jpg', type: 'file', parentId: 'folder-2', size: 5452595, modified: '2024-01-12 16:45' },
                            { id: 'file-2-2', name: '团队合影.png', type: 'file', parentId: 'folder-2', size: 3879731, modified: '2024-01-11 11:20' }
                        ]
                    },
                    {
                        id: 'folder-3',
                        name: '视频',
                        type: 'folder',
                        parentId: 'root',
                        modified: '2024-01-08 11:30',
                        children: [
                            { id: 'file-3-1', name: '产品演示.mp4', type: 'file', parentId: 'folder-3', size: 134217728, modified: '2024-01-08 11:30' },
                            { id: 'file-3-2', name: '培训课程.mp4', type: 'file', parentId: 'folder-3', size: 268435456, modified: '2024-01-05 14:00' }
                        ]
                    },
                    { id: 'file-1', name: 'README.txt', type: 'file', parentId: 'root', size: 2048, modified: '2024-01-15 09:00' },
                    { id: 'file-2', name: '数据备份.zip', type: 'file', parentId: 'root', size: 163577856, modified: '2024-01-13 18:45' }
                ]
            }
        };

        // 全局状态
        let state = {
            currentFolderId: 'root',
            path: ['root'],
            selectedItems: new Set(),
            searchQuery: '',
            sortBy: 'time-desc',
            contextMenuItemId: null
        };

        // ID映射表 - O(1)查找
        let fileMap = new Map();

        // ==================== 初始化 ====================
        function init() {
            buildFileMap(fileSystem.root);
            updateStorage();
            renderSidebar();
            renderBreadcrumb();
            renderFileList();
            setupEventListeners();
        }

        // 构建文件映射表
        function buildFileMap(node) {
            fileMap.set(node.id, node);
            if (node.children) {
                node.children.forEach(child => buildFileMap(child));
            }
        }

        // 设置事件监听
        function setupEventListeners() {
            // 搜索
            document.getElementById('search-input').addEventListener('input', (e) => {
                state.searchQuery = e.target.value;
                document.getElementById('clear-search').classList.toggle('hidden', !e.target.value);
                renderFileList();
            });

            // 点击空白关闭右键菜单
            document.addEventListener('click', () => {
                document.getElementById('context-menu').classList.add('hidden');
            });

            // 拖拽上传
            const dropZone = document.getElementById('main-content');
            dropZone.addEventListener('dragover', (e) => {
                e.preventDefault();
                dropZone.classList.add('drag-over');
            });
            dropZone.addEventListener('dragleave', () => {
                dropZone.classList.remove('drag-over');
            });
            dropZone.addEventListener('drop', (e) => {
                e.preventDefault();
                dropZone.classList.remove('drag-over');
                handleFileUpload(e.dataTransfer.files);
            });

            // ESC关闭弹窗
            document.addEventListener('keydown', (e) => {
                if (e.key === 'Escape') {
                    closeAllModals();
                }
            });
        }

        // ==================== 工具函数 ====================
        function formatSize(bytes) {
            if (bytes === 0) return '0 B';
            const k = 1024;
            const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
            const i = Math.floor(Math.log(bytes) / Math.log(k));
            return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i];
        }

        function getFileIcon(item) {
            if (item.type === 'folder') {
                return '<i class="ri-folder-fill text-yellow-500 text-xl"></i>';
            }
            const ext = item.name.split('.').pop().toLowerCase();
            const iconMap = {
                'doc': 'ri-file-word-fill text-blue-500',
                'docx': 'ri-file-word-fill text-blue-500',
                'pdf': 'ri-file-pdf-fill text-red-500',
                'xls': 'ri-file-excel-fill text-green-500',
                'xlsx': 'ri-file-excel-fill text-green-500',
                'ppt': 'ri-file-ppt-fill text-orange-500',
                'pptx': 'ri-file-ppt-fill text-orange-500',
                'jpg': 'ri-image-fill text-purple-500',
                'jpeg': 'ri-image-fill text-purple-500',
                'png': 'ri-image-fill text-purple-500',
                'gif': 'ri-image-fill text-purple-500',
                'mp4': 'ri-video-fill text-pink-500',
                'avi': 'ri-video-fill text-pink-500',
                'mp3': 'ri-music-fill text-cyan-500',
                'zip': 'ri-file-zip-fill text-gray-500',
                'rar': 'ri-file-zip-fill text-gray-500',
                'txt': 'ri-file-text-fill text-gray-500',
                'md': 'ri-file-markdown-fill text-gray-600'
            };
            const iconClass = iconMap[ext] || 'ri-file-fill text-gray-400';
            return `<i class="${iconClass} text-xl"></i>`;
        }

        function generateId() {
            return 'item-' + Date.now() + '-' + Math.random().toString(36).substr(2, 9);
        }

        function showToast(message, type = 'success') {
            const container = document.getElementById('toast-container');
            const toast = document.createElement('div');
            const bgColor = type === 'success' ? 'bg-green-500' : type === 'error' ? 'bg-red-500' : 'bg-blue-500';
            const icon = type === 'success' ? 'ri-check-line' : type === 'error' ? 'ri-error-warning-line' : 'ri-information-line';
            
            toast.className = `toast ${bgColor} text-white px-4 py-3 rounded-lg shadow-lg flex items-center gap-2`;
            toast.innerHTML = `<i class="${icon}"></i><span>${message}</span>`;
            container.appendChild(toast);
            
            setTimeout(() => toast.remove(), 3000);
        }

        // ==================== 存储空间 ====================
        function updateStorage() {
            let totalSize = 0;
            function calcSize(node) {
                if (node.type === 'file') {
                    totalSize += node.size;
                } else if (node.children) {
                    node.children.forEach(calcSize);
                }
            }
            calcSize(fileSystem.root);

            const maxSize = 1099511627776; // 1TB
            const percent = Math.min((totalSize / maxSize) * 100, 100);
            
            document.getElementById('storage-text').textContent = `${formatSize(totalSize)} / 1 TB`;
            document.getElementById('storage-bar').style.width = `${percent}%`;
        }

        // ==================== 导航相关 ====================
        function navigateTo(folderId) {
            const folder = fileMap.get(folderId);
            if (!folder || folder.type !== 'folder') return;

            // 重建路径
            state.path = [];
            let current = folder;
            while (current) {
                state.path.unshift(current.id);
                current = current.parentId ? fileMap.get(current.parentId) : null;
            }

            state.currentFolderId = folderId;
            state.selectedItems.clear();
            updateSelectionBar();
            renderBreadcrumb();
            renderFileList();
            renderSidebar();
            updateNavHighlight();
        }

        function goBack() {
            if (state.path.length > 1) {
                state.path.pop();
                const parentId = state.path[state.path.length - 1];
                navigateTo(parentId);
            }
        }

        function updateNavHighlight() {
            document.querySelectorAll('[id^="nav-"]').forEach(el => {
                el.classList.remove('bg-blue-50', 'text-blue-600', 'font-medium');
                el.classList.add('text-gray-600');
            });
            
            if (state.currentFolderId === 'root') {
                document.getElementById('nav-all').classList.add('bg-blue-50', 'text-blue-600', 'font-medium');
                document.getElementById('nav-all').classList.remove('text-gray-600');
            }
        }

        // ==================== 面包屑 ====================
        function renderBreadcrumb() {
            const breadcrumb = document.getElementById('breadcrumb');
            const backBtn = document.getElementById('back-btn');
            
            backBtn.disabled = state.path.length <= 1;

            breadcrumb.innerHTML = state.path.map((id, index) => {
                const item = fileMap.get(id);
                const isLast = index === state.path.length - 1;
                const separator = isLast ? '' : '<i class="ri-arrow-right-s-line text-gray-400"></i>';
                
                if (isLast) {
                    return `<span class="text-gray-800 font-medium">${item.name}</span>`;
                }
                return `
                    <span class="text-blue-500 cursor-pointer hover:underline" onclick="navigateTo('${id}')">${item.name}</span>
                    ${separator}
                `;
            }).join('');
        }

        // ==================== 侧边栏 ====================
        function renderSidebar() {
            const sidebar = document.getElementById('sidebar-folders');
            const rootFolder = fileMap.get('root');
            const rootFolders = rootFolder.children.filter(item => item.type === 'folder');
            
            sidebar.innerHTML = rootFolders.map(folder => {
                const isActive = state.currentFolderId === folder.id;
                const activeClass = isActive ? 'bg-blue-50 text-blue-600 font-medium' : 'text-gray-600 hover:bg-gray-50';
                return `
                    <div class="folder-item flex items-center gap-2 px-3 py-2 rounded-lg cursor-pointer ${activeClass}" 
                         onclick="navigateTo('${folder.id}')">
                        <i class="ri-folder-fill ${isActive ? 'text-blue-500' : 'text-yellow-500'}"></i>
                        <span>${folder.name}</span>
                    </div>
                `;
            }).join('');
        }

        // ==================== 文件渲染 ====================
        function renderFileList() {
            const currentFolder = fileMap.get(state.currentFolderId);
            let items = [...(currentFolder.children || [])];

            // 搜索过滤
            if (state.searchQuery) {
                items = items.filter(item => 
                    item.name.toLowerCase().includes(state.searchQuery.toLowerCase())
                );
                document.getElementById('search-empty').classList.toggle('hidden', items.length > 0);
                document.getElementById('file-list').parentElement.classList.toggle('hidden', items.length === 0);
            } else {
                document.getElementById('search-empty').classList.add('hidden');
                document.getElementById('file-list').parentElement.classList.remove('hidden');
            }

            // 排序
            sortItems(items);

            // 空状态
            const hasItems = items.length > 0 || state.searchQuery;
            document.getElementById('empty-state').classList.toggle('hidden', hasItems);

            if (!hasItems) return;

            renderListView(items);
            updateSelectAllCheckbox();
        }

        function renderListView(items) {
            const fileList = document.getElementById('file-list');
            
            if (items.length === 0) {
                fileList.innerHTML = '';
                return;
            }
            
            fileList.innerHTML = items.map(item => {
                const isSelected = state.selectedItems.has(item.id);
                
                return `
                    <div class="file-item file-row grid grid-cols-12 gap-4 px-4 py-3 border-b border-gray-100 items-center ${isSelected ? 'selected' : ''}"
                         data-id="${item.id}"
                         ondblclick="handleItemDoubleClick('${item.id}')"
                         onclick="handleItemClick(event, '${item.id}')"
                         oncontextmenu="showContextMenu(event, '${item.id}')">
                        <div class="col-span-1">
                            <input type="checkbox" ${isSelected ? 'checked' : ''} 
                                   onclick="event.stopPropagation(); toggleSelection('${item.id}')"
                                   class="w-4 h-4 rounded">
                        </div>
                        <div class="col-span-5 flex items-center gap-3">
                            ${getFileIcon(item)}
                            <span class="text-gray-800">${highlightSearch(item.name)}</span>
                        </div>
                        <div class="col-span-2 text-gray-500 text-sm">${item.type === 'folder' ? '-' : formatSize(item.size)}</div>
                        <div class="col-span-3 text-gray-500 text-sm">${item.modified}</div>
                        <div class="col-span-1 flex gap-1">
                            <button class="p-1.5 hover:bg-gray-100 rounded text-gray-400 hover:text-gray-600" 
                                    onclick="event.stopPropagation(); downloadItem('${item.id}')" title="下载">
                                <i class="ri-download-line"></i>
                            </button>
                            <button class="p-1.5 hover:bg-gray-100 rounded text-gray-400 hover:text-gray-600" 
                                    onclick="event.stopPropagation(); showMoreMenu(event, '${item.id}')" title="更多">
                                <i class="ri-more-2-fill"></i>
                            </button>
                        </div>
                    </div>
                `;
            }).join('');
        }

        function highlightSearch(name) {
            if (!state.searchQuery) return name;
            const regex = new RegExp(`(${state.searchQuery})`, 'gi');
            return name.replace(regex, '<mark class="bg-yellow-200">$1</mark>');
        }

        // ==================== 点击处理 ====================
        function handleItemClick(event, itemId) {
            if (event.ctrlKey || event.metaKey) {
                toggleSelection(itemId);
            }
        }

        function handleItemDoubleClick(itemId) {
            const item = fileMap.get(itemId);
            if (item.type === 'folder') {
                navigateTo(itemId);
            }
        }

        // ==================== 选择相关 ====================
        function toggleSelection(itemId) {
            if (state.selectedItems.has(itemId)) {
                state.selectedItems.delete(itemId);
            } else {
                state.selectedItems.add(itemId);
            }
            updateSelectionBar();
            renderFileList();
        }

        function toggleSelectAll() {
            const currentFolder = fileMap.get(state.currentFolderId);
            const items = currentFolder.children || [];
            
            if (state.selectedItems.size === items.length) {
                state.selectedItems.clear();
            } else {
                items.forEach(item => state.selectedItems.add(item.id));
            }
            updateSelectionBar();
            renderFileList();
        }

        function clearSelection() {
            state.selectedItems.clear();
            updateSelectionBar();
            renderFileList();
        }

        function updateSelectionBar() {
            const bar = document.getElementById('selection-bar');
            const count = document.getElementById('selected-count');
            
            count.textContent = state.selectedItems.size;
            bar.classList.toggle('hidden', state.selectedItems.size === 0);
        }

        function updateSelectAllCheckbox() {
            const currentFolder = fileMap.get(state.currentFolderId);
            const items = currentFolder.children || [];
            const checkbox = document.getElementById('select-all');
            
            checkbox.checked = state.selectedItems.size > 0 && state.selectedItems.size === items.length;
            checkbox.indeterminate = state.selectedItems.size > 0 && state.selectedItems.size < items.length;
        }

        // ==================== 排序 ====================
        function sortFiles() {
            state.sortBy = document.getElementById('sort-select').value;
            renderFileList();
        }

        function sortItems(items) {
            const [field, order] = state.sortBy.split('-');
            const multiplier = order === 'asc' ? 1 : -1;
            
            items.sort((a, b) => {
                // 文件夹始终排在前面
                if (a.type !== b.type) {
                    return a.type === 'folder' ? -1 : 1;
                }
                
                if (field === 'name') {
                    return multiplier * a.name.localeCompare(b.name);
                } else if (field === 'size') {
                    return multiplier * ((a.size || 0) - (b.size || 0));
                } else if (field === 'time') {
                    return multiplier * (new Date(a.modified) - new Date(b.modified));
                }
                return 0;
            });
        }

        // ==================== 搜索 ====================
        function clearSearch() {
            document.getElementById('search-input').value = '';
            state.searchQuery = '';
            document.getElementById('clear-search').classList.add('hidden');
            renderFileList();
        }

        // ==================== 右键菜单 ====================
        function showContextMenu(event, itemId) {
            event.preventDefault();
            event.stopPropagation();
            
            state.contextMenuItemId = itemId;
            const menu = document.getElementById('context-menu');
            
            menu.style.left = `${event.clientX}px`;
            menu.style.top = `${event.clientY}px`;
            menu.classList.remove('hidden');
        }

        function handleContextAction(action) {
            const itemId = state.contextMenuItemId;
            document.getElementById('context-menu').classList.add('hidden');
            
            switch (action) {
                case 'open':
                    const item = fileMap.get(itemId);
                    if (item.type === 'folder') {
                        navigateTo(itemId);
                    }
                    break;
                case 'download':
                    downloadItem(itemId);
                    break;
                case 'rename':
                    startRename(itemId);
                    break;
                case 'delete':
                    deleteItem(itemId);
                    break;
            }
        }

        function showMoreMenu(event, itemId) {
            state.contextMenuItemId = itemId;
            const menu = document.getElementById('context-menu');
            const rect = event.target.getBoundingClientRect();
            
            menu.style.left = `${rect.left}px`;
            menu.style.top = `${rect.bottom}px`;
            menu.classList.remove('hidden');
        }

        // ==================== 文件操作 ====================
        function downloadItem(itemId) {
            const item = fileMap.get(itemId);
            showToast(`开始下载: ${item.name}`);
        }

        function downloadSelected() {
            showToast(`开始下载 ${state.selectedItems.size} 个文件`);
        }

        function startRename(itemId) {
            const item = fileMap.get(itemId);
            document.getElementById('rename-input').value = item.name;
            state.contextMenuItemId = itemId;
            openModal('rename-modal');
            setTimeout(() => document.getElementById('rename-input').focus(), 100);
        }

        function confirmRename() {
            const newName = document.getElementById('rename-input').value.trim();
            if (!newName) {
                showToast('请输入有效名称', 'error');
                return;
            }
            
            const item = fileMap.get(state.contextMenuItemId);
            item.name = newName;
            closeModal('rename-modal');
            renderFileList();
            renderSidebar();
            showToast('重命名成功');
        }

        function deleteItem(itemId) {
            const item = fileMap.get(itemId);
            const parent = fileMap.get(item.parentId);
            
            parent.children = parent.children.filter(c => c.id !== itemId);
            fileMap.delete(itemId);
            state.selectedItems.delete(itemId);
            
            updateSelectionBar();
            updateStorage();
            renderFileList();
            renderSidebar();
            showToast('已删除到回收站');
        }

        function deleteSelected() {
            const count = state.selectedItems.size;
            state.selectedItems.forEach(id => {
                const item = fileMap.get(id);
                const parent = fileMap.get(item.parentId);
                parent.children = parent.children.filter(c => c.id !== id);
                fileMap.delete(id);
            });
            
            state.selectedItems.clear();
            updateSelectionBar();
            updateStorage();
            renderFileList();
            renderSidebar();
            showToast(`已删除 ${count} 个项目`);
        }

        // ==================== 新建文件夹 ====================
        function createNewFolder() {
            const name = document.getElementById('new-folder-name').value.trim();
            if (!name) {
                showToast('请输入文件夹名称', 'error');
                return;
            }
            
            const newFolder = {
                id: generateId(),
                name: name,
                type: 'folder',
                parentId: state.currentFolderId,
                modified: new Date().toLocaleString('zh-CN', { 
                    year: 'numeric', month: '2-digit', day: '2-digit',
                    hour: '2-digit', minute: '2-digit'
                }).replace(/\//g, '-'),
                children: []
            };
            
            const parent = fileMap.get(state.currentFolderId);
            parent.children.unshift(newFolder);
            fileMap.set(newFolder.id, newFolder);
            
            closeModal('new-folder-modal');
            document.getElementById('new-folder-name').value = '';
            renderFileList();
            renderSidebar();
            showToast('文件夹创建成功');
        }

        // ==================== 文件上传 ====================
        function handleFileUpload(files) {
            if (files.length === 0) return;
            
            Array.from(files).forEach(file => {
                const newFile = {
                    id: generateId(),
                    name: file.name,
                    type: 'file',
                    parentId: state.currentFolderId,
                    size: file.size,
                    modified: new Date().toLocaleString('zh-CN', { 
                        year: 'numeric', month: '2-digit', day: '2-digit',
                        hour: '2-digit', minute: '2-digit'
                    }).replace(/\//g, '-')
                };
                
                const parent = fileMap.get(state.currentFolderId);
                parent.children.unshift(newFile);
                fileMap.set(newFile.id, newFile);
            });
            
            updateStorage();
            renderFileList();
            showToast(`成功上传 ${files.length} 个文件`);
        }

        // ==================== 弹窗控制 ====================
        function openModal(id) {
            document.getElementById(id).classList.remove('hidden');
            document.getElementById(id).classList.add('flex');
        }

        function closeModal(id) {
            document.getElementById(id).classList.add('hidden');
            document.getElementById(id).classList.remove('flex');
        }

        function closeAllModals() {
            ['new-folder-modal', 'rename-modal'].forEach(closeModal);
        }

        // 初始化
        init();
        */
    </script>
    <script src="app.js?v=<?= filemtime(__DIR__ . '/app.js') ?>"></script>
</body>
</html>
