<?php
/**
 * 系统升级管理器
 * 处理在线升级的所有功能：备份、更新、数据库升级、清理、回滚
 */

class UpgradeManager {
    
    private $rootDir;
    private $backupDir;
    private $tempDir;
    private $db;
    private $log = [];
    
    public function __construct($rootDir = null, $db = null) {
        $this->rootDir = $rootDir ?: dirname(__DIR__);
        $this->backupDir = $this->rootDir . '/backup/upgrade_' . date('Ymd_His');
        $this->tempDir = $this->rootDir . '/temp/upgrade';
        $this->db = $db;
        
        // 确保必要目录存在
        $this->ensureDirectoryExists($this->rootDir . '/backup');
        $this->ensureDirectoryExists($this->rootDir . '/temp');
        $this->ensureDirectoryExists($this->rootDir . '/logs');
    }
    
    /**
     * 确保目录存在
     */
    private function ensureDirectoryExists($dir) {
        if (!is_dir($dir)) {
            mkdir($dir, 0755, true);
        }
    }
    
    /**
     * 获取日志
     */
    public function getLog() {
        $messages = [];
        foreach ($this->log as $entry) {
            $messages[] = '[' . $entry['time'] . '] ' . $entry['message'];
        }
        return $messages;
    }
    
    /**
     * 添加日志
     */
    private function log($message, $type = 'info') {
        $this->log[] = [
            'time' => date('H:i:s'),
            'message' => $message,
            'type' => $type
        ];
    }
    
    /**
     * 创建备份
     */
    public function createBackup() {
        $this->log('开始创建备份...', 'info');
        
        if (!is_dir($this->backupDir)) {
            mkdir($this->backupDir, 0755, true);
        }
        
        // 需要备份的文件列表
        $filesToBackup = [
            'config.php',
            'admin/',
            'user/',
            'templates/',
            'api/',
            'MPHX/',
            'static/'
        ];
        
        $backedUp = 0;
        foreach ($filesToBackup as $file) {
            $source = $this->rootDir . '/' . $file;
            $dest = $this->backupDir . '/' . $file;
            
            if (file_exists($source)) {
                if (is_dir($source)) {
                    $this->copyDirectory($source, $dest);
                } else {
                    copy($source, $dest);
                }
                $backedUp++;
            }
        }
        
        // 备份数据库
        $this->backupDatabase();
        
        $this->log("备份完成，共备份 {$backedUp} 项", 'success');
        return $this->backupDir;
    }
    
    /**
     * 复制目录
     */
    private function copyDirectory($source, $dest) {
        if (!is_dir($dest)) {
            mkdir($dest, 0755, true);
        }
        
        $dir = opendir($source);
        while (($file = readdir($dir)) !== false) {
            if ($file == '.' || $file == '..') continue;
            
            $srcPath = $source . '/' . $file;
            $destPath = $dest . '/' . $file;
            
            if (is_dir($srcPath)) {
                $this->copyDirectory($srcPath, $destPath);
            } else {
                copy($srcPath, $destPath);
            }
        }
        closedir($dir);
    }
    
    /**
     * 备份数据库
     */
    private function backupDatabase() {
        $this->log('备份数据库...', 'info');
        
        $dbConfig = $this->getDbConfig();
        if (!$dbConfig) {
            $this->log('无法读取数据库配置', 'error');
            return false;
        }
        
        $backupFile = $this->backupDir . '/database_backup.sql';
        
        // 首先尝试使用mysqldump备份
        $command = sprintf(
            'mysqldump -h%s -u%s -p%s %s > %s 2>&1',
            escapeshellarg($dbConfig['host']),
            escapeshellarg($dbConfig['user']),
            escapeshellarg($dbConfig['pass']),
            escapeshellarg($dbConfig['name']),
            escapeshellarg($backupFile)
        );
        
        exec($command, $output, $returnCode);
        
        if ($returnCode === 0 && file_exists($backupFile) && filesize($backupFile) > 0) {
            $this->log('数据库备份完成 (mysqldump)', 'success');
            return true;
        }
        
        // 如果mysqldump失败，使用PHP方式备份
        $this->log('mysqldump失败，使用PHP方式备份...', 'warning');
        return $this->backupDatabasePHP($dbConfig, $backupFile);
    }
    
    /**
     * 使用PHP方式备份数据库
     */
    private function backupDatabasePHP($dbConfig, $backupFile) {
        try {
            $conn = mysqli_connect($dbConfig['host'], $dbConfig['user'], $dbConfig['pass'], $dbConfig['name']);
            if (!$conn) {
                $this->log('数据库连接失败: ' . mysqli_connect_error(), 'error');
                return false;
            }
            
            mysqli_set_charset($conn, 'utf8mb4');
            
            $sql = "-- MLEOE Database Backup\n";
            $sql .= "-- Generated: " . date('Y-m-d H:i:s') . "\n";
            $sql .= "-- Database: " . $dbConfig['name'] . "\n\n";
            $sql .= "SET FOREIGN_KEY_CHECKS=0;\n\n";
            
            // 获取所有表
            $tables = [];
            $result = mysqli_query($conn, "SHOW TABLES");
            while ($row = mysqli_fetch_row($result)) {
                $tables[] = $row[0];
            }
            
            foreach ($tables as $table) {
                // 获取表结构
                $result = mysqli_query($conn, "SHOW CREATE TABLE `$table`");
                $row = mysqli_fetch_row($result);
                $sql .= "\n-- Table structure for `$table`\n";
                $sql .= "DROP TABLE IF EXISTS `$table`;\n";
                $sql .= $row[1] . ";\n\n";
                
                // 获取表数据
                $result = mysqli_query($conn, "SELECT * FROM `$table`");
                if (mysqli_num_rows($result) > 0) {
                    $sql .= "-- Dumping data for `$table`\n";
                    while ($row = mysqli_fetch_assoc($result)) {
                        $columns = array_keys($row);
                        $values = array_map(function($v) use ($conn) {
                            if ($v === null) return 'NULL';
                            return "'" . mysqli_real_escape_string($conn, $v) . "'";
                        }, array_values($row));
                        
                        $sql .= "INSERT INTO `$table` (`" . implode('`, `', $columns) . "`) VALUES (" . implode(', ', $values) . ");\n";
                    }
                    $sql .= "\n";
                }
            }
            
            $sql .= "SET FOREIGN_KEY_CHECKS=1;\n";
            
            file_put_contents($backupFile, $sql);
            mysqli_close($conn);
            
            if (file_exists($backupFile) && filesize($backupFile) > 0) {
                $this->log('数据库备份完成 (PHP方式)', 'success');
                return true;
            } else {
                $this->log('PHP方式备份失败', 'error');
                return false;
            }
        } catch (Exception $e) {
            $this->log('数据库备份异常: ' . $e->getMessage(), 'error');
            return false;
        }
    }
    
    /**
     * 获取数据库配置
     */
    private function getDbConfig() {
        $configFile = $this->rootDir . '/config.php';
        if (file_exists($configFile)) {
            $config = include $configFile;
            return [
                'host' => $config['host'] ?? 'localhost',
                'user' => $config['user'] ?? 'root',
                'pass' => $config['pwd'] ?? '',
                'name' => $config['dbname'] ?? 'mleoe'
            ];
        }
        return null;
    }
    
    /**
     * 下载更新包
     */
    public function downloadUpdate($downloadUrl) {
        $this->log('开始下载更新包...', 'info');
        
        if (!is_dir($this->tempDir)) {
            mkdir($this->tempDir, 0755, true);
        }
        
        // 根据URL判断文件类型
        if (strpos($downloadUrl, '.tar.gz') !== false) {
            $zipFile = $this->tempDir . '/update.tar.gz';
        } else {
            $zipFile = $this->tempDir . '/update.zip';
        }
        
        // 使用cURL下载
        $ch = curl_init($downloadUrl);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($ch, CURLOPT_MAXREDIRS, 5);
        curl_setopt($ch, CURLOPT_TIMEOUT, 300);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_USERAGENT, 'MLEOE-Upgrade/1.0');
        
        $data = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
        $curlError = curl_error($ch);
        curl_close($ch);
        
        if ($curlError) {
            $this->log('下载错误: ' . $curlError, 'error');
            return false;
        }
        
        if ($httpCode !== 200) {
            $this->log('下载失败，HTTP状态码: ' . $httpCode, 'error');
            return false;
        }
        
        if (empty($data)) {
            $this->log('下载内容为空', 'error');
            return false;
        }
        
        // 检查文件类型 (支持 zip 和 tar.gz)
        $isValidType = strpos($contentType, 'zip') !== false || 
                       strpos($contentType, 'octet-stream') !== false || 
                       strpos($contentType, 'gzip') !== false ||
                       strpos($contentType, 'tar') !== false ||
                       $contentType === '';
        
        if (!$isValidType) {
            $this->log('下载的文件类型不正确: ' . $contentType, 'warning');
            // 继续处理，因为有些服务器可能返回错误的Content-Type
        }
        
        file_put_contents($zipFile, $data);
        
        // 验证文件大小
        $fileSize = filesize($zipFile);
        if ($fileSize < 1024) {
            $this->log('更新包文件异常，大小: ' . $fileSize . ' 字节', 'error');
            unlink($zipFile);
            return false;
        }
        
        $this->log('更新包下载完成，大小: ' . $this->formatBytes($fileSize), 'success');
        
        // 自动解压
        return $this->extractUpdate($zipFile);
    }
    
    /**
     * 格式化字节大小
     */
    private function formatBytes($bytes, $precision = 2) {
        $units = ['B', 'KB', 'MB', 'GB', 'TB'];
        $bytes = max($bytes, 0);
        $pow = floor(($bytes ? log($bytes) : 0) / log(1024));
        $pow = min($pow, count($units) - 1);
        $bytes /= pow(1024, $pow);
        return round($bytes, $precision) . ' ' . $units[$pow];
    }
    
    /**
     * 解压更新包
     */
    public function extractUpdate($zipFile) {
        $this->log('开始解压更新包...', 'info');
        
        $extractDir = $this->tempDir . '/extracted';
        
        if (!is_dir($extractDir)) {
            mkdir($extractDir, 0755, true);
        }
        
        // 检查文件类型
        $fileExt = strtolower(pathinfo($zipFile, PATHINFO_EXTENSION));
        $fileName = basename($zipFile);
        
        // 支持 tar.gz 格式
        if (strpos($fileName, '.tar.gz') !== false || $fileExt === 'gz') {
            return $this->extractTarGz($zipFile, $extractDir);
        }
        
        // 支持 zip 格式
        $zip = new ZipArchive();
        if ($zip->open($zipFile) === true) {
            $zip->extractTo($extractDir);
            $zip->close();
            $this->log('解压完成', 'success');
            return $extractDir;
        } else {
            $this->log('解压失败', 'error');
            return false;
        }
    }
    
    /**
     * 解压 tar.gz 文件
     */
    private function extractTarGz($tarGzFile, $extractDir) {
        $this->log('解压 tar.gz 格式...', 'info');
        
        // 方法1: 使用系统 tar 命令
        if (function_exists('exec')) {
            $command = sprintf('tar -xzf %s -C %s 2>&1', escapeshellarg($tarGzFile), escapeshellarg($extractDir));
            exec($command, $output, $returnCode);
            
            if ($returnCode === 0) {
                $this->log('解压完成 (tar命令)', 'success');
                return $extractDir;
            }
            $this->log('tar命令解压失败，尝试PHP方式...', 'warning');
        }
        
        // 方法2: 使用PHP PharData
        if (class_exists('PharData')) {
            try {
                // 先解压 .gz 得到 .tar
                $tarFile = str_replace('.tar.gz', '.tar', $tarGzFile);
                $pharGz = new PharData($tarGzFile);
                $pharGz->decompress(); // 解压为 .tar
                
                // 再解压 .tar
                $phar = new PharData($tarFile);
                $phar->extractTo($extractDir);
                
                // 清理临时 .tar 文件
                if (file_exists($tarFile)) {
                    unlink($tarFile);
                }
                
                $this->log('解压完成 (PharData)', 'success');
                return $extractDir;
            } catch (Exception $e) {
                $this->log('PharData解压失败: ' . $e->getMessage(), 'warning');
            }
        }
        
        $this->log('解压失败，请确保系统支持tar命令或PharData扩展', 'error');
        return false;
    }
    
    /**
     * 应用文件更新
     */
    public function applyFileUpdate($extractDir) {
        $this->log('开始应用文件更新...', 'info');
        
        // 查找升级包中的files目录
        $filesDir = $this->findFilesDirectory($extractDir);
        
        if (!$filesDir) {
            $this->log('未找到files目录，直接复制所有文件', 'info');
            $filesDir = $extractDir;
        }
        
        $this->copyDirectory($filesDir, $this->rootDir);
        $this->log('文件更新完成', 'success');
        
        return true;
    }
    
    /**
     * 复制文件到目标位置（支持admin目录映射）
     */
    public function copyFiles($source, $dest, $admin_dir = 'admin') {
        $this->log('开始复制文件...', 'info');
        
        if (!is_dir($source)) {
            $this->log('源目录不存在: ' . $source, 'error');
            return false;
        }
        
        // 确保路径以 / 结尾
        $source = rtrim($source, '/') . '/';
        $dest = rtrim($dest, '/') . '/';
        
        $files = scandir($source);
        $copied = 0;
        
        $this->log("源目录: {$source}, 目标目录: {$dest}", 'info');
        $this->log("发现文件数: " . (count($files) - 2), 'info'); // 减去 . 和 ..
        
        foreach ($files as $file) {
            if ($file == '.' || $file == '..') continue;
            
            $src_file = $source . $file;
            
            // 如果是admin目录，复制到当前配置的后台目录
            if ($file == 'admin' && is_dir($src_file)) {
                $dest_file = $dest . $admin_dir . '/';
            } else {
                $dest_file = $dest . $file;
            }
            
            $this->log("处理: {$src_file} -> {$dest_file}", 'info');
            
            if (is_dir($src_file)) {
                $count = $this->copyDirectoryWithCount($src_file . '/', $dest_file . '/');
                $copied += $count;
                $this->log("目录复制完成: {$file} ({$count} 项)", 'info');
            } else {
                // 确保目标目录存在
                $dest_dir = dirname($dest_file);
                if (!is_dir($dest_dir)) {
                    mkdir($dest_dir, 0755, true);
                }
                
                if (copy($src_file, $dest_file)) {
                    $copied++;
                    $this->log("复制文件: {$file}", 'info');
                } else {
                    $this->log("复制失败: {$file}", 'error');
                }
            }
        }
        
        $this->log("文件复制完成，共复制 {$copied} 项", 'success');
        return true;
    }
    
    /**
     * 复制目录并返回复制的文件数
     */
    private function copyDirectoryWithCount($source, $dest) {
        if (!is_dir($dest)) {
            mkdir($dest, 0755, true);
        }
        
        $count = 0;
        $dir = opendir($source);
        while (($file = readdir($dir)) !== false) {
            if ($file == '.' || $file == '..') continue;
            
            $srcPath = $source . '/' . $file;
            $destPath = $dest . '/' . $file;
            
            if (is_dir($srcPath)) {
                $count += $this->copyDirectoryWithCount($srcPath, $destPath);
            } else {
                if (copy($srcPath, $destPath)) {
                    $count++;
                }
            }
        }
        closedir($dir);
        
        return $count;
    }
    
    /**
     * 查找files目录
     */
    private function findFilesDirectory($dir) {
        // 首先检查当前目录是否有files子目录（支持解压后直接是升级包内容）
        $filesDir = $dir . '/files';
        if (is_dir($filesDir)) {
            return $filesDir;
        }
        
        // 检查是否有升级包目录（如upgrade_v1.0.2）
        $subdirs = glob($dir . '/*', GLOB_ONLYDIR);
        foreach ($subdirs as $subdir) {
            $filesDir = $subdir . '/files';
            if (is_dir($filesDir)) {
                return $filesDir;
            }
        }
        
        return null;
    }
    
    /**
     * 更新数据库
     */
    public function updateDatabase($extractDir) {
        $this->log('开始更新数据库...', 'info');
        
        // 查找SQL目录
        $sqlDir = $this->findSqlDirectory($extractDir);
        
        if (!$sqlDir || !is_dir($sqlDir)) {
            $this->log('未找到SQL文件，跳过数据库更新', 'info');
            return true;
        }
        
        $dbConfig = $this->getDbConfig();
        if (!$dbConfig) {
            $this->log('无法读取数据库配置', 'error');
            return false;
        }
        
        $conn = mysqli_connect($dbConfig['host'], $dbConfig['user'], $dbConfig['pass'], $dbConfig['name']);
        if (!$conn) {
            $this->log('数据库连接失败', 'error');
            return false;
        }
        
        mysqli_set_charset($conn, 'utf8mb4');
        
        // 获取所有SQL文件
        $sqlFiles = glob($sqlDir . '/*.sql');
        sort($sqlFiles);
        
        $imported = 0;
        foreach ($sqlFiles as $sqlFile) {
            if ($this->executeSqlFile($sqlFile, $conn)) {
                $tableName = basename($sqlFile, '.sql');
                $this->log("导入表: {$tableName}", 'success');
                $imported++;
            }
        }
        
        mysqli_close($conn);
        $this->log("数据库更新完成，共导入 {$imported} 个表", 'success');
        
        return true;
    }
    
    /**
     * 查找SQL目录
     */
    private function findSqlDirectory($dir) {
        $sqlDir = $dir . '/sql';
        if (is_dir($sqlDir)) {
            return $sqlDir;
        }
        
        $subdirs = glob($dir . '/*', GLOB_ONLYDIR);
        foreach ($subdirs as $subdir) {
            $sqlDir = $subdir . '/sql';
            if (is_dir($sqlDir)) {
                return $sqlDir;
            }
        }
        
        return null;
    }
    
    /**
     * 执行SQL文件
     */
    private function executeSqlFile($file, $conn) {
        $sql = file_get_contents($file);
        if (empty($sql)) return true;
        
        // 分割多条SQL语句
        $queries = array_filter(array_map('trim', explode(';', $sql)));
        
        foreach ($queries as $query) {
            if (!empty($query)) {
                // 添加 IF NOT EXISTS 到 CREATE TABLE
                if (stripos($query, 'CREATE TABLE') !== false && stripos($query, 'IF NOT EXISTS') === false) {
                    $query = preg_replace('/CREATE TABLE\s+(`?\w+`?)/i', 'CREATE TABLE IF NOT EXISTS $1', $query);
                }
                
                // 跳过 DROP TABLE
                if (stripos($query, 'DROP TABLE') !== false) {
                    continue;
                }
                
                mysqli_query($conn, $query);
            }
        }
        
        return true;
    }
    
    /**
     * 清理过时文件
     */
    public function cleanupObsoleteFiles() {
        $this->log('开始清理过时文件...', 'info');
        
        $obsoleteFiles = [
            'apply_optimization.php',
            'finance_integration/',
            'test_rewrite/',
            '*.tmp',
            '*.temp',
            '*.bak'
        ];
        
        $protectedFiles = [
            'config.php',
            'install/',
            'user/upload/',
            'backup/'
        ];
        
        $deleted = 0;
        foreach ($obsoleteFiles as $file) {
            if (strpos($file, '*') !== false) {
                // 通配符模式
                $matches = $this->scanWildcard($file, $this->rootDir);
                foreach ($matches as $match) {
                    if ($this->deleteFile($match, $protectedFiles)) {
                        $deleted++;
                    }
                }
            } else {
                if ($this->deleteFile($file, $protectedFiles)) {
                    $deleted++;
                }
            }
        }
        
        $this->log("清理完成，共删除 {$deleted} 个文件/目录", 'success');
        return true;
    }
    
    /**
     * 扫描通配符文件
     */
    private function scanWildcard($pattern, $dir) {
        $matches = [];
        $iterator = new RecursiveIteratorIterator(
            new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS)
        );
        
        foreach ($iterator as $file) {
            if (fnmatch($pattern, $file->getFilename())) {
                $matches[] = str_replace($dir . '/', '', $file->getPathname());
            }
        }
        
        return $matches;
    }
    
    /**
     * 删除文件（带保护检查）
     */
    private function deleteFile($file, $protectedFiles) {
        $fullPath = $this->rootDir . '/' . $file;
        
        // 检查是否在白名单中
        foreach ($protectedFiles as $protected) {
            if (strpos($file, $protected) === 0) {
                return false;
            }
        }
        
        if (!file_exists($fullPath)) {
            return false;
        }
        
        if (is_dir($fullPath)) {
            $this->deleteDirectory($fullPath);
        } else {
            unlink($fullPath);
        }
        
        return true;
    }
    
    /**
     * 删除目录
     */
    private function deleteDirectory($dir) {
        $files = array_diff(scandir($dir), ['.', '..']);
        foreach ($files as $file) {
            $path = $dir . '/' . $file;
            if (is_dir($path)) {
                $this->deleteDirectory($path);
            } else {
                unlink($path);
            }
        }
        return rmdir($dir);
    }
    
    /**
     * 回滚到之前版本
     */
    public function rollback($backupDir = null) {
        $this->log('开始回滚...', 'info');
        
        if (!$backupDir) {
            // 查找最新的备份
            $backups = glob($this->rootDir . '/backup/upgrade_*', GLOB_ONLYDIR);
            if (empty($backups)) {
                $this->log('没有找到可用的备份', 'error');
                return false;
            }
            rsort($backups);
            $backupDir = $backups[0];
        }
        
        if (!is_dir($backupDir)) {
            $this->log('备份目录不存在: ' . $backupDir, 'error');
            return false;
        }
        
        // 恢复文件
        $this->log('恢复文件...', 'info');
        $this->copyDirectory($backupDir, $this->rootDir);
        
        // 恢复数据库
        $dbBackup = $backupDir . '/database_backup.sql';
        if (file_exists($dbBackup)) {
            $this->log('恢复数据库...', 'info');
            $this->restoreDatabase($dbBackup);
        }
        
        $this->log('回滚完成', 'success');
        return true;
    }
    
    /**
     * 恢复数据库
     */
    private function restoreDatabase($sqlFile) {
        $dbConfig = $this->getDbConfig();
        if (!$dbConfig) {
            $this->log('无法读取数据库配置', 'error');
            return false;
        }
        
        // 首先尝试使用mysql命令恢复
        $command = sprintf(
            'mysql -h%s -u%s -p%s %s < %s 2>&1',
            escapeshellarg($dbConfig['host']),
            escapeshellarg($dbConfig['user']),
            escapeshellarg($dbConfig['pass']),
            escapeshellarg($dbConfig['name']),
            escapeshellarg($sqlFile)
        );
        
        exec($command, $output, $returnCode);
        
        if ($returnCode === 0) {
            $this->log('数据库恢复完成 (mysql命令)', 'success');
            return true;
        }
        
        // 如果命令失败，使用PHP方式恢复
        $this->log('mysql命令失败，使用PHP方式恢复...', 'warning');
        return $this->restoreDatabasePHP($dbConfig, $sqlFile);
    }
    
    /**
     * 使用PHP方式恢复数据库
     */
    private function restoreDatabasePHP($dbConfig, $sqlFile) {
        try {
            $conn = mysqli_connect($dbConfig['host'], $dbConfig['user'], $dbConfig['pass'], $dbConfig['name']);
            if (!$conn) {
                $this->log('数据库连接失败: ' . mysqli_connect_error(), 'error');
                return false;
            }
            
            mysqli_set_charset($conn, 'utf8mb4');
            
            // 读取SQL文件
            $sql = file_get_contents($sqlFile);
            if (empty($sql)) {
                $this->log('SQL文件为空', 'error');
                return false;
            }
            
            // 分割SQL语句
            $sql = str_replace("\r\n", "\n", $sql);
            $sql = str_replace("\r", "\n", $sql);
            $queries = array_filter(array_map('trim', explode(";\n", $sql)));
            
            $success = 0;
            $failed = 0;
            
            foreach ($queries as $query) {
                if (empty($query) || substr($query, 0, 2) == '--' || substr($query, 0, 2) == '/*') {
                    continue;
                }
                
                if (mysqli_query($conn, $query)) {
                    $success++;
                } else {
                    $failed++;
                    // 记录错误但不中断
                    if ($failed <= 5) {
                        $this->log('SQL执行错误: ' . mysqli_error($conn), 'warning');
                    }
                }
            }
            
            mysqli_close($conn);
            
            $this->log("数据库恢复完成 (PHP方式) - 成功: {$success}, 失败: {$failed}", 'success');
            return true;
            
        } catch (Exception $e) {
            $this->log('数据库恢复异常: ' . $e->getMessage(), 'error');
            return false;
        }
    }
    
    /**
     * 清理临时文件
     */
    public function cleanup() {
        if (is_dir($this->tempDir)) {
            $this->deleteDirectory($this->tempDir);
        }
        $this->log('临时文件已清理', 'info');
    }
}
