// 网盘管理系统 - 客户端逻辑
// 版本: v1.2 - 修复404错误
// console.log('[Disk] 加载 DiskManager v1.2');

class DiskManager {
    constructor() {
        this.files = [];
        this.uploadingFiles = [];
        this.dragCounter = 0;
        this.clipboard = null;
        this.shortcutKeys = null;
        this.container = document.querySelector('.disk-container');
        
        // 全局文件结构缓存（用于快速验证文件夹内容）
        this.fileStructureCache = new Map(); // key: 文件路径, value: 文件信息（包括pngCount）
        this.cacheInitialized = false;
        
        // 当前登录用户名
        this.currentUsername = null;
        
        this.init();
    }
    
    // 获取当前登录用户名
    getCurrentUsername() {
        // 如果已经缓存了用户名，直接返回
        if (this.currentUsername) {
            return this.currentUsername;
        }
        
        // 从导航栏 iframe 中获取用户名
        try {
            // 尝试从父窗口的 navigationFrame 获取
            let targetWindow = window.parent;
            while (targetWindow && targetWindow !== window) {
                try {
                    const navigationFrame = targetWindow.document.getElementById('navigationFrame');
                    if (navigationFrame && navigationFrame.contentWindow) {
                        const navWindow = navigationFrame.contentWindow;
                        const navDoc = navigationFrame.contentDocument || navWindow.document;
                        
                        // 检查用户是否已登录
                        const userAvatarContainer = navDoc.getElementById('userAvatarContainer');
                        if (userAvatarContainer) {
                            const computedStyle = navDoc.defaultView.getComputedStyle(userAvatarContainer);
                            if (computedStyle.display !== 'none') {
                                // 用户已登录，从 userAvatar 的 alt 属性获取用户名
                                const userAvatar = navDoc.getElementById('userAvatar');
                                if (userAvatar && userAvatar.alt && userAvatar.alt !== '用户头像') {
                                    const username = userAvatar.alt;
                                    // 缓存用户名
                                    this.currentUsername = username;
                                    console.log('[DiskManager] 从导航栏获取用户名:', username);
                                    return username;
                                }
                            }
                        }
                    }
                } catch (e) {
                    // 跨域或访问限制，继续尝试上层窗口
                    console.warn('[DiskManager] 访问导航栏失败:', e);
                }
                
                // 尝试更上层的窗口
                if (targetWindow.parent && targetWindow.parent !== targetWindow) {
                    targetWindow = targetWindow.parent;
                } else {
                    break;
                }
            }
        } catch (error) {
            console.warn('[DiskManager] 无法获取用户名:', error);
        }
        
        // 如果仍然没有获取到，返回 null
        return this.currentUsername;
    }
    
    // 设置当前用户名（从外部调用，例如登录成功后）
    setCurrentUsername(username) {
        this.currentUsername = username;
    }
    
    // 从 localStorage 恢复登录状态
    restoreLoginFromStorage() {
        try {
            const loginDataStr = localStorage.getItem('loginData');
            if (!loginDataStr) {
                return;
            }
            
            const loginData = JSON.parse(loginDataStr);
            const now = Date.now();
            
            // 检查是否过期
            if (now >= loginData.expireTime) {
                localStorage.removeItem('loginData');
                return;
            }
            
            // 未过期，恢复登录状态
            if (loginData.user && loginData.user.username) {
                this.setCurrentUsername(loginData.user.username);
                console.log('[DiskManager] 从 localStorage 恢复登录状态:', loginData.user.username);
            }
        } catch (error) {
            console.error('[DiskManager] 恢复登录状态失败:', error);
        }
    }
    
    // 监听登录成功消息
    initUserListener() {
        window.addEventListener('message', (event) => {
            if (event.data && event.data.type === 'login-success' && event.data.user) {
                const username = event.data.user.username;
                this.setCurrentUsername(username);
                console.log('[DiskManager] 收到登录成功消息，设置用户名:', username);
                // 登录成功后重新加载文件列表
                this.loadFiles();
            } else if (event.data && event.data.type === 'logout') {
                this.setCurrentUsername(null);
                console.log('[DiskManager] 收到登出消息，清除用户名');
                // 登出后清空文件列表
                this.files = [];
                this.renderFiles();
            }
        });
    }

    async init() {
        // 先尝试从 localStorage 恢复登录状态（同步操作，立即执行）
        this.restoreLoginFromStorage();
        
        // 并行加载工具栏和右键菜单（不阻塞页面）
        const toolbarPromise = this.ensureToolBar();
        const contextMenuPromise = this.ensureContextMenu();
        
        // 初始化基本元素（这些不依赖工具栏和菜单的HTML）
        this.initElements();
        this.initUploadProgress();
        this.initUserListener();
        
        // 等待工具栏加载完成后，初始化依赖它的组件
        await toolbarPromise;
        this.initElements(); // 重新获取工具栏中的元素
        this.initPath();
        this.initSelection();
        this.initShortcutKeys();
        this.initSearchBar();
        this.bindEvents();
        
        // 工具栏加载完成后立即开始加载文件列表
            const username = this.getCurrentUsername();
            if (username) {
                console.log('[DiskManager] 初始化时检测到已登录用户:', username);
            // 开始加载文件（不阻塞后续初始化）
        this.loadFiles();
        }
        
        // 等待右键菜单加载完成后初始化（并行进行，不影响文件加载）
        await contextMenuPromise;
        this.initContextMenu();
        
        // 后台初始化文件结构缓存（不阻塞页面加载）
        this.initFileStructureCache();
    }

    async ensureToolBar() {
        if (document.getElementById('breadcrumb')) {
            return;
        }

        if (!this.container) {
            return;
        }

        try {
            const response = await fetch('tool-bar.html', { cache: 'no-cache' });
            if (!response.ok) {
                throw new Error('加载工具栏失败');
            }
            const html = await response.text();
            this.container.insertAdjacentHTML('afterbegin', html);
        } catch (error) {
            console.error('加载工具栏失败:', error);
        }
    }

    async ensureContextMenu() {
        if (document.getElementById('contextMenu')) {
            return;
        }

        const menuContainer = document.getElementById('contextMenuContainer');
        if (!menuContainer) {
            return;
        }

        try {
            const response = await fetch('right-click-menu.html', { cache: 'no-cache' });
            if (!response.ok) {
                throw new Error('加载右键菜单失败');
            }
            const html = await response.text();
            menuContainer.innerHTML = html;
        } catch (error) {
            console.error('加载右键菜单失败:', error);
        }
    }

    initElements() {
        this.dropZone = document.getElementById('dropZone');
        this.fileList = document.getElementById('fileList');
        this.breadcrumb = document.getElementById('breadcrumb');
        this.emptyState = document.getElementById('emptyState');
        this.loading = document.getElementById('loading');
        this.btnCreateFolder = document.getElementById('btnCreateFolder');
        this.fileInput = document.getElementById('fileInput');
        this.searchInput = document.getElementById('searchInput');
        this.searchClear = document.getElementById('searchClear');
        this.selectionBar = document.getElementById('selectionBar');
        this.selectionCount = document.getElementById('selectionCount');
        this.selectionBox = document.getElementById('selectionBox');
        this.btnDownload = document.getElementById('btnDownload');
        this.btnDelete = document.getElementById('btnDelete');
        this.btnUpload = document.getElementById('btnUpload');
        this.uploadProgress = document.getElementById('uploadProgress');
        this.uploadProgressList = document.getElementById('uploadProgressList');
        this.uploadProgressTemplate = document.getElementById('uploadProgressTemplate');
        this.uploadProgressClose = document.getElementById('uploadProgressClose');
        this.contextMenu = document.getElementById('contextMenu');
    }

    // 初始化路径导航
    initPath() {
        this.pathNav = new PathNavigator({
            container: this.breadcrumb,
            rootName: '全部文件',
            onNavigate: (path) => {
                this.loadFiles();
            }
        });
    }

    // 初始化框选功能
    initSelection() {
        this.selection = new MultipleSelection({
            container: this.dropZone,
            itemsContainer: this.fileList,
            selectionBox: this.selectionBox,
            selectionBar: this.selectionBar,
            selectionCount: this.selectionCount,
            itemSelector: '.file-item',
            onSelectionChange: (selectedItems) => {
                // 选择变化时的回调（可用于其他逻辑）
            }
        });
    }

    initUploadProgress() {
        if (this.uploadProgressClose) {
            this.uploadProgressClose.addEventListener('click', () => this.hideUploadProgress());
        }
        this.hideUploadProgress();
    }

    initContextMenu() {
        if (!this.dropZone || !this.contextMenu) {
            return;
        }

        this.contextMenuManager = new RightClickMenu({
            target: this.dropZone,
            menu: this.contextMenu,
            onAction: (action, event) => this.handleContextMenuAction(action, event),
            onBeforeShow: (event) => this.handleBeforeShowContextMenu(event)
        });
    }

    handleBeforeShowContextMenu(event) {
        // 在显示右键菜单前，检查是否点击在文件项上
        const fileItem = event.target.closest('.file-item');
        // console.log('[Disk] 右键菜单即将显示');
        // console.log('[Disk]   点击目标:', event.target);
        // console.log('[Disk]   最近的文件项:', fileItem);
        
        if (fileItem) {
            // 如果点击在文件项上，确保它被选中
            const isSelected = this.selection.isSelected(fileItem.dataset.path);
            // console.log('[Disk]   文件项路径:', fileItem.dataset.path);
            // console.log('[Disk]   是否已选中:', isSelected);
            
            if (!isSelected) {
                // console.log('[Disk] → 自动选中该文件项');
                this.selection.selectOnly(fileItem);
                // console.log('[Disk] ✓ 文件项已选中');
            }
        } else {
            // console.log('[Disk] ⚠ 右键点击在空白区域');
        }
    }

    showUploadProgress() {
        if (this.uploadProgress) {
            this.uploadProgress.classList.add('show');
        }
    }

    hideUploadProgress() {
        if (this.uploadProgress) {
            this.uploadProgress.classList.remove('show');
        }
        if (this.uploadProgressList) {
            this.uploadProgressList.innerHTML = '';
        }
    }
    
    showGlobalLoading(text = '正在处理...') {
        // 直接调用父窗口的 GlobalLoading（不通过 postMessage）
        try {
            // 优先使用父窗口的 GlobalLoading
            if (window.parent && window.parent !== window && window.parent.GlobalLoading) {
                window.parent.GlobalLoading.show(text);
                return;
            }
            
            // 如果父窗口没有 GlobalLoading，尝试更上层的窗口
            let targetWindow = window.parent;
            while (targetWindow && targetWindow !== window) {
                if (targetWindow.GlobalLoading) {
                    targetWindow.GlobalLoading.show(text);
                    return;
                }
                if (targetWindow.parent && targetWindow.parent !== targetWindow) {
                    targetWindow = targetWindow.parent;
                } else {
                    break;
                }
            }
        } catch (error) {
            console.error('[Disk] 显示 loading 失败:', error);
        }
    }

    updateGlobalLoadingProgress(current, total, operation = '处理') {
        // 更新loading进度
        const text = `正在${operation} ${current}/${total} 张图片...`;
        this.showGlobalLoading(text);
    }
    
    hideGlobalLoading() {
        // 直接调用父窗口的 GlobalLoading（不通过 postMessage）
        try {
            // 优先使用父窗口的 GlobalLoading
            if (window.parent && window.parent !== window && window.parent.GlobalLoading) {
                window.parent.GlobalLoading.hide();
                return;
            }
            
            // 如果父窗口没有 GlobalLoading，尝试更上层的窗口
            let targetWindow = window.parent;
            while (targetWindow && targetWindow !== window) {
                if (targetWindow.GlobalLoading) {
                    targetWindow.GlobalLoading.hide();
                    return;
                }
                if (targetWindow.parent && targetWindow.parent !== targetWindow) {
                    targetWindow = targetWindow.parent;
                } else {
                    break;
                }
            }
        } catch (error) {
            console.error('[Disk] 隐藏 loading 失败:', error);
        }
    }

    showGlobalAlert(message) {
        // 直接调用父窗口的 GlobalAlert（不通过 postMessage）
        try {
            // 优先使用父窗口的 GlobalAlert（disk 在 assets.html 的 iframe 中）
            if (window.parent && window.parent !== window && window.parent.GlobalAlert) {
                window.parent.GlobalAlert.show(message, 3000);
                return;
            }
            
            // 如果父窗口没有 GlobalAlert，尝试更上层的窗口（index.html）
            let targetWindow = window.parent;
            while (targetWindow && targetWindow !== window) {
                if (targetWindow.GlobalAlert) {
                    targetWindow.GlobalAlert.show(message, 3000);
                    return;
                }
                if (targetWindow.parent && targetWindow.parent !== targetWindow) {
                    targetWindow = targetWindow.parent;
                } else {
                    break;
                }
            }
            
            // 降级处理：如果没有 GlobalAlert，使用 console
            console.log('[Alert]', message);
        } catch (error) {
            console.error('[Disk] 显示 alert 失败:', error);
            console.log('[Alert]', message);
        }
    }

    // 统一的错误处理函数：解析服务端错误响应并显示
    async handleServerError(response, defaultMessage = '操作失败') {
        let errorMessage = defaultMessage;
        
        try {
            // 尝试解析 JSON 错误响应
            const errorData = await response.json().catch(() => null);
            if (errorData) {
                // 优先使用服务端返回的 message
                if (errorData.message) {
                    errorMessage = errorData.message;
                } else if (errorData.error) {
                    errorMessage = errorData.error;
                } else if (typeof errorData === 'string') {
                    errorMessage = errorData;
                }
            }
        } catch (e) {
            // 如果解析失败，使用默认消息或状态码
            if (response.status) {
                errorMessage = `${defaultMessage} (状态码: ${response.status})`;
            }
        }
        
        this.showGlobalAlert(errorMessage);
        return errorMessage;
    }

    showGlobalConfirm(message) {
        // 直接调用父窗口的 GlobalConfirm（不通过 postMessage）
        return new Promise((resolve) => {
            try {
                // 优先使用父窗口的 GlobalConfirm
                if (window.parent && window.parent !== window && window.parent.GlobalConfirm) {
                    window.parent.GlobalConfirm.show(message).then((confirmed) => {
                        resolve(confirmed);
                    }).catch(() => {
                        resolve(false);
                    });
                    return;
                }
                
                // 如果父窗口没有 GlobalConfirm，尝试更上层的窗口
                let targetWindow = window.parent;
                while (targetWindow && targetWindow !== window) {
                    if (targetWindow.GlobalConfirm) {
                        targetWindow.GlobalConfirm.show(message).then((confirmed) => {
                            resolve(confirmed);
                        }).catch(() => {
                            resolve(false);
                        });
                        return;
                    }
                    if (targetWindow.parent && targetWindow.parent !== targetWindow) {
                        targetWindow = targetWindow.parent;
                    } else {
                        break;
                    }
                }
                
                // 如果找不到 GlobalConfirm，直接返回 false（不降级到原生 confirm）
                console.error('[Disk] 无法找到 GlobalConfirm，操作已取消');
                resolve(false);
            } catch (error) {
                console.error('[Disk] 显示 confirm 失败:', error);
                // 不降级到原生 confirm，直接返回 false
                resolve(false);
            }
        });
    }

    handleContextMenuAction(action) {
        console.log(`[Disk] 右键菜单动作: ${action}`);
        switch (action) {
            case 'new':
                this.createFolder();
                break;
            case 'cut':
                this.cutSelected();
                break;
            case 'copy':
                this.copySelected();
                break;
            case 'paste':
                this.pasteClipboard();
                break;
            case 'remove-bg':
                console.log('[Disk] 触发一键抠背景功能');
                this.removeBackgroundFromSelected();
                break;
            case 'crop-mini':
                console.log('[Disk] 触发剪裁最小区域功能');
                this.cropMiniFromSelected();
                break;
            default:
                console.warn('[Disk] 未知的菜单动作:', action);
                break;
        }
    }

    initShortcutKeys() {
        if (this.shortcutKeys) {
            this.shortcutKeys.destroy();
        }

        this.shortcutKeys = new ShortcutKeys({
            selection: this.selection,
            onDelete: () => this.deleteSelected(),
            onRename: () => this.renameSelected(),
            onCopy: () => this.copySelected(),
            onCut: () => this.cutSelected(),
            onPaste: () => this.pasteClipboard()
        });
    }

    initSearchBar() {
        this.searchBar = new SearchBar({
            input: this.searchInput,
            clearButton: this.searchClear,
            fileList: this.fileList,
            emptyState: this.emptyState,
            getFiles: () => this.files,
            renderAll: () => this.renderFiles(),
            createFileItem: (file) => this.createFileItem(file)
        });
    }

    bindEvents() {
        // 拖拽上传事件
        this.dropZone.addEventListener('dragenter', (e) => this.handleDragEnter(e));
        this.dropZone.addEventListener('dragover', (e) => this.handleDragOver(e));
        this.dropZone.addEventListener('dragleave', (e) => this.handleDragLeave(e));
        this.dropZone.addEventListener('drop', (e) => this.handleDrop(e));
        document.addEventListener('dragend', () => this.resetDropState());

        // 按钮事件
        if (this.fileInput) {
            this.fileInput.addEventListener('change', (e) => this.handleFileSelect(e));
        }
        if (this.btnCreateFolder) {
            this.btnCreateFolder.addEventListener('click', () => this.createFolder());
        }

        // 选择操作按钮
        this.btnDownload.addEventListener('click', () => this.downloadSelected());
        this.btnDelete.addEventListener('click', () => this.deleteSelected());
        
        // 上传按钮
        if (this.btnUpload) {
            this.btnUpload.addEventListener('click', () => {
                if (this.fileInput) {
                    const currentPath = this.pathNav.getPath();
                    const isRootDir = !currentPath || currentPath === '';
                    
                    // 根目录只允许上传文件夹
                    if (isRootDir) {
                        this.fileInput.setAttribute('webkitdirectory', '');
                        this.fileInput.removeAttribute('accept');
                    } else {
                        this.fileInput.removeAttribute('webkitdirectory');
                        this.fileInput.setAttribute('accept', 'image/*');
                    }
                    
                    this.fileInput.click();
                }
            });
        }
    }

    // 下载选中的文件
    downloadSelected() {
        const selectedPaths = this.selection.getSelectedItems();
        selectedPaths.forEach(filePath => {
            const file = this.files.find(f => f.path === filePath);
            if (file && file.type !== 'directory') {
                this.downloadFile(filePath);
            }
        });
    }

    // 删除选中的文件
    async deleteSelected() {
        const count = this.selection.getSelectedCount();
        if (count === 0) return;

        const confirmMsg = `确定要删除选中的 ${count} 个文件/文件夹吗？`;
        const confirmed = await this.showGlobalConfirm(confirmMsg);
        
        if (!confirmed) {
            return;
        }

        try {
            const username = this.getCurrentUsername();
            if (!username) {
                this.showGlobalAlert('请先登录');
                return;
            }
            
            const response = await fetch('/api/disk/delete', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    username: username,
                    paths: this.selection.getSelectedItems()
                })
            });

            if (!response.ok) {
                await this.handleServerError(response, '删除失败');
                return;
            }

            const data = await response.json();
            if (data.success) {
                this.selection.clearSelection();
                this.loadFiles();
            } else {
                this.showGlobalAlert('删除失败: ' + (data.message || '未知错误'));
            }
        } catch (error) {
            this.showGlobalAlert('删除失败: ' + (error.message || '网络错误'));
        }
    }

    renameSelected() {
        if (!this.selection || this.selection.getSelectedCount() !== 1) {
            return;
        }

        const selectedPath = this.selection.getSelectedItems()[0];
        const selectedItem = this.fileList.querySelector(`[data-path="${selectedPath}"]`);
        if (selectedItem) {
            this.startRename(selectedItem);
        }
    }

    copySelected() {
        if (!this.selection || !this.selection.hasSelection()) {
            return false;
        }

        const selectedPaths = this.selection.getSelectedItems();
        this.clearCutVisuals();
        this.clipboard = {
            mode: 'copy',
            items: selectedPaths.map(path => ({ path }))
        };
        return true;
    }

    cutSelected() {
        if (!this.selection || !this.selection.hasSelection()) {
            return false;
        }

        const selectedPaths = this.selection.getSelectedItems();
        this.clipboard = {
            mode: 'cut',
            items: selectedPaths.map(path => ({ path }))
        };
        this.applyCutVisuals(selectedPaths);
        return true;
    }

    async pasteClipboard() {
        if (!this.clipboard || !this.clipboard.items || this.clipboard.items.length === 0) {
            return false;
        }

        const targetFolder = this.pathNav.getPath();
        const isCut = this.clipboard.mode === 'cut';
        let hasSuccess = false;

        for (const item of this.clipboard.items) {
            let result = false;
            if (isCut) {
                result = await this.moveFile(item.path, targetFolder, { suppressReload: true });
            } else {
                result = await this.copyFile(item.path, targetFolder, { suppressReload: true });
            }
            hasSuccess = hasSuccess || result;
        }

        if (hasSuccess) {
            await this.loadFiles();
        }

        if (isCut) {
            this.clipboard = null;
            this.clearCutVisuals();
        }

        return hasSuccess;
    }

    async removeBackgroundFromSelected() {
        console.log('\n' + '='.repeat(70));
        console.log('[Disk] 🎨 一键抠图功能被触发');
        console.log('='.repeat(70));
        
        const selectedPaths = this.selection.getSelectedItems();
        console.log(`[Disk] 获取选中项: ${selectedPaths.length} 个`);
        
        if (selectedPaths.length === 0) {
            console.warn('[Disk] ⚠ 没有选中任何项');
            this.showGlobalAlert('请先选择要抠图的文件夹');
            return;
        }

        // getSelectedItems() 返回的已经是路径数组
        console.log('[Disk] 选中的路径:', selectedPaths);
        
        // 确认操作
        const confirmMsg = selectedPaths.length === 1 
            ? `一键抠背景会覆盖原文件，确定要对"${selectedPaths[0]}"进行处理吗？`
            : `一键抠背景会覆盖原文件，确定要对选中的 ${selectedPaths.length} 个文件夹进行处理吗？`;
        
        console.log('[Disk] → 准备显示确认对话框...');
        console.log('[Disk]   确认消息:', confirmMsg);
        
        // 通过父窗口显示全局确认对话框
        console.log('[Disk] → 调用 showGlobalConfirm()');
        const confirmed = await this.showGlobalConfirm(confirmMsg);
        console.log('[Disk] ← showGlobalConfirm() 返回，结果:', confirmed);
        
        if (!confirmed) {
            console.log('[Disk] ✗ 用户取消操作，函数返回');
            return;
        }
        console.log('[Disk] ✓ 用户确认操作，继续执行');

        // 计算总图片数
        let totalPngCount = 0;
        selectedPaths.forEach(path => {
            const fileInfo = this.files.find(f => f.path === path) || this.getFileFromCache(path);
            console.log('[Disk] 检查文件:', path, '信息:', fileInfo);
            if (fileInfo && fileInfo.pngCount) {
                console.log('[Disk]   pngCount:', fileInfo.pngCount);
                totalPngCount += fileInfo.pngCount;
            }
        });
        
        console.log('[Disk] 总PNG数量:', totalPngCount);

        // 显示loading（带总数信息）
        console.log('[Disk] → 显示全局Loading...');
        const loadingText = totalPngCount > 0 
            ? `正在处理 0/${totalPngCount} 张图片...`
            : '正在处理中，请稍候...';
        this.showGlobalLoading(loadingText);
        console.log('[Disk] ✓ Loading已显示');
        
        // 保存总数，用于更新进度
        this.currentProcessTotal = totalPngCount;

        try {
            console.log('[Disk] → 准备发送HTTP请求到服务器');
            console.log('[Disk]   URL: /api/disk/remove-background');
            console.log('[Disk]   方法: POST');
            console.log('[Disk]   数据:', { paths: selectedPaths });
            
            const username = this.getCurrentUsername();
            if (!username) {
                this.showGlobalAlert('请先登录');
                return;
            }
            
            // 使用fetch读取SSE流
            const response = await fetch('/api/disk/remove-background', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({ username: username, paths: selectedPaths })
            });

            console.log('[Disk] ✓ HTTP响应收到');
            console.log('[Disk]   状态码:', response.status);

            if (!response.ok) {
                this.hideGlobalLoading();
                await this.handleServerError(response, '处理失败');
                return;
            }

            // 读取SSE流
            console.log('[Disk] → 开始读取SSE流...');
            const reader = response.body.getReader();
            const decoder = new TextDecoder();
            let buffer = '';
            let finalResult = null;

            while (true) {
                const { done, value } = await reader.read();
                
                if (done) {
                    console.log('[Disk] ✓ SSE流读取完成');
                    break;
                }

                const chunk = decoder.decode(value, { stream: true });
                console.log('[Disk] ← 收到数据块:', chunk.substring(0, 100));
                buffer += chunk;
                
                const lines = buffer.split('\n\n');
                buffer = lines.pop() || '';

                for (const line of lines) {
                    if (line.startsWith('data: ')) {
                        const jsonStr = line.substring(6);
                        try {
                            const data = JSON.parse(jsonStr);
                            console.log('[Disk] ← 解析到事件:', data);

                            if (data.type === 'image-progress') {
                                // 更新进度
                                console.log(`[Disk] → 更新进度: ${data.current}/${data.total}`);
                                this.updateGlobalLoadingProgress(data.current, data.total, '处理');
                            } else if (data.type === 'complete') {
                                console.log('[Disk] ← 收到完成事件');
                                finalResult = data;
                            } else if (data.type === 'error') {
                                console.error('[Disk] ← 收到错误事件');
                                throw new Error(data.message);
                            }
                        } catch (e) {
                            console.error('[Disk] 解析SSE数据失败:', e, '原始数据:', jsonStr);
                        }
                    }
                }
            }

            console.log('[Disk] ✓ 最终结果:', finalResult);

            if (finalResult && finalResult.success) {
                console.log('[Disk] ✓✓✓ 服务器处理成功！');
                console.log('[Disk]   处理文件夹数:', finalResult.folders || 0);
                console.log('[Disk]   处理图片数:', finalResult.processed || 0);
                
                console.log('[Disk] → 隐藏Loading...');
                this.hideGlobalLoading();
                console.log('[Disk] ✓ Loading已隐藏');
                
                const message = `处理完成！\n共处理 ${finalResult.processed || 0} 张图片`;
                console.log('[Disk] → 显示成功提示');
                this.showGlobalAlert(message);
                
                console.log('[Disk] → 清除图片缓存...');
                await this.clearImageCache(selectedPaths);
                console.log('[Disk] ✓ 缓存已清除');
                
                console.log('[Disk] → 刷新文件列表以更新预览图...');
                await this.loadFiles();
                console.log('[Disk] ✓ 文件列表已刷新');
                console.log('='.repeat(70));
                console.log('[Disk] 🎉🎉🎉 一键抠图完成！');
                console.log('='.repeat(70) + '\n');
            } else {
                throw new Error(finalResult?.message || '处理失败');
            }
        } catch (error) {
            console.error('\n' + '='.repeat(70));
            console.error('[Disk] ✗✗✗ 客户端处理失败');
            console.error('[Disk] 错误信息:', error.message);
            console.error('[Disk] 错误堆栈:', error.stack);
            console.error('='.repeat(70) + '\n');
            
            this.hideGlobalLoading();
            this.showGlobalAlert('处理失败: ' + error.message);
        }
    }

    async cropMiniFromSelected() {
        console.log('[Disk] 剪裁最小区域功能被触发');
        
        const selectedPaths = this.selection.getSelectedItems();
        console.log(`[Disk] 获取选中项: ${selectedPaths.length} 个`);
        
        if (selectedPaths.length === 0) {
            this.showGlobalAlert('请先选择要剪裁的文件夹');
            return;
        }

        // 计算总图片数
        let totalPngCount = 0;
        selectedPaths.forEach(path => {
            const fileInfo = this.files.find(f => f.path === path) || this.getFileFromCache(path);
            if (fileInfo && fileInfo.pngCount) {
                totalPngCount += fileInfo.pngCount;
            }
        });

        // 确认操作
        const confirmMsg = selectedPaths.length === 1 
            ? `确定要对"${selectedPaths[0]}"进行剪裁吗？`
            : `确定要对选中的 ${selectedPaths.length} 个文件夹进行剪裁吗？`;
        
        const confirmed = await this.showGlobalConfirm(confirmMsg);
        if (!confirmed) {
            return;
        }

        // 显示loading
        const loadingText = totalPngCount > 0 
            ? `正在剪裁 0/${totalPngCount} 张图片...`
            : '正在剪裁中，请稍候...';
        this.showGlobalLoading(loadingText);
        
        // 保存总数，用于更新进度
        this.currentProcessTotal = totalPngCount;

        try {
            const username = this.getCurrentUsername();
            if (!username) {
                this.showGlobalAlert('请先登录');
                return;
            }
            
            // 使用fetch读取SSE流
            const response = await fetch('/api/disk/crop-mini', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({ username: username, paths: selectedPaths })
            });

            if (!response.ok) {
                this.hideGlobalLoading();
                await this.handleServerError(response, '剪裁失败');
                return;
            }

            // 读取SSE流
            const reader = response.body.getReader();
            const decoder = new TextDecoder();
            let buffer = '';
            let finalResult = null;

            while (true) {
                const { done, value } = await reader.read();
                
                if (done) break;

                buffer += decoder.decode(value, { stream: true });
                const lines = buffer.split('\n\n');
                buffer = lines.pop() || '';

                for (const line of lines) {
                    if (line.startsWith('data: ')) {
                        const jsonStr = line.substring(6);
                        try {
                            const data = JSON.parse(jsonStr);

                            if (data.type === 'image-progress') {
                                this.updateGlobalLoadingProgress(data.current, data.total, '剪裁');
                            } else if (data.type === 'complete') {
                                finalResult = data;
                            } else if (data.type === 'error') {
                                throw new Error(data.message);
                            }
                        } catch (e) {
                            console.error('[Disk] 解析SSE数据失败:', e);
                        }
                    }
                }
            }

            if (finalResult && finalResult.success) {
                this.hideGlobalLoading();
                
                const message = `剪裁完成！\n共处理 ${finalResult.processed || 0} 张图片`;
                this.showGlobalAlert(message);
                
                // 清除缓存并刷新
                await this.clearImageCache(selectedPaths);
                await this.loadFiles();
            } else {
                throw new Error(finalResult?.message || '剪裁失败');
            }
        } catch (error) {
            console.error('[Disk] 剪裁失败:', error);
            this.hideGlobalLoading();
            this.showGlobalAlert('剪裁失败: ' + error.message);
        }
    }

    applyCutVisuals(paths = []) {
        this.clearCutVisuals();
        paths.forEach(path => {
            const item = this.fileList.querySelector(`[data-path="${path}"]`);
            if (item) {
                item.classList.add('cut');
            }
        });
    }

    clearCutVisuals() {
        this.fileList.querySelectorAll('.file-item.cut').forEach(item => item.classList.remove('cut'));
    }

    clearSearch(options) {
        if (this.searchBar) {
            this.searchBar.clear(options);
        }
    }

    // 检查是否是外部文件拖入（而非内部拖拽操作）
    isExternalFileDrag(e) {
        return e.dataTransfer.types.includes('Files') && 
               !e.dataTransfer.types.includes('text/plain');
    }

    // 拖拽处理
    handleDragEnter(e) {
        e.preventDefault();
        e.stopPropagation();
        
        if (this.isExternalFileDrag(e)) {
            this.dropZone.classList.add('drag-over');
            this.dragCounter++;
        }
    }

    handleDragOver(e) {
        e.preventDefault();
        e.stopPropagation();
    }

    handleDragLeave(e) {
        e.preventDefault();
        e.stopPropagation();
        
        if (this.isExternalFileDrag(e)) {
            this.dragCounter = Math.max(0, this.dragCounter - 1);
            if (this.dragCounter === 0) {
                this.dropZone.classList.remove('drag-over');
            }
        }
    }

    async handleDrop(e) {
        e.preventDefault();
        e.stopPropagation();
        this.dropZone.classList.remove('drag-over');
        this.dragCounter = 0;

        const items = e.dataTransfer.items;
        if (!items) return;

        const entries = [];
        for (let i = 0; i < items.length; i++) {
            const item = items[i].webkitGetAsEntry();
            if (item) {
                entries.push(item);
            }
        }

        await this.processEntries(entries);
    }

    resetDropState() {
        this.dragCounter = 0;
        this.dropZone.classList.remove('drag-over');
    }

    async processEntries(entries) {
        const currentPath = this.pathNav.getPath();
        const isRootDir = !currentPath || currentPath === '';
        
        // 检查是否在根目录上传文件（非文件夹）
        if (isRootDir) {
            const hasFiles = entries.some(entry => entry.isFile);
            if (hasFiles) {
                this.showGlobalAlert('根目录只允许上传文件夹');
                return;
            }
        }
        
        const filesToUpload = [];
        
        for (const entry of entries) {
            await this.traverseEntry(entry, '', filesToUpload);
        }

        if (filesToUpload.length > 0) {
            // 显示确认对话框
            const folderName = entries.length === 1 && entries[0].isDirectory 
                ? entries[0].name 
                : '选中的文件';
            const confirmMsg = `将 ${filesToUpload.length} 个文件上传到此网站？\n此操作会上传"${folderName}"下的所有文件。请仅在您信任该网站的情况下执行此操作。`;
            
            const confirmed = await this.showGlobalConfirm(confirmMsg);
            if (!confirmed) {
                return;
            }
            
            await this.uploadFiles(filesToUpload);
        }
    }

    async traverseEntry(entry, relativePath, filesToUpload) {
        if (entry.isFile) {
            const file = await new Promise((resolve) => {
                entry.file(resolve);
            });
            // 只接受图片格式的文件
            if (this.isImageFile(file.name)) {
                filesToUpload.push({
                    file: file,
                    path: relativePath + file.name
                });
            }
            // 非图片格式的文件直接跳过
        } else if (entry.isDirectory) {
            const dirReader = entry.createReader();
            const entries = await new Promise((resolve) => {
                dirReader.readEntries(resolve);
            });

            for (const childEntry of entries) {
                await this.traverseEntry(
                    childEntry,
                    relativePath + entry.name + '/',
                    filesToUpload
                );
            }
        }
    }

    async handleFileSelect(e) {
        const currentPath = this.pathNav.getPath();
        const isRootDir = !currentPath || currentPath === '';
        
        const files = Array.from(e.target.files);
        
        if (files.length === 0) {
            this.fileInput.value = '';
            return;
        }
        
        // 检查登录状态
        const username = this.getCurrentUsername();
        if (!username) {
            this.showGlobalAlert('请先登录');
            this.fileInput.value = '';
            return;
        }
        
        // 只接受图片格式的文件，其他格式直接跳过
        const filesToUpload = files
            .filter(file => this.isImageFile(file.name))
            .map(file => ({
                file: file,
                path: file.webkitRelativePath || file.name
            }));
        
        if (filesToUpload.length > 0) {
            // 显示确认对话框
            const folderName = files[0].webkitRelativePath 
                ? files[0].webkitRelativePath.split('/')[0] 
                : '选中的文件';
            const confirmMsg = `将 ${filesToUpload.length} 个文件上传到此网站？\n此操作会上传"${folderName}"下的所有文件。请仅在您信任该网站的情况下执行此操作。`;
            
            const confirmed = await this.showGlobalConfirm(confirmMsg);
            if (!confirmed) {
                this.fileInput.value = '';
                return;
            }
            
            await this.uploadFiles(filesToUpload);
        }
        this.fileInput.value = '';
    }

    async uploadFiles(filesToUpload) {
        if (!filesToUpload.length) return;

        // 显示全局loading遮罩
        this.showGlobalLoading(`正在上传 ${filesToUpload.length} 个文件...`);
        let hasSuccess = false;

        for (let i = 0; i < filesToUpload.length; i++) {
            const fileData = filesToUpload[i];
            
            // 更新进度文本
            this.showGlobalLoading(`正在上传... (${i + 1}/${filesToUpload.length})`);

            try {
                await this.uploadFile(fileData, null);
                hasSuccess = true;
                // 每上传成功一个文件就立即刷新显示（静默刷新，不显示加载动画）
                await this.loadFilesQuietly();
            } catch (error) {
                console.error('上传失败:', error);
            }
        }

        // 所有文件处理完成后，隐藏loading
        this.hideGlobalLoading();
        
        if (hasSuccess) {
            // 上传成功后刷新文件列表
            await this.loadFiles();
        }
    }

    async uploadFile(fileData, progressItem) {
        const username = this.getCurrentUsername();
        if (!username) {
            throw new Error('请先登录');
        }
        
        const formData = new FormData();
        formData.append('file', fileData.file);
        formData.append('path', this.pathNav.getPath());
        formData.append('relativePath', fileData.path);
        formData.append('username', username);

        const response = await fetch('/api/disk/upload', {
            method: 'POST',
            body: formData
        });

        if (!response.ok) {
            throw new Error('上传失败');
        }

        return response.json();
    }

    createProgressItem(fileName) {
        if (!this.uploadProgressTemplate || !this.uploadProgressList) {
            return null;
        }

        const fragment = this.uploadProgressTemplate.content.cloneNode(true);
        const item = fragment.querySelector('.upload-progress-item');
        if (!item) {
            return null;
        }

        const nameEl = item.querySelector('.upload-progress-name');
        if (nameEl) {
            nameEl.textContent = fileName;
        }

        this.uploadProgressList.appendChild(fragment);
        return this.uploadProgressList.lastElementChild;
    }

    updateProgressItem(item, status, message) {
        if (!item) return;
        const statusEl = item.querySelector('.upload-progress-status');
        const barFill = item.querySelector('.upload-progress-bar-fill');
        
        if (statusEl) {
            statusEl.textContent = message;
        }
        
        if (!barFill) return;

        if (status === 'success') {
            barFill.style.width = '100%';
            barFill.style.background = '#52c41a';
        } else if (status === 'error') {
            barFill.style.background = '#ff4d4f';
        }
    }

    // 初始化文件结构缓存（递归加载所有文件夹信息）
    async initFileStructureCache() {
        if (this.cacheInitialized) {
            return;
        }
        
        try {
            // console.log('[Disk] 开始初始化文件结构缓存...');
            const username = this.getCurrentUsername();
            if (!username) {
                console.warn('[Disk] 未登录，无法初始化缓存');
                return;
            }
            const response = await fetch(`/api/disk/list?username=${encodeURIComponent(username)}&path=&recursive=true`);
            
            if (!response.ok) {
                await this.handleServerError(response, '加载文件列表失败');
                return;
            }

            const data = await response.json();

            if (data.success && data.files) {
                // 构建缓存 Map
                this.fileStructureCache.clear();
                data.files.forEach(file => {
                    this.fileStructureCache.set(file.path, file);
                });
                this.cacheInitialized = true;
                // console.log(`[Disk] 文件结构缓存初始化完成，共 ${this.fileStructureCache.size} 个项目`);
            } else if (!data.success && data.message) {
                this.showGlobalAlert('加载文件列表失败: ' + data.message);
            }
        } catch (error) {
            this.showGlobalAlert('加载文件列表失败: ' + (error.message || '网络错误'));
        }
    }

    // 从缓存中获取文件信息
    getFileFromCache(filePath) {
        return this.fileStructureCache.get(filePath);
    }

    // 更新缓存中的单个文件信息
    updateCacheItem(filePath, fileInfo) {
        this.fileStructureCache.set(filePath, fileInfo);
    }

    // 从缓存中移除文件信息
    removeCacheItem(filePath) {
        this.fileStructureCache.delete(filePath);
    }

    // 清除图片缓存（用于抠图后更新预览）
    async clearImageCache(folderPaths) {
        try {
            // 清除浏览器的图片缓存
            if ('caches' in window) {
                const cacheNames = await caches.keys();
                for (const cacheName of cacheNames) {
                    const cache = await caches.open(cacheName);
                    const requests = await cache.keys();
                    
                    for (const request of requests) {
                        const url = request.url;
                        // 检查是否是处理过的文件夹的图片
                        for (const folderPath of folderPaths) {
                            if (url.includes(encodeURIComponent(folderPath))) {
                                await cache.delete(request);
                                console.log('[Disk] 清除缓存:', url);
                            }
                        }
                    }
                }
            }
        } catch (error) {
            console.error('[Disk] 清除缓存失败:', error);
        }
    }

    // 加载文件列表
    async loadFiles() {
        this.showLoading(true);
        this.selection.clearSelection();
        this.clearSearch();

        try {
            const username = this.getCurrentUsername();
            if (!username) {
                this.showGlobalAlert('请先登录');
                this.showLoading(false);
                return;
            }
            const response = await fetch(`/api/disk/list?username=${encodeURIComponent(username)}&path=${encodeURIComponent(this.pathNav.getPath())}`);
            
            if (!response.ok) {
                await this.handleServerError(response, '加载文件列表失败');
                return;
            }

            const data = await response.json();

            if (data.success) {
                this.files = data.files;
                
                // 更新缓存
                data.files.forEach(file => {
                    this.updateCacheItem(file.path, file);
                });
                
                this.renderFiles();
            } else if (data.message) {
                this.showGlobalAlert('加载文件列表失败: ' + data.message);
            }
        } catch (error) {
            this.showGlobalAlert('加载文件列表失败: ' + (error.message || '网络错误'));
        } finally {
            this.showLoading(false);
        }
    }

    // 静默加载文件列表（用于上传过程中增量更新，不显示加载动画，不闪烁）
    async loadFilesQuietly() {
        try {
            const username = this.getCurrentUsername();
            if (!username) {
                return;
            }
            const response = await fetch(`/api/disk/list?username=${encodeURIComponent(username)}&path=${encodeURIComponent(this.pathNav.getPath())}`);
            
            if (!response.ok) {
                // 静默加载失败时不显示错误，避免干扰用户
                return;
            }

            const data = await response.json();

            if (data.success) {
                this.files = data.files;
                this.renderFilesSmooth();
            }
        } catch (error) {
            console.error('加载文件列表失败:', error);
        }
    }

    renderFiles() {
        this.fileList.innerHTML = '';

        if (this.files.length === 0) {
            this.emptyState.classList.add('show');
            return;
        }

        this.emptyState.classList.remove('show');

        this.files.forEach(file => {
            const fileItem = this.createFileItem(file);
            this.fileList.appendChild(fileItem);
        });
    }

    // 平滑渲染文件列表（增量更新，避免闪烁）
    renderFilesSmooth() {
        if (this.files.length === 0) {
            this.emptyState.classList.add('show');
            this.fileList.innerHTML = '';
            return;
        }

        this.emptyState.classList.remove('show');

        // 获取当前已存在的文件路径
        const existingPaths = new Set();
        const existingItems = this.fileList.querySelectorAll('.file-item');
        existingItems.forEach(item => {
            existingPaths.add(item.dataset.path);
        });

        // 创建新文件路径集合
        const newPaths = new Set(this.files.map(f => f.path));

        // 删除不存在的文件项
        existingItems.forEach(item => {
            if (!newPaths.has(item.dataset.path)) {
                item.remove();
            }
        });

        // 只添加新文件项
        this.files.forEach(file => {
            if (!existingPaths.has(file.path)) {
                const fileItem = this.createFileItem(file);
                this.fileList.appendChild(fileItem);
            }
        });
    }

    createFileItem(file) {
        const div = document.createElement('div');
        div.className = 'file-item';
        div.dataset.name = file.name;
        div.dataset.type = file.type;
        div.dataset.path = file.path;
        div.draggable = true;

        const size = file.type === 'directory' ? '' : this.formatFileSize(file.size);
        const isImage = this.isImageFile(file.name);

        // 勾选标记
        const checkMark = `
            <div class="check-mark">
                <svg width="12" height="12" viewBox="0 0 12 12" fill="currentColor">
                    <path d="M10 3L4.5 8.5 2 6" stroke="white" stroke-width="2" fill="none"/>
                </svg>
            </div>
        `;

        // 检查是否是包含PNG的文件夹（通过名称模式判断）
        const isAnimationFolder = file.type === 'directory' && this.isAnimationFolder(file.name);

        if (isAnimationFolder) {
            // 动画文件夹显示第一帧预览
            // 使用服务器提供的预览信息（完全避免404错误）
            if (file.hasPreview && file.previewUrl) {
                // 服务器确认有预览图，直接使用服务器提供的URL
                // 确保 URL 包含用户名参数（如果服务器没有提供）
                const username = this.getCurrentUsername();
                let previewUrl = file.previewUrl;
                if (username && !previewUrl.includes('username=')) {
                    // 如果 URL 中没有用户名参数，添加它
                    const separator = previewUrl.includes('?') ? '&' : '?';
                    previewUrl = previewUrl + separator + 'username=' + encodeURIComponent(username);
                }
                // 添加时间戳防止缓存
                previewUrl = previewUrl + (previewUrl.includes('?') ? '&' : '?') + 't=' + Date.now();
                // console.log(`[Disk] 文件夹 ${file.name} 有预览图`);
                div.innerHTML = `
                    ${checkMark}
                    <div class="file-thumbnail folder-preview">
                        <img src="${previewUrl}" alt="${file.name}" loading="lazy">
                        <div class="folder-badge">📁</div>
                    </div>
                    <div class="file-name">${file.name}</div>
                    <input type="text" class="rename-input" style="display: none;">
                `;
            } else {
                // 服务器确认没有预览图，直接显示文件夹图标
                // console.log(`[Disk] 文件夹 ${file.name} 无预览图，显示图标`);
                const icon = this.getFileIcon(file);
                div.innerHTML = `
                    ${checkMark}
                    <div class="file-icon">
                        ${icon}
                    </div>
                    <div class="file-name">${file.name}</div>
                    <input type="text" class="rename-input" style="display: none;">
                `;
            }
        } else if (isImage && file.type !== 'directory') {
            // 添加时间戳防止缓存
            const username = this.getCurrentUsername();
            const previewUrl = username 
                ? `/api/disk/preview?username=${encodeURIComponent(username)}&path=${encodeURIComponent(file.path)}&t=${Date.now()}`
                : `/api/disk/preview?path=${encodeURIComponent(file.path)}&t=${Date.now()}`;
            div.innerHTML = `
                ${checkMark}
                <div class="file-thumbnail">
                    <img src="${previewUrl}" alt="${file.name}" loading="lazy">
                </div>
                <div class="file-name">${file.name}</div>
                <input type="text" class="rename-input" style="display: none;">
                ${size ? `<div class="file-info">${size}</div>` : ''}
            `;
        } else {
            const icon = this.getFileIcon(file);
            div.innerHTML = `
                ${checkMark}
                <div class="file-icon">
                    ${icon}
                </div>
                <div class="file-name">${file.name}</div>
                <input type="text" class="rename-input" style="display: none;">
                ${size ? `<div class="file-info">${size}</div>` : ''}
            `;
        }

        // 用于区分单击和双击的定时器
        let clickTimer = null;
        
        // 单击选中（Windows 11 行为）
        div.addEventListener('click', (e) => {
            // 如果正在重命名，不处理
            if (e.target.classList.contains('rename-input')) {
                return;
            }
            e.stopPropagation();
            
            const isAlreadySelected = this.selection.isSelected(file.path);
            const clickedOnName = e.target.classList.contains('file-name');
            const ctrlKey = e.ctrlKey;
            
            // 清除之前的定时器
            if (clickTimer) {
                clearTimeout(clickTimer);
                clickTimer = null;
            }
            
            // 延迟执行单击操作，给双击留出时间
            clickTimer = setTimeout(() => {
                clickTimer = null;
                
                if (ctrlKey) {
                    // Ctrl+点击：切换选中状态（多选）
                    this.selection.toggleSelection(div);
                } else if (clickedOnName && isAlreadySelected) {
                    // 点击已选中项的名称：触发重命名
                    this.startRename(div);
                } else {
                    // 普通点击：选中当前项，取消其他选择
                    this.selection.selectOnly(div);
                }
            }, 200);
        });

        // 双击进入文件夹或打开文件（整个项目都可以双击）
        div.addEventListener('dblclick', (e) => {
            // 如果正在重命名，不处理
            if (e.target.classList.contains('rename-input')) {
                return;
            }
            e.stopPropagation();
            
            // 取消单击的定时器，防止双击时执行单击操作
            if (clickTimer) {
                clearTimeout(clickTimer);
                clickTimer = null;
            }
            
            if (file.type === 'directory') {
                this.navigateToPath(file.path);
            } else {
                this.downloadFile(file.path);
            }
        });

        // 拖拽开始
        div.addEventListener('dragstart', (e) => {
            e.stopPropagation();
            div.classList.add('dragging');
            e.dataTransfer.effectAllowed = 'move';
            e.dataTransfer.setData('text/plain', JSON.stringify({
                type: file.type, // 'directory' 或 'file'
                path: file.path,
                name: file.name,
                isDirectory: file.type === 'directory',
                pngCount: file.pngCount || 0, // PNG文件数量
                hasPreview: file.hasPreview || false, // 是否有预览图
                needsMatting: file.needsMatting || false // 是否需要抠图
            }));
        });

        div.addEventListener('dragend', () => {
            div.classList.remove('dragging');
            document.querySelectorAll('.file-item.drag-target').forEach(el => {
                el.classList.remove('drag-target');
            });
        });

        // 文件夹可以接收拖拽
        if (file.type === 'directory') {
            div.addEventListener('dragover', (e) => {
                e.preventDefault();
                e.stopPropagation();
                const draggingEl = document.querySelector('.file-item.dragging');
                if (draggingEl && draggingEl !== div) {
                    div.classList.add('drag-target');
                    e.dataTransfer.dropEffect = 'move';
                }
            });

            div.addEventListener('dragleave', (e) => {
                e.stopPropagation();
                div.classList.remove('drag-target');
            });

            div.addEventListener('drop', async (e) => {
                e.preventDefault();
                e.stopPropagation();
                div.classList.remove('drag-target');

                try {
                    const data = JSON.parse(e.dataTransfer.getData('text/plain'));
                    if (data.type === 'move-file' && data.path !== file.path) {
                        await this.moveFile(data.path, file.path);
                    }
                } catch (error) {
                    // 可能是外部文件拖拽，忽略
                }
            });
        }

        return div;
    }

    // 移动文件/文件夹
    async moveFile(sourcePath, targetFolder, options = {}) {
        const { suppressReload = false, silent = false } = options;
        const username = this.getCurrentUsername();
        if (!username) {
            if (!silent) {
                this.showGlobalAlert('请先登录');
            }
            return;
        }
        
        try {
            const response = await fetch('/api/disk/move', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    username: username,
                    sourcePath,
                    targetFolder
                })
            });

            if (!response.ok) {
                if (!silent) {
                    await this.handleServerError(response, '移动失败');
                }
                return false;
            }

            const data = await response.json();
            if (data.success) {
                if (!suppressReload) {
                    await this.loadFiles();
                }
                return true;
            } else {
                if (!silent) {
                    this.showGlobalAlert('移动失败: ' + (data.message || '未知错误'));
                }
                return false;
            }
        } catch (error) {
            if (!silent) {
                this.showGlobalAlert('移动失败: ' + (error.message || '网络错误'));
            }
            return false;
        }
    }

    getFileIcon(file) {
        if (file.type === 'directory') {
            return `
                <svg class="folder-icon" viewBox="0 0 64 64" fill="currentColor">
                    <path d="M8 12h20l4 6h24a4 4 0 014 4v28a4 4 0 01-4 4H8a4 4 0 01-4-4V16a4 4 0 014-4z"/>
                </svg>
            `;
        }

        const ext = file.name.split('.').pop().toLowerCase();
        
        if (['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg'].includes(ext)) {
            return `
                <svg class="file-icon-image" viewBox="0 0 64 64" fill="currentColor">
                    <path d="M12 8h40a4 4 0 014 4v40a4 4 0 01-4 4H12a4 4 0 01-4-4V12a4 4 0 014-4z"/>
                    <circle cx="20" cy="20" r="4" fill="white"/>
                    <path d="M8 48l16-16 12 12 16-20v24H8z" fill="white" opacity="0.8"/>
                </svg>
            `;
        }

        if (['mp4', 'avi', 'mov', 'wmv', 'flv', 'mkv'].includes(ext)) {
            return `
                <svg class="file-icon-video" viewBox="0 0 64 64" fill="currentColor">
                    <path d="M12 12h40a4 4 0 014 4v32a4 4 0 01-4 4H12a4 4 0 01-4-4V16a4 4 0 014-4z"/>
                    <path d="M24 20l20 12-20 12z" fill="white"/>
                </svg>
            `;
        }

        if (['mp3', 'wav', 'ogg', 'flac', 'aac'].includes(ext)) {
            return `
                <svg class="file-icon-audio" viewBox="0 0 64 64" fill="currentColor">
                    <path d="M12 12h40a4 4 0 014 4v32a4 4 0 01-4 4H12a4 4 0 01-4-4V16a4 4 0 014-4z"/>
                    <path d="M24 20h4v20a6 6 0 11-4-5.66V20zm20-4v20a6 6 0 11-4-5.66V16h4z" fill="white"/>
                </svg>
            `;
        }

        if (['zip', 'rar', '7z', 'tar', 'gz'].includes(ext)) {
            return `
                <svg class="file-icon-zip" viewBox="0 0 64 64" fill="currentColor">
                    <path d="M16 8h32a4 4 0 014 4v40a4 4 0 01-4 4H16a4 4 0 01-4-4V12a4 4 0 014-4z"/>
                    <rect x="28" y="12" width="8" height="4" fill="white"/>
                    <rect x="28" y="20" width="8" height="4" fill="white"/>
                    <rect x="28" y="28" width="8" height="4" fill="white"/>
                    <rect x="28" y="36" width="8" height="8" rx="2" fill="white"/>
                </svg>
            `;
        }

        if (['doc', 'docx', 'txt', 'pdf', 'xls', 'xlsx', 'ppt', 'pptx'].includes(ext)) {
            return `
                <svg class="file-icon-document" viewBox="0 0 64 64" fill="currentColor">
                    <path d="M16 8h24l12 12v32a4 4 0 01-4 4H16a4 4 0 01-4-4V12a4 4 0 014-4z"/>
                    <path d="M40 8v12h12" fill="white" opacity="0.5"/>
                    <rect x="20" y="28" width="24" height="2" fill="white"/>
                    <rect x="20" y="34" width="24" height="2" fill="white"/>
                    <rect x="20" y="40" width="16" height="2" fill="white"/>
                </svg>
            `;
        }

        return `
            <svg class="file-icon-default" viewBox="0 0 64 64" fill="currentColor">
                <path d="M16 8h24l12 12v32a4 4 0 01-4 4H16a4 4 0 01-4-4V12a4 4 0 014-4z"/>
                <path d="M40 8v12h12" fill="white" opacity="0.5"/>
            </svg>
        `;
    }

    formatFileSize(bytes) {
        if (bytes === 0) return '0 B';
        const k = 1024;
        const sizes = ['B', 'KB', 'MB', 'GB'];
        const i = Math.floor(Math.log(bytes) / Math.log(k));
        return Math.round(bytes / Math.pow(k, i) * 100) / 100 + ' ' + sizes[i];
    }

    isImageFile(fileName) {
        const ext = fileName.split('.').pop().toLowerCase();
        return ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg'].includes(ext);
    }
    
    isAnimationFolder(folderName) {
        // 判断是否是动画文件夹（通过名称模式）
        // 放宽匹配规则，让更多文件夹能显示预览图
        return /^player_\d+$/i.test(folderName) || 
               /^(idle|walk|run|attack|死亡|站立|行走|攻击)/i.test(folderName) ||
               /动画|animation|ani|sprite|序列|sequence/i.test(folderName) ||
               // 新增：所有文件夹都尝试显示预览图（如果有图片就显示）
               true; // 默认返回true，让所有文件夹都尝试加载预览图
    }

    // 注意：guessFirstFrameName、tryAlternativePreview 和 showFolderIcon 方法已废弃
    // 现在使用服务器端提供的预览信息，完全避免客户端的404错误

    // 导航到指定路径
    navigateToPath(path) {
        this.pathNav.navigateTo(path);
    }

    // 创建文件夹
    async createFolder() {
        let folderName = '新建文件夹';
        let counter = 1;
        
        while (this.files.some(f => f.name === folderName && f.type === 'directory')) {
            folderName = `新建文件夹 (${counter})`;
            counter++;
        }

        const username = this.getCurrentUsername();
        if (!username) {
            this.showGlobalAlert('请先登录');
            return;
        }

        try {
            const response = await fetch('/api/disk/create-folder', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    username: username,
                    path: this.pathNav.getPath(),
                    name: folderName
                })
            });

            if (!response.ok) {
                await this.handleServerError(response, '创建文件夹失败');
                return;
            }

            const data = await response.json();
            if (data.success) {
                await this.loadFiles();
                const newFolderItem = this.fileList.querySelector(`[data-name="${folderName}"]`);
                if (newFolderItem) {
                    this.startRename(newFolderItem);
                }
            } else {
                this.showGlobalAlert('创建文件夹失败: ' + (data.message || '未知错误'));
            }
        } catch (error) {
            this.showGlobalAlert('创建文件夹失败: ' + (error.message || '网络错误'));
        }
    }

    // 开始重命名（参考 Windows 行为）
    startRename(fileItem) {
        const nameEl = fileItem.querySelector('.file-name');
        const input = fileItem.querySelector('.rename-input');
        if (!nameEl || !input) return;

        const oldName = fileItem.dataset.name;
        const filePath = fileItem.dataset.path;

        // 标记当前正在重命名
        this._isRenaming = true;

        // 显示输入框，隐藏文件名
        input.value = oldName;
        nameEl.style.display = 'none';
        input.style.display = '';

        // 选中文件名（不含扩展名，文件夹则全选）
        setTimeout(() => {
            const dotIndex = oldName.lastIndexOf('.');
            if (dotIndex > 0 && fileItem.dataset.type !== 'directory') {
                input.setSelectionRange(0, dotIndex);
            } else {
                input.select();
            }
            input.focus();
        }, 10);

        // 状态标记
        let finished = false;

        const exitRename = () => {
            this._isRenaming = false;
            input.style.display = 'none';
            nameEl.style.display = '';
        };

        const commitRename = async () => {
            if (finished) return;
            finished = true;

            const newName = input.value.trim();
            exitRename();

            // 名字有效且有变化才提交
            if (newName && newName !== oldName) {
                await this.renameFile(filePath, newName);
            }
        };

        const cancelRename = () => {
            if (finished) return;
            finished = true;
            exitRename();
        };

        // 使用 addEventListener 确保事件被捕获
        const handleBlur = () => {
            input.removeEventListener('blur', handleBlur);
            input.removeEventListener('keydown', handleKeydown);
            if (!finished) {
                commitRename();
            }
        };

        const handleKeydown = (e) => {
            if (e.key === 'Enter') {
                e.preventDefault();
                e.stopPropagation();
                input.removeEventListener('blur', handleBlur);
                input.removeEventListener('keydown', handleKeydown);
                commitRename();
            } else if (e.key === 'Escape') {
                e.preventDefault();
                e.stopPropagation();
                input.removeEventListener('blur', handleBlur);
                input.removeEventListener('keydown', handleKeydown);
                cancelRename();
            }
        };

        input.addEventListener('blur', handleBlur);
        input.addEventListener('keydown', handleKeydown);
    }

    // 执行重命名
    async renameFile(oldPath, newName) {
        const username = this.getCurrentUsername();
        if (!username) {
            this.showGlobalAlert('请先登录');
            return;
        }
        
        try {
            const response = await fetch('/api/disk/rename', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    username: username,
                    oldPath: oldPath,
                    newName: newName
                })
            });

            const data = await response.json();
            if (data.success) {
                this.loadFiles();
            } else {
                this.showGlobalAlert('重命名失败: ' + data.message);
                this.loadFiles();
            }
        } catch (error) {
            console.error('重命名失败:', error);
            this.showGlobalAlert('重命名失败');
            this.loadFiles();
        }
    }

    // 下载文件
    downloadFile(filePath) {
        const username = this.getCurrentUsername();
        if (!username) {
            this.showGlobalAlert('请先登录');
            return;
        }
        window.open(`/api/disk/download?username=${encodeURIComponent(username)}&path=${encodeURIComponent(filePath)}`, '_blank');
    }

    async copyFile(sourcePath, targetFolder, options = {}) {
        const { suppressReload = false, silent = false } = options;
        const username = this.getCurrentUsername();
        if (!username) {
            if (!silent) {
                this.showGlobalAlert('请先登录');
            }
            return;
        }
        
        try {
            const response = await fetch('/api/disk/copy', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    username: username,
                    sourcePath,
                    targetFolder
                })
            });

            if (!response.ok) {
                if (!silent) {
                    await this.handleServerError(response, '复制失败');
                }
                return false;
            }

            const data = await response.json();
            if (data.success) {
                if (!suppressReload) {
                    await this.loadFiles();
                }
                return true;
            } else {
                if (!silent) {
                    this.showGlobalAlert('复制失败: ' + (data.message || '未知错误'));
                }
                return false;
            }
        } catch (error) {
            if (!silent) {
                this.showGlobalAlert('复制失败: ' + (error.message || '网络错误'));
            }
            return false;
        }
    }

    showLoading(show) {
        if (show) {
            this.loading.classList.add('show');
        } else {
            this.loading.classList.remove('show');
        }
    }
}

// 初始化
document.addEventListener('DOMContentLoaded', () => {
    window.diskManager = new DiskManager();
});
