// 网盘管理系统 - 服务端逻辑

const fs = require('fs');
const path = require('path');
const { promisify } = require('util');
const { spawn } = require('child_process');
const formidable = require('formidable');

const mkdir = promisify(fs.mkdir);
const readdir = promisify(fs.readdir);
const stat = promisify(fs.stat);
const access = promisify(fs.access);
const copyFile = promisify(fs.copyFile);
const rmdir = promisify(fs.rmdir);
const unlink = promisify(fs.unlink);

class DiskManager {
    constructor() {
        // 用户数据根目录
        this.usersDir = path.join(__dirname, 'users');
        this.tempDir = path.join(__dirname, 'temp');
        this.pythonDir = path.join(__dirname, 'python');
    }

    // 根据用户名获取用户的数据目录
    getUserRootDir(username) {
        if (!username) {
            throw new Error('用户名不能为空');
        }
        // 用户名转换为小写，确保一致性
        const normalizedUsername = username.toLowerCase();
        return path.join(this.usersDir, normalizedUsername, 'disk_data');
    }

    // 确保用户目录存在
    async ensureUserDir(username) {
        const userRootDir = this.getUserRootDir(username);
        try {
            await access(userRootDir);
        } catch (error) {
            await mkdir(userRootDir, { recursive: true });
            console.log('创建用户disk_data目录:', userRootDir);
        }
    }

    // 从请求中获取用户名（支持查询参数和请求体）
    getUsernameFromRequest(req, fields = null) {
        // 先尝试从查询参数获取
        const url = new URL(req.url, `http://${req.headers.host}`);
        let username = url.searchParams.get('username');
        
        // 如果查询参数没有，尝试从请求体（fields）获取
        if (!username && fields) {
            username = Array.isArray(fields.username) ? fields.username[0] : (fields.username || null);
        }
        
        return username;
    }

    // 获取Python命令（尝试python或python3）
    async getPythonCommand() {
        return new Promise((resolve) => {
            const python = spawn('python', ['--version']);
            python.on('close', (code) => {
                if (code === 0) {
                    resolve('python');
                } else {
                    const python3 = spawn('python3', ['--version']);
                    python3.on('close', (code) => {
                        resolve(code === 0 ? 'python3' : null);
                    });
                }
            });
            python.on('error', () => {
                const python3 = spawn('python3', ['--version']);
                python3.on('close', (code) => {
                    resolve(code === 0 ? 'python3' : null);
                });
                python3.on('error', () => resolve(null));
            });
        });
    }

    // 调用Python抠图脚本
    async runImageMatting(inputFolder, outputFolder, onProgress) {
        const pythonCmd = await this.getPythonCommand();
        if (!pythonCmd) {
            throw new Error('未找到Python环境，请安装Python 3.7+');
        }

        const pythonExe = path.join(this.pythonDir, 'venv', 'Scripts', 'python.exe');
        const scriptPath = path.join(this.pythonDir, 'rembg-matting.py');
        
        // 检查是否使用虚拟环境
        const usePython = await new Promise((resolve) => {
            fs.access(pythonExe, fs.constants.F_OK, (err) => {
                resolve(err ? pythonCmd : pythonExe);
            });
        });

        return new Promise((resolve, reject) => {
            console.log('\n' + '='.repeat(70));
            console.log('【Python】🚀 启动AI抠图进程');
            console.log('='.repeat(70));
            console.log('【Python】命令:', usePython);
            console.log('【Python】脚本:', scriptPath);
            console.log('【Python】输入文件夹:', inputFolder);
            console.log('【Python】输出文件夹:', outputFolder);
            console.log('='.repeat(70) + '\n');
            
            // 使用 -u 参数让Python输出无缓冲
            const python = spawn(usePython, ['-u', scriptPath, inputFolder, outputFolder]);
            
            console.log('【Python】进程已启动，PID:', python.pid);

            let stdout = '';
            let stderr = '';
            let processed = 0;

            python.stdout.on('data', (data) => {
                const output = data.toString();
                stdout += output;
                // 分行打印，保持格式
                const lines = output.split('\n');
                lines.forEach(line => {
                    if (line.trim()) {
                        console.log(`【Python】抠图: ${line}`);
                        
                        // 捕获进度信息: PROGRESS: 1/22
                        const progressMatch = line.match(/PROGRESS:\s*(\d+)\/(\d+)/);
                        if (progressMatch) {
                            const current = parseInt(progressMatch[1], 10);
                            const total = parseInt(progressMatch[2], 10);
                            console.log(`【Python】进度: ${current}/${total} (${Math.round(current/total*100)}%)`);
                            
                            // 调用进度回调
                            if (onProgress) {
                                onProgress(current, total);
                            }
                        }
                    }
                });

                const successMatch = output.match(/成功:?\s*(\d+)|成功\s*(\d+)|Success:\s*(\d+)/);
                if (successMatch) {
                    processed = parseInt(successMatch[1] || successMatch[2] || successMatch[3], 10);
                }
            });

            python.stderr.on('data', (data) => {
                const error = data.toString();
                stderr += error;
                // 实时打印stderr
                const lines = error.split('\n');
                lines.forEach(line => {
                    if (line.trim()) {
                        console.error(`【Python】抠图错误: ${line}`);
                    }
                });
            });

            python.on('close', (code) => {
                console.log('\n' + '='.repeat(70));
                console.log(`【Python】抠图进程结束，退出码: ${code}`);
                if (code === 0) {
                    console.log(`【Python】✅ 抠图成功！处理了 ${processed} 张图片`);
                    console.log('='.repeat(70) + '\n');
                    resolve({ success: true, processed, message: '抠图完成' });
                } else {
                    console.error(`【Python】❌ 抠图失败，退出码: ${code}`);
                    if (stderr) console.error(`【Python】错误详情:\n${stderr}`);
                    console.log('='.repeat(70) + '\n');
                    reject(new Error(`抠图失败，退出码: ${code}\n${stderr}`));
                }
            });

            python.on('error', (error) => {
                console.error(`【Python】❌ 启动进程失败:`, error);
                reject(new Error(`启动Python进程失败: ${error.message}`));
            });
        });
    }

    // 调用Python裁剪脚本
    async runCutMiniSize(inputFolder, outputFolder, onProgress) {
        const pythonCmd = await this.getPythonCommand();
        if (!pythonCmd) {
            throw new Error('未找到Python环境，请安装Python 3.7+');
        }

        const pythonExe = path.join(this.pythonDir, 'venv', 'Scripts', 'python.exe');
        const scriptPath = path.join(this.pythonDir, 'cut-mini-size.py');
        
        const usePython = await new Promise((resolve) => {
            fs.access(pythonExe, fs.constants.F_OK, (err) => {
                resolve(err ? pythonCmd : pythonExe);
            });
        });

        return new Promise((resolve, reject) => {
            console.log('\n' + '='.repeat(70));
            console.log('【Python】✂️ 启动智能裁剪进程');
            console.log('='.repeat(70));
            console.log('【Python】命令:', usePython);
            console.log('【Python】脚本:', scriptPath);
            console.log('【Python】输入文件夹:', inputFolder);
            console.log('【Python】输出文件夹:', outputFolder);
            console.log('='.repeat(70) + '\n');
            
            // 使用 -u 参数让Python输出无缓冲
            const python = spawn(usePython, ['-u', scriptPath, inputFolder, outputFolder]);
            
            console.log('【Python】进程已启动，PID:', python.pid);

            let stdout = '';
            let stderr = '';
            let processed = 0;
            let width = 0;
            let height = 0;

            python.stdout.on('data', (data) => {
                const output = data.toString();
                stdout += output;
                // 分行打印，保持格式
                const lines = output.split('\n');
                lines.forEach(line => {
                    if (line.trim()) {
                        console.log(`【Python】裁剪: ${line}`);
                        
                        // 捕获进度信息: PROGRESS: 1/22
                        const progressMatch = line.match(/PROGRESS:\s*(\d+)\/(\d+)/);
                        if (progressMatch) {
                            const current = parseInt(progressMatch[1], 10);
                            const total = parseInt(progressMatch[2], 10);
                            console.log(`【Python】进度: ${current}/${total} (${Math.round(current/total*100)}%)`);
                            
                            // 调用进度回调
                            if (onProgress) {
                                onProgress(current, total);
                            }
                        }
                    }
                });

                const successMatch = output.match(/成功:?\s*(\d+)|成功\s*(\d+)|Success:\s*(\d+)/);
                if (successMatch) {
                    processed = parseInt(successMatch[1] || successMatch[2] || successMatch[3], 10);
                }

                const sizeMatch = output.match(/width=(\d+).*height=(\d+)/);
                if (sizeMatch) {
                    width = parseInt(sizeMatch[1], 10);
                    height = parseInt(sizeMatch[2], 10);
                }
            });

            python.stderr.on('data', (data) => {
                const error = data.toString();
                stderr += error;
                // 实时打印stderr
                const lines = error.split('\n');
                lines.forEach(line => {
                    if (line.trim()) {
                        console.error(`【Python】裁剪错误: ${line}`);
                    }
                });
            });

            python.on('close', (code) => {
                console.log('\n' + '='.repeat(70));
                console.log(`【Python】裁剪进程结束，退出码: ${code}`);
                if (code === 0) {
                    console.log(`【Python】✅ 裁剪成功！处理了 ${processed} 张图片`);
                    console.log(`【Python】📐 最终尺寸: ${width}x${height}`);
                    console.log('='.repeat(70) + '\n');
                    resolve({ 
                        success: true, 
                        processed, 
                        width, 
                        height,
                        message: `裁剪完成，尺寸: ${width}x${height}` 
                    });
                } else {
                    console.error(`【Python】❌ 裁剪失败，退出码: ${code}`);
                    if (stderr) console.error(`【Python】错误详情:\n${stderr}`);
                    console.log('='.repeat(70) + '\n');
                    reject(new Error(`裁剪失败，退出码: ${code}\n${stderr}`));
                }
            });

            python.on('error', (error) => {
                console.error(`【Python】❌ 启动进程失败:`, error);
                reject(new Error(`启动Python进程失败: ${error.message}`));
            });
        });
    }

    // 获取安全的文件路径（基于用户名）
    getSafePath(relativePath, username) {
        if (!username) {
            throw new Error('用户名不能为空');
        }
        const userRootDir = this.getUserRootDir(username);
        // 移除开头的斜杠
        relativePath = relativePath.replace(/^\/+/, '');
        // 解析路径，防止目录遍历攻击
        const fullPath = path.join(userRootDir, relativePath);
        // 确保路径在用户根目录内
        if (!fullPath.startsWith(userRootDir)) {
            throw new Error('非法路径');
        }
        return fullPath;
    }

    // 检查文件夹是否包含预览图
    async checkFolderPreview(folderPath) {
        const commonNames = ['01.png', '00.png', '001.png', '0001.png', '1.png', '0.png'];
        
        try {
            const items = await readdir(folderPath);
            
            // 首先检查常见的帧文件名
            for (const name of commonNames) {
                if (items.includes(name)) {
                    return {
                        hasPreview: true,
                        previewFile: name
                    };
                }
            }
            
            // 检查是否有任何PNG文件
            const pngFiles = items.filter(item => item.toLowerCase().endsWith('.png'));
            if (pngFiles.length > 0) {
                // 按文件名排序，取第一个
                pngFiles.sort();
                return {
                    hasPreview: true,
                    previewFile: pngFiles[0]
                };
            }
            
            return {
                hasPreview: false,
                previewFile: null
            };
        } catch (error) {
            return {
                hasPreview: false,
                previewFile: null
            };
        }
    }

    // 检查文件夹是否需要抠图（检测PNG图片是否有非透明背景）
    async checkNeedMatting(folderPath) {
        try {
            const sharp = require('sharp');
            const items = await readdir(folderPath);
            
            // 获取所有PNG文件（只计算一次，不区分大小写）
            const pngFiles = items.filter(item => item.toLowerCase().endsWith('.png'));
            
            if (pngFiles.length === 0) {
                return {
                    needsMatting: false,
                    pngCount: 0
                };
            }
            
            // 检查前3张PNG图片是否有非透明背景（采样检测，提高性能）
            const samplesToCheck = Math.min(3, pngFiles.length);
            let hasOpaqueBackground = false;
            
            for (let i = 0; i < samplesToCheck; i++) {
                const filePath = path.join(folderPath, pngFiles[i]);
                const hasOpaque = await this.checkImageHasOpaqueBackground(filePath);
                if (hasOpaque) {
                    hasOpaqueBackground = true;
                    break; // 只要有一张有非透明背景，就需要抠图
                }
            }
            
            return {
                needsMatting: hasOpaqueBackground,
                pngCount: pngFiles.length
            };
        } catch (error) {
            console.error('[DiskManager] 检查抠图需求失败:', error);
            return {
                needsMatting: true, // 出错时默认显示抠图选项（保守策略）
                pngCount: 0
            };
        }
    }

    // 检查单个图片是否有非透明背景
    async checkImageHasOpaqueBackground(imagePath) {
        try {
            const sharp = require('sharp');
            const image = sharp(imagePath);
            const metadata = await image.metadata();
            
            // 如果图片没有alpha通道，肯定有不透明背景
            if (!metadata.hasAlpha) {
                return true;
            }
            
            // 获取图片数据，快速检查边缘像素
            const { data, info } = await image
                .ensureAlpha()
                .raw()
                .toBuffer({ resolveWithObject: true });
            
            const { width, height, channels } = info;
            
            // 采样检测：检查四个角和边缘的像素
            const samplePoints = [
                { x: 0, y: 0 }, // 左上
                { x: width - 1, y: 0 }, // 右上
                { x: 0, y: height - 1 }, // 左下
                { x: width - 1, y: height - 1 }, // 右下
                { x: Math.floor(width / 2), y: 0 }, // 顶部中间
                { x: Math.floor(width / 2), y: height - 1 }, // 底部中间
            ];
            
            let opaqueCount = 0;
            for (const point of samplePoints) {
                const idx = (point.y * width + point.x) * channels;
                const alpha = data[idx + 3];
                
                // 如果alpha接近255（不透明），说明可能有背景
                if (alpha > 250) {
                    const r = data[idx];
                    const g = data[idx + 1];
                    const b = data[idx + 2];
                    
                    // 检查是否是白色或浅色背景（可能需要抠图）
                    if (r > 230 && g > 230 && b > 230) {
                        opaqueCount++;
                    }
                }
            }
            
            // 如果超过一半的采样点都是不透明的浅色，判断为需要抠图
            return opaqueCount >= 3;
            
        } catch (error) {
            console.error('[DiskManager] 检查图片背景失败:', error);
            return true; // 出错时默认需要抠图
        }
    }

    // 处理文件列表请求
    async handleListRequest(req, res) {
        try {
            const url = new URL(req.url, `http://${req.headers.host}`);
            const username = url.searchParams.get('username');
            if (!username) {
                res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' });
                res.end(JSON.stringify({ success: false, error: '缺少用户名参数' }));
                return;
            }
            
            const relativePath = url.searchParams.get('path') || '';
            const recursive = url.searchParams.get('recursive') === 'true'; // 是否递归获取所有子文件夹
            
            // 确保用户目录存在
            await this.ensureUserDir(username);
            
            const fullPath = this.getSafePath(relativePath, username);
            

            // 检查目录是否存在
            try {
                await access(fullPath);
            } catch (error) {
                // 目录不存在，创建它
                await mkdir(fullPath, { recursive: true });
            }

            if (recursive) {
                // 递归获取所有文件夹结构
                const allFiles = await this.getFilesRecursive(fullPath, relativePath);
                res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
                res.end(JSON.stringify({
                    success: true,
                    files: allFiles,
                    recursive: true
                }));
            } else {
                // 只获取当前目录
                const items = await readdir(fullPath);
                const files = [];

                for (const item of items) {
                    const itemPath = path.join(fullPath, item);
                    const stats = await stat(itemPath);
                    const itemRelativePath = path.join(relativePath, item).replace(/\\/g, '/');

                    const fileInfo = {
                        name: item,
                        path: itemRelativePath,
                        type: stats.isDirectory() ? 'directory' : 'file',
                        size: stats.size,
                        modifiedTime: stats.mtime
                    };

                    // 如果是文件夹，检查是否包含PNG预览图，并提供完整的预览URL
                    if (stats.isDirectory()) {
                        const previewInfo = await this.checkFolderPreview(itemPath);
                        fileInfo.hasPreview = previewInfo.hasPreview;
                        if (previewInfo.hasPreview && previewInfo.previewFile) {
                            // 返回完整的预览URL路径（包含用户名）
                            fileInfo.previewUrl = `/api/disk/preview?username=${encodeURIComponent(username)}&path=${encodeURIComponent(itemRelativePath + '/' + previewInfo.previewFile)}`;
                        }
                        
                        // 检查是否需要抠图（是否有非透明背景的PNG）
                        const mattingInfo = await this.checkNeedMatting(itemPath);
                        fileInfo.needsMatting = mattingInfo.needsMatting;
                        fileInfo.pngCount = mattingInfo.pngCount;
                    }

                    files.push(fileInfo);
                }

                // 排序：文件夹在前，然后按名称排序
                files.sort((a, b) => {
                    if (a.type === 'directory' && b.type !== 'directory') return -1;
                    if (a.type !== 'directory' && b.type === 'directory') return 1;
                    return a.name.localeCompare(b.name, 'zh-CN');
                });

                res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
                res.end(JSON.stringify({
                    success: true,
                    files: files,
                    recursive: false
                }));
            }
        } catch (error) {
            console.error('获取文件列表失败:', error);
            res.writeHead(500, { 'Content-Type': 'application/json; charset=utf-8' });
            res.end(JSON.stringify({
                success: false,
                message: error.message
            }));
        }
    }

    // 递归获取所有文件夹结构（用于前端缓存）
    async getFilesRecursive(fullPath, relativePath) {
        const allFiles = [];
        
        const processDirectory = async (dirFullPath, dirRelativePath) => {
            try {
                const items = await readdir(dirFullPath);
                
                for (const item of items) {
                    const itemPath = path.join(dirFullPath, item);
                    const stats = await stat(itemPath);
                    const itemRelativePath = dirRelativePath ? 
                        path.join(dirRelativePath, item).replace(/\\/g, '/') : 
                        item;

                    const fileInfo = {
                        name: item,
                        path: itemRelativePath,
                        type: stats.isDirectory() ? 'directory' : 'file',
                        size: stats.size,
                        modifiedTime: stats.mtime
                    };

                    // 如果是文件夹，检查是否包含PNG
                    if (stats.isDirectory()) {
                        const previewInfo = await this.checkFolderPreview(itemPath);
                        fileInfo.hasPreview = previewInfo.hasPreview;
                        if (previewInfo.hasPreview && previewInfo.previewFile) {
                            fileInfo.previewUrl = `/api/disk/preview?path=${encodeURIComponent(itemRelativePath + '/' + previewInfo.previewFile)}`;
                        }
                        
                        const mattingInfo = await this.checkNeedMatting(itemPath);
                        fileInfo.needsMatting = mattingInfo.needsMatting;
                        fileInfo.pngCount = mattingInfo.pngCount;
                        
                        // 递归处理子文件夹
                        await processDirectory(itemPath, itemRelativePath);
                    }

                    allFiles.push(fileInfo);
                }
            } catch (error) {
                console.error(`递归读取目录失败: ${dirRelativePath}`, error);
            }
        };
        
        await processDirectory(fullPath, relativePath);
        
        // 排序：文件夹在前，然后按路径排序
        allFiles.sort((a, b) => {
            if (a.type === 'directory' && b.type !== 'directory') return -1;
            if (a.type !== 'directory' && b.type === 'directory') return 1;
            return a.path.localeCompare(b.path, 'zh-CN');
        });
        
        return allFiles;
    }

    // 处理文件上传请求
    async handleUploadRequest(req, res) {
        try {
            const form = formidable.formidable({
                multiples: true,
                maxFileSize: 500 * 1024 * 1024, // 500MB
                keepExtensions: true
            });

            form.parse(req, async (err, fields, files) => {
                if (err) {
                    console.error('解析上传文件失败:', err);
                    res.writeHead(500, { 'Content-Type': 'application/json; charset=utf-8' });
                    res.end(JSON.stringify({
                        success: false,
                        message: '上传失败'
                    }));
                    return;
                }

                try {
                    // 获取用户名
                    const username = this.getUsernameFromRequest(req, fields);
                    if (!username) {
                        res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' });
                        res.end(JSON.stringify({ success: false, message: '缺少用户名参数' }));
                        return;
                    }
                    
                    // 确保用户目录存在
                    await this.ensureUserDir(username);
                    
                    // 新版 formidable 将字段解析为数组，需要取第一个元素
                    const relativePath = Array.isArray(fields.path) ? fields.path[0] : (fields.path || '');
                    const fileRelativePath = Array.isArray(fields.relativePath) ? fields.relativePath[0] : (fields.relativePath || '');
                    
                    // 获取上传文件的完整路径
                    const uploadPath = path.join(relativePath, fileRelativePath);
                    const targetPath = this.getSafePath(uploadPath, username);
                    
                    // 确保目标目录存在
                    const targetDir = path.dirname(targetPath);
                    await mkdir(targetDir, { recursive: true });

                    // 获取上传的文件
                    const uploadedFile = Array.isArray(files.file) ? files.file[0] : files.file;
                    
                    // 移动文件
                    await this.moveFile(uploadedFile.filepath, targetPath);

                    res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
                    res.end(JSON.stringify({
                        success: true,
                        message: '上传成功'
                    }));
                } catch (error) {
                    console.error('保存文件失败:', error);
                    res.writeHead(500, { 'Content-Type': 'application/json; charset=utf-8' });
                    res.end(JSON.stringify({
                        success: false,
                        message: error.message
                    }));
                }
            });
        } catch (error) {
            console.error('处理上传请求失败:', error);
            res.writeHead(500, { 'Content-Type': 'application/json; charset=utf-8' });
            res.end(JSON.stringify({
                success: false,
                message: error.message
            }));
        }
    }

    // 移动文件
    async moveFile(source, target) {
        return new Promise((resolve, reject) => {
            const readStream = fs.createReadStream(source);
            const writeStream = fs.createWriteStream(target);

            readStream.on('error', reject);
            writeStream.on('error', reject);
            writeStream.on('finish', () => {
                // 删除临时文件
                fs.unlink(source, (err) => {
                    if (err) console.error('删除临时文件失败:', err);
                    resolve();
                });
            });

            readStream.pipe(writeStream);
        });
    }

    // 处理创建文件夹请求
    async handleCreateFolderRequest(req, res) {
        try {
            let body = '';
            req.on('data', chunk => {
                body += chunk.toString();
            });

            req.on('end', async () => {
                try {
                    const data = JSON.parse(body);
                    const username = data.username;
                    if (!username) {
                        res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' });
                        res.end(JSON.stringify({ success: false, message: '缺少用户名参数' }));
                        return;
                    }
                    
                    // 确保用户目录存在
                    await this.ensureUserDir(username);
                    
                    const relativePath = data.path || '';
                    const folderName = data.name;

                    if (!folderName) {
                        throw new Error('文件夹名称不能为空');
                    }

                    // 验证文件夹名称
                    if (/[\\/:*?"<>|]/.test(folderName)) {
                        throw new Error('文件夹名称包含非法字符');
                    }

                    const folderPath = path.join(relativePath, folderName);
                    const fullPath = this.getSafePath(folderPath, username);

                    // 检查文件夹是否已存在
                    try {
                        await access(fullPath);
                        throw new Error('文件夹已存在');
                    } catch (error) {
                        if (error.message === '文件夹已存在') {
                            throw error;
                        }
                        // 文件夹不存在，创建它
                        await mkdir(fullPath, { recursive: true });
                    }

                    res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
                    res.end(JSON.stringify({
                        success: true,
                        message: '创建成功'
                    }));
                } catch (error) {
                    console.error('创建文件夹失败:', error);
                    res.writeHead(500, { 'Content-Type': 'application/json; charset=utf-8' });
                    res.end(JSON.stringify({
                        success: false,
                        message: error.message
                    }));
                }
            });
        } catch (error) {
            console.error('处理创建文件夹请求失败:', error);
            res.writeHead(500, { 'Content-Type': 'application/json; charset=utf-8' });
            res.end(JSON.stringify({
                success: false,
                message: error.message
            }));
        }
    }

    // 处理重命名请求
    async handleRenameRequest(req, res) {
        try {
            let body = '';
            req.on('data', chunk => {
                body += chunk.toString();
            });

            req.on('end', async () => {
                try {
                    const data = JSON.parse(body);
                    const username = data.username;
                    if (!username) {
                        res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' });
                        res.end(JSON.stringify({ success: false, message: '缺少用户名参数' }));
                        return;
                    }
                    
                    const oldPath = data.oldPath;
                    const newName = data.newName;

                    if (!oldPath || !newName) {
                        throw new Error('路径和新名称不能为空');
                    }

                    // 验证新名称
                    if (/[\\/:*?"<>|]/.test(newName)) {
                        throw new Error('名称包含非法字符');
                    }

                    const userRootDir = this.getUserRootDir(username);
                    const oldFullPath = this.getSafePath(oldPath, username);
                    const parentDir = path.dirname(oldFullPath);
                    const newFullPath = path.join(parentDir, newName);

                    // 确保新路径也在用户根目录内
                    if (!newFullPath.startsWith(userRootDir)) {
                        throw new Error('非法路径');
                    }

                    // 检查旧文件是否存在
                    await access(oldFullPath);

                    // 检查新名称是否已存在
                    try {
                        await access(newFullPath);
                        throw new Error('该名称已存在');
                    } catch (error) {
                        if (error.message === '该名称已存在') {
                            throw error;
                        }
                        // 文件不存在，可以重命名
                    }

                    // 执行重命名
                    await promisify(fs.rename)(oldFullPath, newFullPath);

                    res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
                    res.end(JSON.stringify({
                        success: true,
                        message: '重命名成功'
                    }));
                } catch (error) {
                    console.error('重命名失败:', error);
                    res.writeHead(500, { 'Content-Type': 'application/json; charset=utf-8' });
                    res.end(JSON.stringify({
                        success: false,
                        message: error.message
                    }));
                }
            });
        } catch (error) {
            console.error('处理重命名请求失败:', error);
            res.writeHead(500, { 'Content-Type': 'application/json; charset=utf-8' });
            res.end(JSON.stringify({
                success: false,
                message: error.message
            }));
        }
    }

    // 处理文件下载请求
    async handleDownloadRequest(req, res) {
        try {
            const url = new URL(req.url, `http://${req.headers.host}`);
            const username = url.searchParams.get('username');
            if (!username) {
                res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' });
                res.end(JSON.stringify({ success: false, message: '缺少用户名参数' }));
                return;
            }
            
            const relativePath = url.searchParams.get('path') || '';
            
            const fullPath = this.getSafePath(relativePath, username);

            // 检查文件是否存在
            await access(fullPath);
            const stats = await stat(fullPath);

            if (stats.isDirectory()) {
                throw new Error('无法下载文件夹');
            }

            // 设置响应头
            const fileName = path.basename(fullPath);
            res.writeHead(200, {
                'Content-Type': 'application/octet-stream',
                'Content-Disposition': `attachment; filename="${encodeURIComponent(fileName)}"`,
                'Content-Length': stats.size
            });

            // 创建读取流并发送文件
            const readStream = fs.createReadStream(fullPath);
            readStream.pipe(res);
        } catch (error) {
            console.error('下载文件失败:', error);
            res.writeHead(404, { 'Content-Type': 'application/json; charset=utf-8' });
            res.end(JSON.stringify({
                success: false,
                message: '文件不存在'
            }));
        }
    }

    // 处理获取用户网盘中的帧文件列表
    async handleGetUserFrames(username, folderName, res) {
        try {
            console.log(`[DiskManager] 获取用户帧列表: username=${username}, folderName=${folderName}`);
            
            const userRootDir = this.getUserRootDir(username);
            // 处理URL编码和空格
            const decodedFolderName = decodeURIComponent(folderName).replace(/%20/g, ' ');
            const folderPath = path.join(userRootDir, decodedFolderName);
            
            console.log(`[DiskManager] 用户网盘目录: ${userRootDir}`);
            console.log(`[DiskManager] 解码后的文件夹名: ${decodedFolderName}`);
            console.log(`[DiskManager] 完整路径: ${folderPath}`);
            
            // 检查目录是否存在
            try {
                await access(folderPath);
            } catch (accessErr) {
                console.error(`[DiskManager] 文件夹不存在: ${folderPath}`);
                res.writeHead(404, { 'Content-Type': 'application/json; charset=utf-8' });
                res.end(JSON.stringify({ 
                    error: 'Folder not found', 
                    details: `文件夹不存在: ${folderPath}`,
                    folderPath: folderPath
                }));
                return;
            }
            
            // 读取文件夹内容
            const files = await readdir(folderPath);
            console.log(`[DiskManager] 找到 ${files.length} 个文件`);
            
            // 过滤出 PNG 文件，并按数字排序
            const pngFiles = files
                .filter(file => file.toLowerCase().endsWith('.png'))
                .map(file => {
                    let frameNum = null;
                    // 先尝试匹配纯数字格式：00.png, 01.png
                    let match = /^(\d+)\.png$/i.exec(file);
                    if (match) {
                        frameNum = parseInt(match[1], 10);
                    } else {
                        // 再尝试匹配文件名末尾的数字格式
                        match = /(\d+)\.png$/i.exec(file);
                        if (match) {
                            frameNum = parseInt(match[1], 10);
                        }
                    }
                    
                    if (frameNum !== null) {
                        return {
                            frameNum: frameNum,
                            fileName: file
                        };
                    }
                    return null;
                })
                .filter(item => item !== null)
                .sort((a, b) => a.frameNum - b.frameNum);
            
            if (pngFiles.length === 0) {
                console.log(`[DiskManager] 文件夹中没有PNG文件`);
                res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' });
                res.end(JSON.stringify({ 
                    error: '该文件夹中没有图片',
                    frames: []
                }));
                return;
            }
            
            const result = {
                frames: pngFiles.map(item => item.frameNum),
                fileNames: pngFiles.map(item => item.fileName),
                maxFrame: pngFiles.length > 0 ? Math.max(...pngFiles.map(item => item.frameNum)) : 0
            };
            
            console.log(`[DiskManager] ✓ 成功获取 ${result.frames.length} 帧`);
            res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
            res.end(JSON.stringify(result));
        } catch (error) {
            console.error('[DiskManager] 获取用户帧列表失败:', error);
            res.writeHead(500, { 'Content-Type': 'application/json; charset=utf-8' });
            res.end(JSON.stringify({ 
                error: 'Failed to get frames', 
                details: error.message 
            }));
        }
    }

    // 处理图片预览请求
    async handlePreviewRequest(req, res) {
        try {
            const url = new URL(req.url, `http://${req.headers.host}`);
            const username = url.searchParams.get('username');
            if (!username) {
                res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' });
                res.end(JSON.stringify({ success: false, message: '缺少用户名参数' }));
                return;
            }
            
            const relativePath = url.searchParams.get('path') || '';
            
            const fullPath = this.getSafePath(relativePath, username);

            // 检查文件是否存在
            await access(fullPath);
            const stats = await stat(fullPath);

            if (stats.isDirectory()) {
                throw new Error('无法预览文件夹');
            }

            // 获取文件扩展名
            const ext = path.extname(fullPath).toLowerCase();
            const mimeTypes = {
                '.jpg': 'image/jpeg',
                '.jpeg': 'image/jpeg',
                '.png': 'image/png',
                '.gif': 'image/gif',
                '.bmp': 'image/bmp',
                '.webp': 'image/webp',
                '.svg': 'image/svg+xml'
            };

            const contentType = mimeTypes[ext];
            if (!contentType) {
                throw new Error('不支持的图片格式');
            }

            // 设置响应头，添加缓存
            res.writeHead(200, {
                'Content-Type': contentType,
                'Content-Length': stats.size,
                'Cache-Control': 'public, max-age=86400'
            });

            // 创建读取流并发送文件
            const readStream = fs.createReadStream(fullPath);
            readStream.pipe(res);
        } catch (error) {
            console.error('预览图片失败:', error);
            res.writeHead(404, { 'Content-Type': 'application/json; charset=utf-8' });
            res.end(JSON.stringify({
                success: false,
                message: '图片不存在'
            }));
        }
    }

    // 处理移动文件/文件夹请求
    async handleMoveRequest(req, res) {
        try {
            let body = '';
            req.on('data', chunk => {
                body += chunk.toString();
            });

            req.on('end', async () => {
                try {
                    const data = JSON.parse(body);
                    const username = data.username;
                    if (!username) {
                        res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' });
                        res.end(JSON.stringify({ success: false, message: '缺少用户名参数' }));
                        return;
                    }
                    
                    const sourcePath = data.sourcePath;
                    const targetFolder = data.targetFolder;

                    if (!sourcePath) {
                        throw new Error('源路径不能为空');
                    }

                    const userRootDir = this.getUserRootDir(username);
                    const sourceFullPath = this.getSafePath(sourcePath, username);
                    const fileName = path.basename(sourceFullPath);
                    
                    // 目标路径
                    const targetPath = targetFolder ? path.join(targetFolder, fileName) : fileName;
                    const targetFullPath = this.getSafePath(targetPath, username);

                    // 确保源文件存在
                    await access(sourceFullPath);

                    // 检查是否移动到自身或子目录
                    if (targetFullPath.startsWith(sourceFullPath + path.sep) || targetFullPath === sourceFullPath) {
                        throw new Error('不能移动到自身或子目录');
                    }
                    
                    // 确保目标路径也在用户根目录内
                    if (!targetFullPath.startsWith(userRootDir)) {
                        throw new Error('非法路径');
                    }

                    // 检查目标是否已存在
                    try {
                        await access(targetFullPath);
                        throw new Error('目标位置已存在同名文件或文件夹');
                    } catch (error) {
                        if (error.message === '目标位置已存在同名文件或文件夹') {
                            throw error;
                        }
                        // 文件不存在，可以移动
                    }

                    // 确保目标目录存在
                    const targetDir = path.dirname(targetFullPath);
                    await mkdir(targetDir, { recursive: true });

                    // 执行移动
                    await promisify(fs.rename)(sourceFullPath, targetFullPath);

                    res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
                    res.end(JSON.stringify({
                        success: true,
                        message: '移动成功'
                    }));
                } catch (error) {
                    console.error('移动失败:', error);
                    res.writeHead(500, { 'Content-Type': 'application/json; charset=utf-8' });
                    res.end(JSON.stringify({
                        success: false,
                        message: error.message
                    }));
                }
            });
        } catch (error) {
            console.error('处理移动请求失败:', error);
            res.writeHead(500, { 'Content-Type': 'application/json; charset=utf-8' });
            res.end(JSON.stringify({
                success: false,
                message: error.message
            }));
        }
    }

    // 处理复制文件/文件夹请求
    async handleCopyRequest(req, res) {
        try {
            let body = '';
            req.on('data', chunk => {
                body += chunk.toString();
            });

            req.on('end', async () => {
                try {
                    const data = JSON.parse(body);
                    const username = data.username;
                    if (!username) {
                        res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' });
                        res.end(JSON.stringify({ success: false, message: '缺少用户名参数' }));
                        return;
                    }
                    
                    const sourcePath = data.sourcePath;
                    const targetFolder = data.targetFolder;

                    if (!sourcePath) {
                        throw new Error('源路径不能为空');
                    }

                    const userRootDir = this.getUserRootDir(username);
                    const sourceFullPath = this.getSafePath(sourcePath, username);
                    const fileName = path.basename(sourceFullPath);
                    const targetPath = targetFolder ? path.join(targetFolder, fileName) : fileName;
                    const targetFullPath = this.getSafePath(targetPath, username);

                    await access(sourceFullPath);

                    if (targetFullPath === sourceFullPath || targetFullPath.startsWith(sourceFullPath + path.sep)) {
                        throw new Error('不能复制到自身或子目录');
                    }
                    
                    // 确保目标路径也在用户根目录内
                    if (!targetFullPath.startsWith(userRootDir)) {
                        throw new Error('非法路径');
                    }

                    try {
                        await access(targetFullPath);
                        throw new Error('目标位置已存在同名文件或文件夹');
                    } catch (error) {
                        if (error.message === '目标位置已存在同名文件或文件夹') {
                            throw error;
                        }
                    }

                    await this.copyItemRecursive(sourceFullPath, targetFullPath);

                    res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
                    res.end(JSON.stringify({
                        success: true,
                        message: '复制成功'
                    }));
                } catch (error) {
                    console.error('复制失败:', error);
                    res.writeHead(500, { 'Content-Type': 'application/json; charset=utf-8' });
                    res.end(JSON.stringify({
                        success: false,
                        message: error.message
                    }));
                }
            });
        } catch (error) {
            console.error('处理复制请求失败:', error);
            res.writeHead(500, { 'Content-Type': 'application/json; charset=utf-8' });
            res.end(JSON.stringify({
                success: false,
                message: error.message
            }));
        }
    }

    async copyItemRecursive(source, target) {
        const stats = await stat(source);
        if (stats.isDirectory()) {
            await mkdir(target, { recursive: true });
            const entries = await readdir(source);
            for (const entry of entries) {
                const childSource = path.join(source, entry);
                const childTarget = path.join(target, entry);
                await this.copyItemRecursive(childSource, childTarget);
            }
        } else {
            const targetDir = path.dirname(target);
            await mkdir(targetDir, { recursive: true });
            await copyFile(source, target);
        }
    }

    // 处理删除文件/文件夹请求
    async handleDeleteRequest(req, res) {
        try {
            let body = '';
            req.on('data', chunk => {
                body += chunk.toString();
            });

            req.on('end', async () => {
                try {
                    const data = JSON.parse(body);
                    const username = data.username;
                    if (!username) {
                        res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' });
                        res.end(JSON.stringify({ success: false, message: '缺少用户名参数' }));
                        return;
                    }
                    
                    const paths = data.paths;

                    if (!paths || !Array.isArray(paths) || paths.length === 0) {
                        throw new Error('请选择要删除的文件');
                    }

                    const errors = [];

                    for (const filePath of paths) {
                        try {
                            const fullPath = this.getSafePath(filePath, username);
                            await access(fullPath);
                            const stats = await stat(fullPath);

                            if (stats.isDirectory()) {
                                // 递归删除文件夹
                                await this.deleteDirectory(fullPath);
                            } else {
                                // 删除文件
                                await promisify(fs.unlink)(fullPath);
                            }
                        } catch (error) {
                            errors.push(`${filePath}: ${error.message}`);
                        }
                    }

                    if (errors.length > 0) {
                        res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
                        res.end(JSON.stringify({
                            success: true,
                            message: `部分删除成功，${errors.length} 个失败`,
                            errors: errors
                        }));
                    } else {
                        res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
                        res.end(JSON.stringify({
                            success: true,
                            message: '删除成功'
                        }));
                    }
                } catch (error) {
                    console.error('删除失败:', error);
                    res.writeHead(500, { 'Content-Type': 'application/json; charset=utf-8' });
                    res.end(JSON.stringify({
                        success: false,
                        message: error.message
                    }));
                }
            });
        } catch (error) {
            console.error('处理删除请求失败:', error);
            res.writeHead(500, { 'Content-Type': 'application/json; charset=utf-8' });
            res.end(JSON.stringify({
                success: false,
                message: error.message
            }));
        }
    }

    // 递归删除目录
    async deleteDirectory(dirPath) {
        const items = await readdir(dirPath);
        
        for (const item of items) {
            const itemPath = path.join(dirPath, item);
            const stats = await stat(itemPath);
            
            if (stats.isDirectory()) {
                await this.deleteDirectory(itemPath);
            } else {
                await promisify(fs.unlink)(itemPath);
            }
        }
        
        await promisify(fs.rmdir)(dirPath);
    }

    // 处理一键抠图请求（使用SSE实时推送进度）
    async handleRemoveBackgroundRequest(req, res) {
        console.log('\n' + '▓'.repeat(70));
        console.log('[API] 收到一键抠图请求');
        console.log('▓'.repeat(70));
        
        // 设置SSE响应头
        res.writeHead(200, {
            'Content-Type': 'text/event-stream',
            'Cache-Control': 'no-cache',
            'Connection': 'keep-alive',
            'Access-Control-Allow-Origin': '*'
        });
        
        // 发送进度的辅助函数
        const sendProgress = (data) => {
            console.log('[API] → 发送SSE事件:', data);
            const message = `data: ${JSON.stringify(data)}\n\n`;
            res.write(message);
            console.log('[API] ✓ SSE事件已发送');
        };
        
        let body = '';
        req.on('data', chunk => {
            body += chunk.toString();
            console.log('[API] → 接收请求数据...');
        });

        req.on('end', async () => {
            try {
                console.log('[API] ✓ 请求数据接收完成');
                console.log('[API] → 解析JSON数据...');
                const data = JSON.parse(body);
                const { paths, username } = data;
                console.log('[API] ✓ JSON解析成功');
                console.log('[API]   请求路径:', paths);
                console.log('[API]   用户名:', username);
                
                if (!username) {
                    res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' });
                    res.end(JSON.stringify({
                        success: false,
                        message: '缺少用户名参数'
                    }));
                    return;
                }
                
                if (!paths || !Array.isArray(paths) || paths.length === 0) {
                    console.warn('[API] ⚠ 路径为空或无效');
                    res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' });
                    res.end(JSON.stringify({
                        success: false,
                        message: '请选择要处理的文件或文件夹'
                    }));
                    return;
                }

                console.log(`[API] → 开始批量处理，共 ${paths.length} 个项目`);

                let totalProcessed = 0;
                let totalFolders = 0;

                for (let i = 0; i < paths.length; i++) {
                    const relativePath = paths[i];
                    console.log(`\n[API] 处理项目 ${i + 1}/${paths.length}: ${relativePath}`);
                    
                    // 发送开始处理的进度
                    sendProgress({
                        type: 'folder-start',
                        current: i + 1,
                        total: paths.length,
                        folderName: relativePath
                    });
                    
                    console.log('[API] → 获取安全路径...');
                    const fullPath = this.getSafePath(relativePath, username);
                    console.log('[API] ✓ 完整路径:', fullPath);
                    
                    console.log('[API] → 读取文件状态...');
                    const stats = await stat(fullPath);
                    console.log('[API] ✓ 文件状态:', stats.isDirectory() ? '文件夹' : '文件');

                    if (stats.isDirectory()) {
                        console.log('[API] → 开始处理文件夹...');
                        const result = await this.processFolder(fullPath, sendProgress, relativePath);
                        console.log('[API] ✓ 文件夹处理完成');
                        console.log('[API]   结果:', result);
                        
                        if (result.success) {
                            totalProcessed += result.processed;
                            totalFolders++;
                            
                            // 发送文件夹完成的进度
                            sendProgress({
                                type: 'folder-complete',
                                current: i + 1,
                                total: paths.length,
                                folderName: relativePath,
                                processed: result.processed
                            });
                        } else {
                            console.error('[API] ✗ 文件夹处理失败:', result.message);
                            sendProgress({
                                type: 'folder-error',
                                current: i + 1,
                                total: paths.length,
                                folderName: relativePath,
                                error: result.message
                            });
                        }
                    } else {
                        console.log('[API] ⚠ 跳过单个文件（暂不支持）');
                    }
                }

                console.log('\n' + '▓'.repeat(70));
                console.log('[API] ✓✓✓ 所有项目处理完成！');
                console.log(`[API]   处理文件夹: ${totalFolders} 个`);
                console.log(`[API]   处理图片: ${totalProcessed} 张`);
                console.log('▓'.repeat(70));
                
                console.log('[API] → 发送完成消息...');
                sendProgress({
                    type: 'complete',
                    success: true,
                    processed: totalProcessed,
                    folders: totalFolders,
                    message: `处理完成！处理了 ${totalFolders} 个文件夹，共 ${totalProcessed} 张图片`
                });
                res.end();
                console.log('[API] ✓ SSE连接已关闭\n');
            } catch (error) {
                console.error('\n' + '▓'.repeat(70));
                console.error('[API] ✗✗✗ 请求处理失败');
                console.error('[API] 错误类型:', error.name);
                console.error('[API] 错误信息:', error.message);
                console.error('[API] 错误堆栈:', error.stack);
                console.error('▓'.repeat(70) + '\n');
                
                sendProgress({
                    type: 'error',
                    success: false,
                    message: error.message
                });
                res.end();
            }
        });
    }

    // 处理单个文件夹：只抠图（不裁剪）
    async processFolder(folderPath, sendProgress, relativePath) {
        const timestamp = Date.now();
        const folderName = path.basename(folderPath);
        
        // 创建临时目录
        const tempBase = path.join(this.tempDir, `matting_${timestamp}_${folderName}`);
        const tempMatting = path.join(tempBase, 'output');

        try {
            console.log(`\n${'='.repeat(70)}`);
            console.log(`[DiskManager] 开始抠背景: ${folderName}`);
            console.log(`${'='.repeat(70)}`);
            console.log(`[DiskManager] 原始路径: ${folderPath}`);
            
            // 创建临时目录
            console.log(`[DiskManager] 创建临时目录...`);
            await mkdir(tempBase, { recursive: true });
            await mkdir(tempMatting, { recursive: true });
            console.log(`[DiskManager] ✓ 临时目录创建完成`);
            console.log(`[DiskManager]   - 抠图输出: ${tempMatting}`);

            // 使用Python脚本进行抠图
            console.log(`\n[DiskManager] >>> 开始AI抠背景 <<<`);
            const mattingResult = await this.runImageMatting(folderPath, tempMatting, (current, total) => {
                if (sendProgress) {
                    sendProgress({
                        type: 'image-progress',
                        current: current,
                        total: total,
                        folderName: relativePath || folderName
                    });
                }
            });
            
            if (!mattingResult.success) {
                throw new Error(`抠背景失败: ${mattingResult.message}`);
            }

            console.log(`[DiskManager] ✓ 抠背景完成，处理了 ${mattingResult.processed} 张图片`);

            // 将处理后的文件复制回原文件夹
            console.log(`\n[DiskManager] >>> 保存结果到原文件夹 <<<`);
            const saveResult = await this.saveProcessedFiles(tempMatting, folderPath);
            
            console.log(`[DiskManager] ✓ 保存完成，已替换 ${saveResult.saved} 张图片`);
            console.log(`\n${'='.repeat(70)}`);
            console.log(`[DiskManager] ✓✓✓ 处理完成！文件夹: ${folderName} ✓✓✓`);
            console.log(`${'='.repeat(70)}\n`);

            return {
                success: true,
                processed: saveResult.saved
            };

        } catch (error) {
            console.error(`\n${'='.repeat(70)}`);
            console.error(`[DiskManager] ✗✗✗ 处理失败: ${folderName} ✗✗✗`);
            console.error(`[DiskManager] 错误信息: ${error.message}`);
            console.error(`${'='.repeat(70)}\n`);
            return {
                success: false,
                processed: 0,
                message: error.message
            };
        } finally {
            // 清理临时文件
            try {
                console.log('[DiskManager] 清理临时文件...');
                await this.deleteDirectory(tempBase);
                console.log('[DiskManager] ✓ 临时文件已清理');
            } catch (error) {
                console.warn('[DiskManager] ⚠ 清理临时文件失败:', error.message);
            }
        }
    }

    // 处理单个文件夹：只裁剪
    async processFolderCropOnly(folderPath, sendProgress, relativePath) {
        const timestamp = Date.now();
        const folderName = path.basename(folderPath);
        
        // 创建临时目录
        const tempBase = path.join(this.tempDir, `crop_${timestamp}_${folderName}`);
        const tempCrop = path.join(tempBase, 'output');

        try {
            console.log(`\n${'='.repeat(70)}`);
            console.log(`[DiskManager] 开始剪裁: ${folderName}`);
            console.log(`${'='.repeat(70)}`);
            console.log(`[DiskManager] 原始路径: ${folderPath}`);
            
            // 创建临时目录
            console.log(`[DiskManager] 创建临时目录...`);
            await mkdir(tempBase, { recursive: true });
            await mkdir(tempCrop, { recursive: true });
            console.log(`[DiskManager] ✓ 临时目录创建完成`);
            console.log(`[DiskManager]   - 裁剪输出: ${tempCrop}`);

            // 使用Python脚本裁剪多余透明区域
            console.log(`\n[DiskManager] >>> 开始智能裁剪 <<<`);
            const folderBaseName = path.basename(folderPath);
            const cropResult = await this.runCutMiniSize(folderPath, tempCrop, (current, total) => {
                if (sendProgress) {
                    sendProgress({
                        type: 'image-progress',
                        current: current,
                        total: total,
                        folderName: relativePath || folderBaseName
                    });
                }
            });
            
            if (!cropResult.success) {
                throw new Error(`裁剪失败: ${cropResult.message}`);
            }

            console.log(`[DiskManager] ✓ 裁剪完成，最终尺寸: ${cropResult.width}x${cropResult.height}`);

            // 将处理后的文件复制回原文件夹
            console.log(`\n[DiskManager] >>> 保存结果到原文件夹 <<<`);
            const saveResult = await this.saveProcessedFiles(tempCrop, folderPath);
            
            console.log(`[DiskManager] ✓ 保存完成，已替换 ${saveResult.saved} 张图片`);
            console.log(`\n${'='.repeat(70)}`);
            console.log(`[DiskManager] ✓✓✓ 裁剪完成！文件夹: ${folderName} ✓✓✓`);
            console.log(`${'='.repeat(70)}\n`);

            return {
                success: true,
                processed: saveResult.saved,
                width: cropResult.width,
                height: cropResult.height
            };

        } catch (error) {
            console.error(`\n${'='.repeat(70)}`);
            console.error(`[DiskManager] ✗✗✗ 裁剪失败: ${folderName} ✗✗✗`);
            console.error(`[DiskManager] 错误信息: ${error.message}`);
            console.error(`${'='.repeat(70)}\n`);
            return {
                success: false,
                processed: 0,
                message: error.message
            };
        } finally {
            // 清理临时文件
            try {
                console.log('[DiskManager] 清理临时文件...');
                await this.deleteDirectory(tempBase);
                console.log('[DiskManager] ✓ 临时文件已清理');
            } catch (error) {
                console.warn('[DiskManager] ⚠ 清理临时文件失败:', error.message);
            }
        }
    }

    // 保存处理后的文件到原文件夹（直接替换）
    async saveProcessedFiles(sourceFolder, targetFolder) {
        console.log('[DiskManager] → 开始保存文件...');
        console.log('[DiskManager]   源文件夹:', sourceFolder);
        console.log('[DiskManager]   目标文件夹:', targetFolder);
        
        let saved = 0;
        
        try {
            console.log('[DiskManager] → 读取源文件夹...');
            const files = await readdir(sourceFolder);
            console.log(`[DiskManager] ✓ 找到 ${files.length} 个文件`);
            
            for (let i = 0; i < files.length; i++) {
                const file = files[i];
                const sourcePath = path.join(sourceFolder, file);
                const targetPath = path.join(targetFolder, file);
                
                console.log(`[DiskManager]   [${i + 1}/${files.length}] 替换: ${file}`);
                
                // 不备份，直接替换原文件
                await copyFile(sourcePath, targetPath);
                saved++;
                console.log(`[DiskManager]     ✓ 已替换`);
            }
            
            console.log(`[DiskManager] ✓ 所有文件保存完成，共 ${saved} 个`);
            return { saved };
        } catch (error) {
            console.error('[DiskManager] ✗ 保存文件失败:', error);
            throw error;
        }
    }

    // 处理剪裁最小区域请求（使用SSE实时推送进度）
    async handleCropMiniRequest(req, res) {
        console.log('\n' + '▓'.repeat(70));
        console.log('[API] 收到剪裁最小区域请求');
        console.log('▓'.repeat(70));
        
        // 设置SSE响应头
        res.writeHead(200, {
            'Content-Type': 'text/event-stream',
            'Cache-Control': 'no-cache',
            'Connection': 'keep-alive',
            'Access-Control-Allow-Origin': '*'
        });
        
        // 发送进度的辅助函数
        const sendProgress = (data) => {
            console.log('[API] → 发送SSE事件:', data);
            const message = `data: ${JSON.stringify(data)}\n\n`;
            res.write(message);
            console.log('[API] ✓ SSE事件已发送');
        };
        
        let body = '';
        req.on('data', chunk => {
            body += chunk.toString();
        });

        req.on('end', async () => {
            try {
                const data = JSON.parse(body);
                const { paths, username } = data;
                
                if (!username) {
                    res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' });
                    res.end(JSON.stringify({
                        success: false,
                        message: '缺少用户名参数'
                    }));
                    return;
                }
                
                if (!paths || !Array.isArray(paths) || paths.length === 0) {
                    res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' });
                    res.end(JSON.stringify({
                        success: false,
                        message: '请选择要处理的文件或文件夹'
                    }));
                    return;
                }

                console.log(`[API] → 开始批量裁剪，共 ${paths.length} 个项目`);

                let totalProcessed = 0;
                let totalFolders = 0;

                for (let i = 0; i < paths.length; i++) {
                    const relativePath = paths[i];
                    console.log(`\n[API] 裁剪项目 ${i + 1}/${paths.length}: ${relativePath}`);
                    
                    const fullPath = this.getSafePath(relativePath, username);
                    const stats = await stat(fullPath);

                    if (stats.isDirectory()) {
                        const result = await this.processFolderCropOnly(fullPath, sendProgress, relativePath);
                        
                        if (result.success) {
                            totalProcessed += result.processed;
                            totalFolders++;
                        }
                    }
                }

                console.log('\n' + '▓'.repeat(70));
                console.log('[API] ✓✓✓ 所有项目裁剪完成！');
                console.log(`[API]   处理文件夹: ${totalFolders} 个`);
                console.log(`[API]   处理图片: ${totalProcessed} 张`);
                console.log('▓'.repeat(70));
                
                sendProgress({
                    type: 'complete',
                    success: true,
                    processed: totalProcessed,
                    folders: totalFolders,
                    message: `裁剪完成！处理了 ${totalFolders} 个文件夹，共 ${totalProcessed} 张图片`
                });
                res.end();
            } catch (error) {
                console.error('[API] 裁剪请求处理失败:', error);
                sendProgress({
                    type: 'error',
                    success: false,
                    message: error.message
                });
                res.end();
            }
        });
    }
}

module.exports = DiskManager;

