import { promises as fs } from 'fs';
import path from 'path';
import { taskManager } from './taskManager.js';
let io = null;
export function setFileOperationDependencies(socketIO) {
    io = socketIO;
}
async function calculateDirectoryStats(dirPath) {
    let totalSize = 0;
    let totalFiles = 0;
    async function traverse(currentPath) {
        try {
            const stats = await fs.stat(currentPath);
            if (stats.isFile()) {
                totalSize += stats.size;
                totalFiles++;
            }
            else if (stats.isDirectory()) {
                const items = await fs.readdir(currentPath);
                for (const item of items) {
                    await traverse(path.join(currentPath, item));
                }
            }
        }
        catch (error) {
        }
    }
    await traverse(dirPath);
    return { totalSize, totalFiles };
}
async function copyDirectoryWithProgress(src, dest, taskId, onProgress) {
    let copiedSize = 0;
    let copiedFiles = 0;
    await fs.mkdir(dest, { recursive: true });
    const items = await fs.readdir(src);
    for (const item of items) {
        const srcPath = path.join(src, item);
        const destPath = path.join(dest, item);
        try {
            const stats = await fs.stat(srcPath);
            if (stats.isDirectory()) {
                const result = await copyDirectoryWithProgress(srcPath, destPath, taskId, onProgress);
                copiedSize += result.copiedSize;
                copiedFiles += result.copiedFiles;
            }
            else {
                await fs.copyFile(srcPath, destPath);
                copiedSize += stats.size;
                copiedFiles++;
                onProgress(copiedSize, copiedFiles);
            }
        }
        catch (error) {
            console.error(`复制文件失败: ${srcPath}`, error);
        }
    }
    return { copiedSize, copiedFiles };
}
async function moveDirectoryWithProgress(src, dest, taskId, onProgress) {
    try {
        await fs.rename(src, dest);
        const stats = await calculateDirectoryStats(dest);
        onProgress(stats.totalSize, stats.totalFiles);
        return { movedSize: stats.totalSize, movedFiles: stats.totalFiles };
    }
    catch (renameError) {
        if (renameError.code === 'EXDEV') {
            const result = await copyDirectoryWithProgress(src, dest, taskId, onProgress);
            await fs.rm(src, { recursive: true });
            return { movedSize: result.copiedSize, movedFiles: result.copiedFiles };
        }
        else {
            throw renameError;
        }
    }
}
export async function executeFileOperation(taskId) {
    const task = taskManager.getTask(taskId);
    if (!task || task.type !== 'copy' && task.type !== 'move') {
        return;
    }
    try {
        taskManager.updateTask(taskId, {
            status: 'running',
            message: '正在准备文件操作...'
        });
        if (io) {
            io.emit('task-updated', task);
        }
        const data = task.data;
        const { sourcePaths, targetPath, operation, conflictStrategy = 'replace' } = data;
        let totalSize = 0;
        let totalFiles = 0;
        taskManager.updateTask(taskId, {
            message: '正在计算文件大小...'
        });
        for (const sourcePath of sourcePaths) {
            try {
                const stats = await fs.stat(sourcePath);
                if (stats.isFile()) {
                    totalSize += stats.size;
                    totalFiles++;
                }
                else if (stats.isDirectory()) {
                    const dirStats = await calculateDirectoryStats(sourcePath);
                    totalSize += dirStats.totalSize;
                    totalFiles += dirStats.totalFiles;
                }
            }
            catch (error) {
                console.error(`无法访问文件: ${sourcePath}`, error);
            }
        }
        let processedSize = 0;
        let processedFiles = 0;
        const updateProgress = (addedSize, addedFiles) => {
            processedSize += addedSize;
            processedFiles += addedFiles;
            const progress = totalSize > 0 ? Math.round((processedSize / totalSize) * 100) : 0;
            const message = `${operation === 'copy' ? '复制' : '移动'}中... (${processedFiles}/${totalFiles} 个文件)`;
            taskManager.updateTask(taskId, {
                progress,
                message
            });
            if (io) {
                const updatedTask = taskManager.getTask(taskId);
                if (updatedTask) {
                    io.emit('task-updated', updatedTask);
                }
            }
        };
        for (const sourcePath of sourcePaths) {
            try {
                const fileName = path.basename(sourcePath);
                let targetFilePath = path.join(targetPath, fileName);
                const stats = await fs.stat(sourcePath);
                const targetExists = await fs.access(targetFilePath).then(() => true).catch(() => false);
                if (targetExists) {
                    if (conflictStrategy === 'skip') {
                        if (stats.isFile()) {
                            updateProgress(stats.size, 1);
                        }
                        else if (stats.isDirectory()) {
                            const dirStats = await calculateDirectoryStats(sourcePath);
                            updateProgress(dirStats.totalSize, dirStats.totalFiles);
                        }
                        continue;
                    }
                    else if (conflictStrategy === 'rename') {
                        const ext = path.extname(fileName);
                        const nameWithoutExt = path.basename(fileName, ext);
                        let counter = 1;
                        while (await fs.access(targetFilePath).then(() => true).catch(() => false)) {
                            targetFilePath = path.join(targetPath, `${nameWithoutExt}(${counter})${ext}`);
                            counter++;
                        }
                    }
                    else {
                        const targetStats = await fs.stat(targetFilePath);
                        if (targetStats.isDirectory()) {
                            await fs.rm(targetFilePath, { recursive: true });
                        }
                        else {
                            await fs.unlink(targetFilePath);
                        }
                    }
                }
                if (stats.isFile()) {
                    if (operation === 'copy') {
                        await fs.copyFile(sourcePath, targetFilePath);
                    }
                    else {
                        await fs.rename(sourcePath, targetFilePath);
                    }
                    updateProgress(stats.size, 1);
                }
                else if (stats.isDirectory()) {
                    if (operation === 'copy') {
                        await copyDirectoryWithProgress(sourcePath, targetFilePath, taskId, (size, files) => {
                            updateProgress(size - processedSize, files - processedFiles);
                        });
                    }
                    else {
                        await moveDirectoryWithProgress(sourcePath, targetFilePath, taskId, (size, files) => {
                            updateProgress(size - processedSize, files - processedFiles);
                        });
                    }
                }
            }
            catch (error) {
                console.error(`${operation === 'copy' ? '复制' : '移动'}失败: ${sourcePath}`, error);
            }
        }
        taskManager.updateTask(taskId, {
            status: 'completed',
            progress: 100,
            message: `${operation === 'copy' ? '复制' : '移动'}完成！处理了 ${processedFiles} 个文件`
        });
        if (io) {
            const completedTask = taskManager.getTask(taskId);
            if (completedTask) {
                io.emit('task-updated', completedTask);
            }
        }
    }
    catch (error) {
        console.error(`文件操作任务失败 (${taskId}):`, error);
        taskManager.updateTask(taskId, {
            status: 'failed',
            message: `操作失败: ${error.message}`
        });
        if (io) {
            const failedTask = taskManager.getTask(taskId);
            if (failedTask) {
                io.emit('task-updated', failedTask);
            }
        }
    }
}
