<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>文件备份系统</title>
    <style>
        /* 保留原有样式,新增样式在下面 */
        
        .exclude-panel {
            background: #f8f9fa;
            padding: 20px;
            border-radius: 8px;
            margin-bottom: 20px;
            border-left: 4px solid #ff9800;
        }
        
        .exclude-panel h3 {
            color: #ff9800;
            margin-bottom: 15px;
            display: flex;
            align-items: center;
            justify-content: space-between;
        }
        
        .exclude-rules {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
            gap: 15px;
            margin-bottom: 15px;
        }
        
        .rule-category {
            background: white;
            padding: 15px;
            border-radius: 6px;
            border: 1px solid #ddd;
        }
        
        .rule-category h4 {
            margin-bottom: 10px;
            color: #333;
            font-size: 14px;
            text-transform: uppercase;
            letter-spacing: 1px;
        }
        
        .rule-items {
            font-size: 13px;
            line-height: 1.4;
            color: #666;
        }
        
        .rule-item {
            display: inline-block;
            background: #e3f2fd;
            padding: 3px 8px;
            margin: 2px;
            border-radius: 3px;
            font-family: monospace;
        }
        
        .excluded-files {
            max-height: 200px;
            overflow-y: auto;
            background: white;
            padding: 10px;
            border-radius: 6px;
            border: 1px solid #ddd;
            font-size: 12px;
        }
        
        .excluded-file {
            padding: 3px 5px;
            border-bottom: 1px solid #eee;
            font-family: monospace;
        }
        
        .excluded-file:last-child {
            border-bottom: none;
        }
        
        .toggle-btn {
            background: #ff9800;
            color: white;
            border: none;
            padding: 5px 10px;
            border-radius: 4px;
            cursor: pointer;
            font-size: 12px;
        }
        
        .toggle-btn:hover {
            background: #f57c00;
        }
        
        .config-form {
            background: white;
            padding: 20px;
            border-radius: 8px;
            margin-bottom: 20px;
            border: 1px solid #ddd;
        }
        
        .form-group {
            margin-bottom: 15px;
        }
        
        .form-group label {
            display: block;
            margin-bottom: 5px;
            font-weight: bold;
            color: #333;
        }
        
        .form-control {
            width: 100%;
            padding: 8px;
            border: 1px solid #ddd;
            border-radius: 4px;
            font-size: 14px;
        }
        
        .form-control:focus {
            outline: none;
            border-color: #667eea;
            box-shadow: 0 0 0 2px rgba(102, 126, 234, 0.2);
        }
        
        .form-text {
            font-size: 12px;
            color: #666;
            margin-top: 5px;
        }
        
        .modal {
            display: none;
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.5);
            z-index: 1000;
            justify-content: center;
            align-items: center;
        }
        
        .modal-content {
            background: white;
            padding: 30px;
            border-radius: 10px;
            max-width: 500px;
            width: 90%;
            max-height: 80vh;
            overflow-y: auto;
        }
        
        .modal-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 20px;
        }
        
        .modal-close {
            background: none;
            border: none;
            font-size: 24px;
            cursor: pointer;
            color: #666;
        }
        
        .modal-close:hover {
            color: #333;
        }
        
        .modal-buttons {
            display: flex;
            justify-content: flex-end;
            gap: 10px;
            margin-top: 20px;
        }
    </style>
</head>
<body>
    <div class="container">
        <header>
            <h1>📁 文件备份系统</h1>
            <p>安全、可靠的自动化文件备份解决方案</p>
        </header>
        
        <div class="content">
            <div class="stats-grid" id="stats">
                <!-- 统计数据将通过JavaScript动态加载 -->
            </div>
            
            <div class="exclude-panel" id="excludePanel">
                <!-- 排除规则信息将通过JavaScript动态加载 -->
            </div>
            
            <div class="backup-controls">
                <button class="btn" onclick="startBackup()" id="startBtn">开始备份</button>
                <button class="btn btn-stop" onclick="stopBackup()" id="stopBtn" style="display:none">停止备份</button>
                <button class="btn" onclick="resetBackup()" id="resetBtn">重置备份</button>
                <button class="btn" onclick="showConfig()" id="configBtn">配置</button>
                <button class="btn" onclick="location.reload()">刷新状态</button>
                
                <div class="auto-backup">
                    <label>
                        <input type="checkbox" id="autoBackup" onchange="toggleAutoBackup()">
                        自动备份
                    </label>
                    <input type="number" id="interval" value="2" min="1" max="60" style="display:none">
                    <span style="display:none" id="intervalText">秒间隔</span>
                </div>
            </div>
            
            <div class="progress-section">
                <h2>备份进度</h2>
                <div class="progress-container">
                    <div class="progress-bar" id="progressBar">
                        <div class="progress-text" id="progressText">0%</div>
                    </div>
                </div>
                <div id="progressInfo">等待开始备份...</div>
            </div>
            
            <div class="file-info" id="currentFile">
                <!-- 当前文件信息将通过JavaScript动态加载 -->
            </div>
            
            <div class="log-container" id="log">
                <!-- 日志将通过JavaScript动态加载 -->
            </div>
            
            <div class="spinner" id="spinner"></div>
        </div>
        
        <footer>
            <p>© 2023 文件备份系统 | 兼容 PHP 5.3 - PHP 8.x</p>
            <p>当前备份目录: /mnt/sda1/www/2026</p>
            <p>API地址: https://zgyzty.com/assets/sapi.php</p>
            <p>默认排除: config.php, backup.php, api.php 等系统文件</p>
        </footer>
    </div>
    
    <!-- 配置模态框 -->
    <div class="modal" id="configModal">
        <div class="modal-content">
            <div class="modal-header">
                <h2>备份配置</h2>
                <button class="modal-close" onclick="hideConfig()">&times;</button>
            </div>
            
            <div class="config-form">
                <div class="form-group">
                    <label>扫描目录:</label>
                    <input type="text" class="form-control" id="configScanDir" value=".">
                    <div class="form-text">要备份的目录路径</div>
                </div>
                
                <div class="form-group">
                    <label>排除目录 (用逗号分隔):</label>
                    <textarea class="form-control" id="configExcludeDirs" rows="3">.git, vendor, node_modules, backups</textarea>
                    <div class="form-text">排除的目录名,如 .git, vendor 等</div>
                </div>
                
                <div class="form-group">
                    <label>排除文件 (用逗号分隔):</label>
                    <textarea class="form-control" id="configExcludeFiles" rows="3">config.php, backup.php, api.php, backup_status.json, backup_errors.json, curlog.txt</textarea>
                    <div class="form-text">排除的文件名,支持通配符如 *.php</div>
                </div>
                
                <div class="form-group">
                    <label>排除扩展名 (用逗号分隔):</label>
                    <textarea class="form-control" id="configExcludeExtensions" rows="3">tmp, log, cache</textarea>
                    <div class="form-text">排除的文件扩展名,如 tmp, log 等</div>
                </div>
                
                <div class="modal-buttons">
                    <button class="btn" onclick="saveConfig()">保存配置</button>
                    <button class="btn btn-stop" onclick="hideConfig()">取消</button>
                </div>
            </div>
        </div>
    </div>
    
    <script>
        let isBackupRunning = false;
        let autoBackupEnabled = false;
        let backupInterval;
        let logEntries = [];
        
        // 加载统计信息
        function loadStats() {
            fetch('backup.php?action=stats')
                .then(response => response.json())
                .then(data => {
                    const statsHtml = `
                        <div class="stat-card">
                            <h3>📊 总文件数</h3>
                            <div class="number">${data.total_files}</div>
                        </div>
                        <div class="stat-card">
                            <h3>✅ 已备份</h3>
                            <div class="number">${data.backed_up}</div>
                        </div>
                        <div class="stat-card">
                            <h3>⏳ 待备份</h3>
                            <div class="number">${data.pending}</div>
                        </div>
                        <div class="stat-card">
                            <h3>❌ 失败数</h3>
                            <div class="number">${data.errors}</div>
                        </div>
                        <div class="stat-card">
                            <h3>🚫 已排除</h3>
                            <div class="number">${data.excluded_count}</div>
                        </div>
                    `;
                    document.getElementById('stats').innerHTML = statsHtml;
                    
                    // 加载排除规则
                    loadExcludeRules(data);
                });
        }
        
        // 加载排除规则
        function loadExcludeRules(data) {
            fetch('backup.php?action=exclude_rules')
                .then(response => response.json())
                .then(rules => {
                    let excludedFilesHtml = '';
                    if (data.excluded_files && data.excluded_files.length > 0) {
                        data.excluded_files.slice(0, 20).forEach(file => {
                            excludedFilesHtml += `<div class="excluded-file">${file}</div>`;
                        });
                        if (data.excluded_files.length > 20) {
                            excludedFilesHtml += `<div class="excluded-file">... 还有 ${data.excluded_files.length - 20} 个文件</div>`;
                        }
                    } else {
                        excludedFilesHtml = '<div class="excluded-file">无被排除文件</div>';
                    }
                    
                    const excludeHtml = `
                        <h3>
                            🛡️ 排除规则
                            <button class="toggle-btn" onclick="toggleExcludeDetails()">查看详情</button>
                        </h3>
                        <div class="exclude-rules">
                            <div class="rule-category">
                                <h4>排除目录</h4>
                                <div class="rule-items">
                                    ${rules['排除目录'].map(dir => `<span class="rule-item">${dir}</span>`).join('')}
                                </div>
                            </div>
                            <div class="rule-category">
                                <h4>排除文件</h4>
                                <div class="rule-items">
                                    ${rules['排除文件'].map(file => `<span class="rule-item">${file}</span>`).join('')}
                                </div>
                            </div>
                            <div class="rule-category">
                                <h4>排除扩展名</h4>
                                <div class="rule-items">
                                    ${rules['排除扩展名'].map(ext => `<span class="rule-item">.${ext}</span>`).join('')}
                                </div>
                            </div>
                        </div>
                        <div id="excludeDetails" style="display:none">
                            <h4>被排除的文件 (${data.excluded_count}个):</h4>
                            <div class="excluded-files">
                                ${excludedFilesHtml}
                            </div>
                        </div>
                    `;
                    document.getElementById('excludePanel').innerHTML = excludeHtml;
                });
        }
        
        // 切换排除详情显示
        function toggleExcludeDetails() {
            const details = document.getElementById('excludeDetails');
            const button = document.querySelector('.toggle-btn');
            if (details.style.display === 'none') {
                details.style.display = 'block';
                button.textContent = '隐藏详情';
            } else {
                details.style.display = 'none';
                button.textContent = '查看详情';
            }
        }
        
        // 显示配置模态框
        function showConfig() {
            document.getElementById('configModal').style.display = 'flex';
        }
        
        // 隐藏配置模态框
        function hideConfig() {
            document.getElementById('configModal').style.display = 'none';
        }
        
        // 保存配置
        function saveConfig() {
            const config = {
                scan_dir: document.getElementById('configScanDir').value,
                exclude_dirs: document.getElementById('configExcludeDirs').value.split(',').map(s => s.trim()).filter(s => s),
                exclude_files: document.getElementById('configExcludeFiles').value.split(',').map(s => s.trim()).filter(s => s),
                exclude_extensions: document.getElementById('configExcludeExtensions').value.split(',').map(s => s.trim()).filter(s => s)
            };
            
            // 这里应该将配置保存到服务器
            // 由于是单文件系统,我们可以通过URL参数传递
            alert('配置已更新,请刷新页面应用新配置。\n注意:需要重新扫描文件列表。');
            hideConfig();
            
            // 重新加载页面并重置扫描
            setTimeout(() => {
                window.location.href = 'backup.php?reset=1';
            }, 1000);
        }
        
        // 添加日志条目
        function addLogEntry(message, type = 'info') {
            const timestamp = new Date().toLocaleTimeString();
            const entry = {
                time: timestamp,
                message: message,
                type: type
            };
            
            logEntries.unshift(entry); // 添加到开头
            
            // 限制日志数量
            if (logEntries.length > 50) {
                logEntries = logEntries.slice(0, 50);
            }
            
            // 更新日志显示
            updateLogDisplay();
        }
        
        // 更新日志显示
        function updateLogDisplay() {
            const logContainer = document.getElementById('log');
            let logHtml = '';
            
            logEntries.forEach(entry => {
                logHtml += `
                    <div class="log-entry ${entry.type}">
                        <strong>[${entry.time}]</strong> ${entry.message}
                    </div>
                `;
            });
            
            logContainer.innerHTML = logHtml;
        }
        
        // 开始备份
        function startBackup() {
            if (isBackupRunning) return;
            
            isBackupRunning = true;
            document.getElementById('startBtn').style.display = 'none';
            document.getElementById('stopBtn').style.display = 'inline-block';
            document.getElementById('spinner').style.display = 'block';
            
            addLogEntry('开始备份进程...', 'info');
            addLogEntry('注意:config.php, backup.php, api.php 等系统文件已被排除', 'info');
            
            // 执行备份
            performBackup();
        }
        
        // 执行备份
        function performBackup() {
            if (!isBackupRunning) return;
            
            fetch('backup.php?action=backup')
                .then(response => response.json())
                .then(data => {
                    if (data.completed) {
                        // 备份完成
                        backupCompleted(data);
                        return;
                    }
                    
                    // 更新进度
                    updateProgress(data);
                    
                    // 显示当前文件信息
                    updateCurrentFile(data.current_file);
                    
                    // 添加日志
                    if (data.result.success) {
                        addLogEntry(`✅ ${data.result.file} - ${data.result.message} (${data.result.size})`, 'success');
                    } else {
                        addLogEntry(`❌ ${data.result.file} - ${data.result.message}`, 'error');
                    }
                    
                    // 如果启用了自动备份,继续下一个文件
                    if (autoBackupEnabled) {
                        setTimeout(performBackup, document.getElementById('interval').value * 1000);
                    }
                })
                .catch(error => {
                    addLogEntry(`请求错误: ${error.message}`, 'error');
                    if (autoBackupEnabled) {
                        setTimeout(performBackup, 5000); // 5秒后重试
                    }
                });
        }
        
        // 更新进度
        function updateProgress(data) {
            const progress = data.progress;
            const progressBar = document.getElementById('progressBar');
            const progressText = document.getElementById('progressText');
            const progressInfo = document.getElementById('progressInfo');
            
            progressBar.style.width = progress.percent + '%';
            progressText.textContent = progress.percent + '%';
            
            const stats = data.stats;
            progressInfo.innerHTML = `
                进度: ${progress.current}/${progress.total} 文件 | 
                成功: ${stats.success} | 
                失败: ${stats.failed} |
                耗时: ${Math.round((Date.now()/1000 - stats.start_time))}秒
            `;
        }
        
        // 更新当前文件信息
        function updateCurrentFile(file) {
            if (!file) return;
            
            const fileSize = formatBytes(file.size);
            const fileInfo = document.getElementById('currentFile');
            
            fileInfo.innerHTML = `
                <h3>📄 当前备份文件</h3>
                <p><strong>文件路径:</strong> ${file.path}</p>
                <p><strong>文件大小:</strong> ${fileSize}</p>
                <p><strong>修改时间:</strong> ${new Date(file.mtime * 1000).toLocaleString()}</p>
                <p><strong>MD5:</strong> ${file.md5.substring(0, 16)}...</p>
            `;
        }
        
        // 备份完成
        function backupCompleted(data) {
            isBackupRunning = false;
            document.getElementById('startBtn').style.display = 'inline-block';
            document.getElementById('stopBtn').style.display = 'none';
            document.getElementById('spinner').style.display = 'none';
            
            addLogEntry(`🎉 备份完成!总计: ${data.stats.success} 成功, ${data.stats.failed} 失败`, 'success');
            addLogEntry(`🚫 系统文件 (config.php, backup.php, api.php) 已被排除,不会备份`, 'info');
            
            // 更新统计信息
            loadStats();
            
            // 显示完成信息
            document.getElementById('currentFile').innerHTML = `
                <h3>✅ 备份完成</h3>
                <p><strong>总文件数:</strong> ${data.stats.total}</p>
                <p><strong>成功:</strong> ${data.stats.success}</p>
                <p><strong>失败:</strong> ${data.stats.failed}</p>
                <p><strong>开始时间:</strong> ${new Date(data.stats.start_time * 1000).toLocaleString()}</p>
                <p><strong>完成时间:</strong> ${new Date().toLocaleString()}</p>
                <p><strong>备注:</strong> 系统文件已被排除,不会备份</p>
            `;
            
            // 重置进度条
            document.getElementById('progressBar').style.width = '100%';
            document.getElementById('progressText').textContent = '100%';
            
            // 如果启用了自动备份,提示用户
            if (autoBackupEnabled) {
                addLogEntry('自动备份已完成一轮,等待下次计划执行', 'info');
            }
        }
        
        // 停止备份
        function stopBackup() {
            isBackupRunning = false;
            document.getElementById('startBtn').style.display = 'inline-block';
            document.getElementById('stopBtn').style.display = 'none';
            document.getElementById('spinner').style.display = 'none';
            
            addLogEntry('备份已停止', 'info');
        }
        
        // 重置备份
        function resetBackup() {
            if (isBackupRunning) {
                if (!confirm('备份正在进行中,确定要重置吗?')) {
                    return;
                }
                stopBackup();
            }
            
            fetch('backup.php?action=reset')
                .then(() => {
                    location.reload();
                });
        }
        
        // 切换自动备份
        function toggleAutoBackup() {
            autoBackupEnabled = document.getElementById('autoBackup').checked;
            const intervalInput = document.getElementById('interval');
            const intervalText = document.getElementById('intervalText');
            
            if (autoBackupEnabled) {
                intervalInput.style.display = 'inline-block';
                intervalText.style.display = 'inline-block';
                
                // 如果备份没有运行,自动开始
                if (!isBackupRunning) {
                    startBackup();
                }
            } else {
                intervalInput.style.display = 'none';
                intervalText.style.display = 'none';
            }
        }
        
        // 格式化字节大小
        function formatBytes(bytes, decimals = 2) {
            if (bytes === 0) return '0 Bytes';
            const k = 1024;
            const dm = decimals < 0 ? 0 : decimals;
            const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
            const i = Math.floor(Math.log(bytes) / Math.log(k));
            return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
        }
        
        // 页面加载时初始化
        window.onload = function() {
            loadStats();
            addLogEntry('系统就绪,可以开始备份', 'info');
            addLogEntry('注意:config.php, backup.php, api.php 等系统文件默认被排除', 'info');
            
            // 检查是否有待备份文件
            fetch('backup.php?action=stats')
                .then(response => response.json())
                .then(data => {
                    if (data.pending > 0) {
                        addLogEntry(`检测到 ${data.pending} 个待备份文件`, 'info');
                        addLogEntry(`检测到 ${data.excluded_count} 个被排除文件`, 'info');
                    }
                });
        };
    </script>
</body>
</html>