// 素材管理主逻辑模块（参考 client/js/disk/disk.js）

class ResourceManager {
    constructor(options = {}) {
        this.apiBaseUrl = options.apiBaseUrl || 'http://localhost:3000';
        this.files = [];
        this.currentPath = '';
        
        // DOM 元素
        this.container = document.querySelector('.disk-container');
        this.dropZone = null;
        this.fileList = null;
        this.breadcrumb = null;
        this.emptyState = null;
        this.loading = null;
        this.selectionBar = null;
        this.selectionCount = null;
        this.selectionBox = null;
        this.contextMenu = null;
        this.fileInput = null;
        this.searchInput = null;
        this.searchClear = null;
        this.btnUpload = null;
        this.btnDelete = null;
        
        // 功能模块
        this.pathNav = null;
        this.selection = null;
        this.searchBar = null;
        this.contextMenuManager = null;
        this.shortcutKeys = null;
        
        // 等待 DOM 加载完成
        if (document.readyState === 'loading') {
            document.addEventListener('DOMContentLoaded', () => this.init());
        } else {
            this.init();
        }
    }

    async init() {
        this.initElements();
        this.initPath();
        this.initSelection();
        this.initShortcutKeys();
        this.initSearchBar();
        this.initContextMenu();
        this.bindEvents();
        
        // 加载文件列表
        await this.loadFiles();
    }

    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.selectionBar = document.getElementById('selectionBar');
        this.selectionCount = document.getElementById('selectionCount');
        this.selectionBox = document.getElementById('selectionBox');
        this.contextMenu = document.getElementById('contextMenu');
        this.fileInput = null; // 动态创建
        this.searchInput = document.getElementById('searchInput');
        this.searchClear = document.getElementById('searchClear');
        this.btnUpload = document.getElementById('btnUpload');
        this.btnDelete = document.getElementById('btnDelete');
    }

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

    // 初始化框选功能
    initSelection() {
        if (this.dropZone && this.fileList && this.selectionBox) {
            this.selection = new ResourceManagerMultipleSelection({
                container: this.dropZone,
                itemsContainer: this.fileList,
                selectionBox: this.selectionBox,
                selectionBar: this.selectionBar,
                selectionCount: this.selectionCount,
                itemSelector: '.file-item',
                onSelectionChange: (selectedItems) => {
                    // 选择变化时的回调
                }
            });
        }
    }

    // 初始化快捷键
    initShortcutKeys() {
        if (this.shortcutKeys) {
            this.shortcutKeys.destroy();
        }

        this.shortcutKeys = new ResourceManagerShortcutKeys({
            selection: this.selection,
            onDelete: () => this.deleteSelected(),
            onRename: () => this.renameSelected()
        });
    }

    // 初始化搜索栏
    initSearchBar() {
        if (this.searchInput && this.fileList) {
            this.searchBar = new ResourceManagerSearchBar({
                input: this.searchInput,
                clearButton: this.searchClear,
                fileList: this.fileList,
                emptyState: this.emptyState,
                getResources: () => this.files,
                renderAll: () => this.renderFiles(),
                createFileItem: (file) => this.createFileItem(file),
                noResultMessage: '没有找到匹配的资源'
            });
        }
    }

    // 初始化右键菜单
    initContextMenu() {
        if (!this.dropZone || !this.contextMenu) return;

        this.contextMenuManager = new ResourceManagerRightClickMenu({
            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');
        
        if (!this.contextMenu) return false;
        
        const newBtn = this.contextMenu.querySelector('[data-action="new"]');
        const uploadBtn = this.contextMenu.querySelector('[data-action="upload"]');
        const backBtn = this.contextMenu.querySelector('[data-action="back"]');
        const deleteBtn = this.contextMenu.querySelector('[data-action="delete"]');
        const renameBtn = this.contextMenu.querySelector('[data-action="rename"]');
        const refreshBtn = this.contextMenu.querySelector('[data-action="refresh"]');
        
        const isRoot = this.currentPath === '';
        
        // 新建分类：只在根目录时显示
        if (newBtn) {
            newBtn.style.display = isRoot ? 'flex' : 'none';
        }
        
        // 上传素材：只在子目录时显示
        if (uploadBtn) {
            uploadBtn.style.display = isRoot ? 'none' : 'flex';
        }
        
        // 返回上级：只在子目录时显示
        if (backBtn) {
            backBtn.style.display = isRoot ? 'none' : 'flex';
        }
        
        // 刷新按钮始终显示
        if (refreshBtn) {
            refreshBtn.style.display = 'flex';
        }
        
        // 如果点击在文件项上
        if (fileItem) {
            // 确保被点击的项被选中
            const isSelected = this.selection && this.selection.isSelected(fileItem.dataset.path);
            if (!isSelected && this.selection) {
                this.selection.selectOnly(fileItem);
            }
            
            if (deleteBtn) deleteBtn.style.display = 'flex';
            if (renameBtn) renameBtn.style.display = 'flex';
        } else {
            if (deleteBtn) deleteBtn.style.display = 'none';
            if (renameBtn) renameBtn.style.display = 'none';
        }
        
        // 更新分隔线显示
        this.updateContextMenuDividers();
        
        return true;
    }
    
    // 更新右键菜单分隔线显示
    updateContextMenuDividers() {
        if (!this.contextMenu) return;
        
        const items = Array.from(this.contextMenu.children);
        let lastVisibleWasDivider = true;
        
        items.forEach((item, index) => {
            if (item.classList.contains('context-menu-divider')) {
                // 如果上一个可见项也是分隔线，或者是第一个，隐藏
                if (lastVisibleWasDivider) {
                    item.style.display = 'none';
                } else {
                    item.style.display = 'block';
                    lastVisibleWasDivider = true;
                }
            } else if (item.style.display !== 'none') {
                lastVisibleWasDivider = false;
            }
        });
        
        // 隐藏末尾的分隔线
        for (let i = items.length - 1; i >= 0; i--) {
            const item = items[i];
            if (item.classList.contains('context-menu-divider')) {
                if (item.style.display !== 'none') {
                    item.style.display = 'none';
                }
            } else if (item.style.display !== 'none') {
                break;
            }
        }
    }

    // 处理右键菜单操作
    handleContextMenuAction(action) {
        switch (action) {
            case 'new':
                this.createFolder();
                break;
            case 'upload':
                // 触发上传
                this.triggerUpload();
                break;
            case 'back':
                // 返回上级目录
                this.loadFiles('');
                break;
            case 'delete':
                this.deleteSelected();
                break;
            case 'rename':
                this.renameSelected();
                break;
            case 'refresh':
                this.loadFiles(this.currentPath);
                break;
        }
    }

    bindEvents() {
        // 上传按钮已移除，使用右键菜单或拖拽上传

        // 删除按钮
        if (this.btnDelete) {
            this.btnDelete.addEventListener('click', () => this.deleteSelected());
        }

        // 拖拽上传
        if (this.dropZone) {
            console.log('[ResourceManager] 绑定拖拽事件到 dropZone:', this.dropZone);
            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));
        } else {
            console.error('[ResourceManager] dropZone 未找到！');
        }
    }
    
    // 触发上传（动态创建文件输入）
    triggerUpload() {
        // 创建新的文件输入（每次都重新创建以确保属性正确）
        const newInput = document.createElement('input');
        newInput.type = 'file';
        newInput.style.display = 'none';
        
        // 使用文件夹选择模式
        newInput.webkitdirectory = true;
        newInput.directory = true;
        newInput.multiple = true;
        
        // 移除旧的文件输入
        if (this.fileInput) {
            this.fileInput.remove();
        }
        
        // 添加到DOM
        document.body.appendChild(newInput);
        this.fileInput = newInput;
        
        // 绑定change事件 - 跳过浏览器确认后直接处理
        this.fileInput.addEventListener('change', (e) => this.handleFileSelectDirect(e));
        
        // 触发点击
        this.fileInput.click();
    }
    
    // 直接处理文件选择（跳过额外确认）
    async handleFileSelectDirect(e) {
        const files = Array.from(e.target.files);
        if (files.length === 0) {
            this.fileInput.value = '';
            return;
        }

        // 验证文件夹结构
        const validation = this.validateFolderFiles(files);
        
        if (!validation.valid) {
            this.showError(validation.errors.join('\n'));
            this.fileInput.value = '';
            return;
        }
        
        // 浏览器已经确认过了，直接上传，不再弹出我们的确认框
        const filesToUpload = validation.files.map(file => ({
            file: file,
            path: file.webkitRelativePath || file.name
        }));
        
        try {
            await this.uploadFolderFiles(validation.folderName, filesToUpload);
            this.showSuccess(`上传成功: ${validation.folderName}`);
            await this.loadFiles(this.currentPath);
        } catch (error) {
            this.showError('上传失败: ' + error.message);
        }
        
        this.fileInput.value = '';
    }

    // 加载文件列表
    async loadFiles(path = '') {
        this.showLoading(true);
        if (this.selection) {
            this.selection.clearSelection();
        }
        if (this.searchBar) {
            this.searchBar.clear({ noRender: true });
        }
        
        this.currentPath = path;

        try {
            if (path === '') {
                // 根目录：加载分类列表
                const response = await fetch(`${this.apiBaseUrl}/api/store/categories`);
                if (!response.ok) {
                    throw new Error(`加载分类失败: ${response.status}`);
                }
                const result = await response.json();
                
                if (result.success && result.categories) {
                    this.files = result.categories.map(cat => ({
                        name: cat.name,
                        path: cat.dir,
                        type: 'directory',
                        isCategory: true
                    }));
                } else {
                    this.files = [];
                }
            } else {
                // 子目录：加载资源列表
                const response = await fetch(`${this.apiBaseUrl}/api/store/resources?category=${encodeURIComponent(path)}`);
                if (!response.ok) {
                    throw new Error(`加载资源失败: ${response.status}`);
                }
                const result = await response.json();
                
                if (result.success && result.resources) {
                    this.files = result.resources.map(res => ({
                        ...res,
                        type: 'directory'
                    }));
                } else {
                    this.files = [];
                }
            }
            
            this.renderFiles();
        } catch (error) {
            console.error('[ResourceManager] 加载失败:', error);
            this.files = [];
            this.renderFiles();
            this.showError('加载失败: ' + error.message);
        } finally {
            this.showLoading(false);
        }
    }

    // 渲染文件列表
    renderFiles() {
        if (!this.fileList) return;
        
        this.fileList.innerHTML = '';

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

        if (this.emptyState) {
            this.emptyState.classList.remove('show');
        }

        this.files.forEach(file => {
            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;
        
        // 在根目录时，分类文件夹可以拖拽排序
        if (this.currentPath === '' && file.isCategory) {
            div.draggable = true;
            this.setupDragReorder(div, file);
        }

        // 勾选标记
        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>
        `;

        // 检查是否有预览图
        if (file.previewUrl) {
            div.innerHTML = `
                ${checkMark}
                <div class="file-thumbnail folder-preview">
                    <img src="${this.apiBaseUrl}${file.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 {
            div.innerHTML = `
                ${checkMark}
                <div class="file-icon folder-icon">
                    <svg 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>
                </div>
                <div class="file-name">${file.name}</div>
                <input type="text" class="rename-input" style="display: none;">
            `;
        }

        // 点击事件
        let clickTimer = null;
        
        div.addEventListener('click', (e) => {
            if (e.target.classList.contains('rename-input')) return;
            e.stopPropagation();
            
            const isAlreadySelected = this.selection && 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 && this.selection) {
                    this.selection.toggleSelection(div);
                } else if (clickedOnName && isAlreadySelected) {
                    this.startRename(div);
                } else if (this.selection) {
                    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') {
                if (file.isCategory) {
                    this.pathNav.navigateTo(file.path);
                } else {
                    // 资源文件夹可以进一步打开查看
                    // 或者在这里可以打开预览
                }
            }
        });

        return div;
    }

    // 开始重命名
    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;

        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 = () => {
            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();
        };

        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) {
        try {
            const response = await fetch(`${this.apiBaseUrl}/api/admin/store/rename`, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ resourcePath: oldPath, newName })
            });

            const result = await response.json();
            if (result.success) {
                this.showSuccess('重命名成功');
                await this.loadFiles(this.currentPath);
            } else {
                this.showError('重命名失败: ' + (result.message || '未知错误'));
                await this.loadFiles(this.currentPath);
            }
        } catch (error) {
            this.showError('重命名失败: ' + error.message);
            await this.loadFiles(this.currentPath);
        }
    }

    // 重命名选中项
    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);
        }
    }

    // 删除选中项
    async deleteSelected() {
        console.log('[ResourceManager] deleteSelected 被调用');
        console.log('[ResourceManager] this.selection:', this.selection);
        
        if (!this.selection) {
            console.log('[ResourceManager] selection 为空，退出');
            return;
        }
        
        const count = this.selection.getSelectedCount();
        console.log('[ResourceManager] 选中数量:', count);
        
        if (count === 0) {
            console.log('[ResourceManager] 没有选中项，退出');
            return;
        }

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

        try {
            const selectedPaths = this.selection.getSelectedItems();
            
            for (const path of selectedPaths) {
                const response = await fetch(`${this.apiBaseUrl}/api/admin/store/delete`, {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ resourcePath: path })
                });

                const result = await response.json();
                if (!result.success) {
                    this.showError('删除失败: ' + (result.message || '未知错误'));
                }
            }

            this.selection.clearSelection();
            await this.loadFiles(this.currentPath);
            this.showSuccess('删除成功');
        } catch (error) {
            this.showError('删除失败: ' + error.message);
        }
    }

    // 设置拖拽排序
    setupDragReorder(div, file) {
        div.addEventListener('dragstart', (e) => {
            e.stopPropagation();
            div.classList.add('dragging');
            e.dataTransfer.effectAllowed = 'move';
            e.dataTransfer.setData('text/plain', JSON.stringify({
                type: 'reorder',
                name: file.name
            }));
        });

        div.addEventListener('dragend', () => {
            div.classList.remove('dragging');
            // 移除所有拖拽目标样式
            this.fileList.querySelectorAll('.file-item.drag-over-left, .file-item.drag-over-right').forEach(el => {
                el.classList.remove('drag-over-left', 'drag-over-right');
            });
            // 确保移除上传提示
            if (this.dropZone) {
                this.dropZone.classList.remove('drag-over');
            }
        });

        div.addEventListener('dragover', (e) => {
            e.preventDefault();
            
            // 只有内部拖拽排序时才处理
            const draggingEl = this.fileList.querySelector('.file-item.dragging');
            if (!draggingEl || draggingEl === div) {
                // 外部文件拖入时，不阻止冒泡，让 dropZone 处理
                return;
            }
            
            e.stopPropagation();
            e.dataTransfer.dropEffect = 'move';
            
            // 判断鼠标在元素的左半边还是右半边
            const rect = div.getBoundingClientRect();
            const midX = rect.left + rect.width / 2;
            
            div.classList.remove('drag-over-left', 'drag-over-right');
            if (e.clientX < midX) {
                div.classList.add('drag-over-left');
            } else {
                div.classList.add('drag-over-right');
            }
        });

        div.addEventListener('dragleave', (e) => {
            // 只有内部拖拽排序时才阻止冒泡
            const draggingEl = this.fileList.querySelector('.file-item.dragging');
            if (draggingEl) {
                e.stopPropagation();
            }
            div.classList.remove('drag-over-left', 'drag-over-right');
        });

        div.addEventListener('drop', async (e) => {
            e.preventDefault();
            
            // 如果是外部文件拖入，让事件继续冒泡到 dropZone
            if (e.dataTransfer.types.includes('Files') && !e.dataTransfer.getData('text/plain')) {
                console.log('[ResourceManager] 外部文件拖入到文件项，转发到 dropZone');
                this.handleDrop(e);
                return;
            }
            
            e.stopPropagation();
            
            const isLeft = div.classList.contains('drag-over-left');
            div.classList.remove('drag-over-left', 'drag-over-right');

            try {
                const data = JSON.parse(e.dataTransfer.getData('text/plain'));
                if (data.type !== 'reorder') return;
                
                const draggedName = data.name;
                const targetName = file.name;
                
                if (draggedName === targetName) return;
                
                // 重新计算顺序
                const currentOrder = this.files.map(f => f.name);
                const draggedIndex = currentOrder.indexOf(draggedName);
                let targetIndex = currentOrder.indexOf(targetName);
                
                if (draggedIndex === -1 || targetIndex === -1) return;
                
                // 移除拖拽的元素
                currentOrder.splice(draggedIndex, 1);
                
                // 重新计算目标位置（因为移除了一个元素）
                targetIndex = currentOrder.indexOf(targetName);
                
                // 插入到目标位置
                if (isLeft) {
                    currentOrder.splice(targetIndex, 0, draggedName);
                } else {
                    currentOrder.splice(targetIndex + 1, 0, draggedName);
                }
                
                // 保存新顺序
                await this.saveCategoryOrder(currentOrder);
            } catch (error) {
                console.error('[ResourceManager] 拖拽排序失败:', error);
            }
        });
    }

    // 保存分类排序
    async saveCategoryOrder(order) {
        try {
            const response = await fetch(`${this.apiBaseUrl}/api/admin/store/update-order`, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ order })
            });

            const result = await response.json();
            if (result.success) {
                this.showSuccess('排序已保存');
                await this.loadFiles('');
            } else {
                this.showError('保存排序失败: ' + (result.message || '未知错误'));
            }
        } catch (error) {
            this.showError('保存排序失败: ' + error.message);
        }
    }

    // 创建文件夹
    async createFolder() {
        if (this.currentPath !== '') {
            this.showError('只能在根目录创建分类文件夹');
            return;
        }

        const folderName = await this.showPrompt('请输入分类文件夹名称：');
        if (!folderName || !folderName.trim()) return;

        const name = folderName.trim();
        if (/[\\/:*?"<>|]/.test(name)) {
            this.showError('文件夹名称包含非法字符');
            return;
        }

        try {
            const response = await fetch(`${this.apiBaseUrl}/api/admin/store/create-folder`, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ name })
            });

            const result = await response.json();
            if (result.success) {
                this.showSuccess('创建文件夹成功');
                await this.loadFiles('');
            } else {
                this.showError('创建文件夹失败: ' + (result.message || '未知错误'));
            }
        } catch (error) {
            this.showError('创建文件夹失败: ' + error.message);
        }
    }

    // 处理文件选择（始终为文件夹模式）
    async handleFileSelect(e) {
        const files = Array.from(e.target.files);
        if (files.length === 0) {
            this.fileInput.value = '';
            return;
        }

        // 验证文件夹结构
        const validation = this.validateFolderFiles(files);
        
        if (!validation.valid) {
            this.showError(validation.errors.join('\n'));
            this.fileInput.value = '';
            return;
        }
        
        const targetPath = this.currentPath || validation.folderName;
        const confirmMsg = this.currentPath 
            ? `将上传文件夹 "${validation.folderName}" 到分类 "${this.currentPath}"，包含 ${validation.files.length} 个PNG图片，确认上传？`
            : `将上传文件夹 "${validation.folderName}"，包含 ${validation.files.length} 个PNG图片，确认上传？`;
        
        const confirmed = await this.showConfirm(confirmMsg);
        if (!confirmed) {
            this.fileInput.value = '';
            return;
        }

        // 根据当前位置决定上传方式
        // 转换 validation.files (File[]) 为 {file, path}[] 格式
        const filesToUpload = validation.files.map(file => ({
            file: file,
            path: file.webkitRelativePath || file.name
        }));
        
        if (this.currentPath === '') {
            // 在根目录上传，文件夹名就是分类名
            await this.uploadFolderFiles(validation.folderName, filesToUpload);
        } else {
            // 在子目录上传
            await this.uploadFolderFiles(validation.folderName, filesToUpload);
        }
        
        this.fileInput.value = '';
    }
    
    
    // 验证通过文件输入选择的文件夹
    validateFolderFiles(files) {
        const errors = [];
        const validFiles = [];
        let folderName = '';
        
        // 获取文件夹名（第一层目录）
        const paths = new Set();
        for (const file of files) {
            const relativePath = file.webkitRelativePath || file.name;
            const parts = relativePath.split('/');
            if (parts.length > 0) {
                paths.add(parts[0]);
                if (!folderName) folderName = parts[0];
            }
        }
        
        // 检查是否只有一个顶级文件夹
        if (paths.size > 1) {
            errors.push('请只选择一个文件夹');
            return { valid: false, errors, files: [], folderName: '' };
        }
        
        for (const file of files) {
            const relativePath = file.webkitRelativePath || file.name;
            const parts = relativePath.split('/');
            
            // 检查是否有子文件夹（路径深度超过2层）
            if (parts.length > 2) {
                errors.push(`不允许有子文件夹: ${parts.slice(0, -1).join('/')}`);
                continue;
            }
            
            // 检查文件类型
            const fileName = file.name.toLowerCase();
            if (!fileName.endsWith('.png')) {
                errors.push(`文件 "${file.name}" 不是PNG格式，只允许PNG图片`);
                continue;
            }
            
            validFiles.push(file);
        }
        
        if (validFiles.length === 0 && errors.length === 0) {
            errors.push('文件夹为空或没有PNG图片');
        }
        
        // 只显示前5个错误
        const displayErrors = errors.slice(0, 5);
        if (errors.length > 5) {
            displayErrors.push(`... 还有 ${errors.length - 5} 个错误`);
        }
        
        return {
            valid: errors.length === 0,
            errors: displayErrors,
            files: validFiles,
            folderName
        };
    }
    
    // 上传文件
    async uploadFiles(files) {
        if (files.length === 0) return;

        // 获取目标路径
        const category = this.currentPath || files[0].webkitRelativePath?.split('/')[0] || 'default';
        const folderName = files[0].webkitRelativePath?.split('/')[0] || 'upload_' + Date.now();

        const formData = new FormData();
        formData.append('category', category);
        formData.append('name', folderName);
        formData.append('price', 0);
        
        for (const file of files) {
            formData.append('files', file);
        }

        try {
            const response = await fetch(`${this.apiBaseUrl}/api/admin/store/upload`, {
                method: 'POST',
                body: formData
            });

            const result = await response.json();
            if (result.success) {
                this.showSuccess('上传成功');
                await this.loadFiles(this.currentPath);
            } else {
                this.showError('上传失败: ' + (result.message || '未知错误'));
            }
        } catch (error) {
            this.showError('上传失败: ' + error.message);
        }
    }

    // 检查是否是外部文件拖入（而非内部排序拖拽）
    isExternalFileDrag(e) {
        // 如果有正在拖拽的内部元素，说明是内部排序
        if (this.fileList && this.fileList.querySelector('.file-item.dragging')) {
            return false;
        }
        // 检查是否有文件类型
        return e.dataTransfer.types.includes('Files');
    }

    // 拖拽处理
    handleDragEnter(e) {
        e.preventDefault();
        e.stopPropagation();
        console.log('[ResourceManager] dragenter 触发');
        
        // 只有外部文件拖入时才显示上传提示
        if (this.isExternalFileDrag(e)) {
            this.dropZone.classList.add('drag-over');
        }
    }

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

    handleDragLeave(e) {
        e.preventDefault();
        e.stopPropagation();
        
        // 检查是否真正离开了 dropZone（而不是进入子元素）
        if (!this.dropZone.contains(e.relatedTarget)) {
            this.dropZone.classList.remove('drag-over');
        }
    }

    async handleDrop(e) {
        console.log('[ResourceManager] ===== handleDrop 触发 =====');
        e.preventDefault();
        e.stopPropagation();
        this.dropZone.classList.remove('drag-over');

        console.log('[ResourceManager] dataTransfer.types:', Array.from(e.dataTransfer.types));
        console.log('[ResourceManager] isExternalFileDrag:', this.isExternalFileDrag(e));

        // 如果是内部排序拖拽，不处理文件上传
        if (!this.isExternalFileDrag(e)) {
            console.log('[ResourceManager] 是内部拖拽，跳过');
            return;
        }

        const items = e.dataTransfer.items;
        console.log('[ResourceManager] items:', items, 'length:', items ? items.length : 0);
        if (!items) return;

        const entries = [];
        for (let i = 0; i < items.length; i++) {
            const item = items[i].webkitGetAsEntry();
            console.log(`[ResourceManager] entry ${i}:`, item ? item.name : 'null');
            if (item) {
                entries.push(item);
            }
        }

        console.log('[ResourceManager] 共收集到', entries.length, '个 entries');
        await this.processDropEntries(entries);
    }
    
    // 处理拖入的 entries（完全按照 client/js/disk/disk.js 的方式）
    async processDropEntries(entries) {
        console.log('[ResourceManager] processDropEntries 开始处理', entries.length, '个 entries');
        
        // 检查是否有非文件夹
        const hasFiles = entries.some(entry => entry.isFile);
        if (hasFiles) {
            this.showError('只能拖拽文件夹，不能拖拽单个文件');
            return;
        }
        
        const filesToUpload = [];
        
        for (const entry of entries) {
            console.log('[ResourceManager] 开始遍历:', entry.name);
            try {
                await this.traverseEntry(entry, '', filesToUpload);
                console.log('[ResourceManager] 遍历完成:', entry.name, '当前文件数:', filesToUpload.length);
            } catch (err) {
                console.error('[ResourceManager] 遍历失败:', entry.name, err);
            }
        }
        
        console.log('[ResourceManager] 总共收集到', filesToUpload.length, '个 PNG 文件');

        if (filesToUpload.length > 0) {
            // 按文件夹分组
            const folderMap = new Map();
            for (const item of filesToUpload) {
                const folderName = item.path.split('/')[0];
                if (!folderMap.has(folderName)) {
                    folderMap.set(folderName, []);
                }
                folderMap.get(folderName).push(item);
            }
            
            const folderNames = Array.from(folderMap.keys());
            const confirmMsg = `将上传 ${folderMap.size} 个文件夹（${folderNames.slice(0, 5).join('、')}${folderNames.length > 5 ? '...' : ''}），共 ${filesToUpload.length} 个PNG图片\n\n确认上传？`;
            
            const confirmed = await this.showConfirm(confirmMsg);
            if (!confirmed) {
                return;
            }
            
            // 按文件夹逐个上传，每上传完一个就刷新显示
            let successCount = 0;
            let failCount = 0;
            const totalCount = folderMap.size;
            
            for (const [folderName, files] of folderMap) {
                try {
                    await this.uploadFolderFiles(folderName, files);
                    successCount++;
                    // 每上传完一个文件夹就刷新显示
                    await this.loadFiles(this.currentPath);
                    this.showInfo(`上传进度: ${successCount}/${totalCount} - ${folderName}`);
                } catch (error) {
                    console.error(`[ResourceManager] 上传 ${folderName} 失败:`, error);
                    failCount++;
                }
            }
            
            if (failCount === 0) {
                this.showSuccess(`成功上传 ${successCount} 个文件夹`);
            } else {
                this.showWarning(`上传完成: ${successCount} 成功, ${failCount} 失败`);
            }
        } else {
            console.log('[ResourceManager] 没有找到可上传的PNG图片');
            this.showError('没有找到可上传的PNG图片');
        }
    }
    
    // 递归遍历文件夹
    async traverseEntry(entry, relativePath, filesToUpload) {
        console.log('[ResourceManager] traverseEntry:', entry.name, 'isFile:', entry.isFile, 'isDirectory:', entry.isDirectory);
        
        if (entry.isFile) {
            console.log('[ResourceManager] 读取文件:', entry.name);
            const file = await new Promise((resolve, reject) => {
                entry.file(resolve, reject);
            });
            console.log('[ResourceManager] 文件读取完成:', file.name, file.size);
            // 只接受 PNG 文件
            if (file.name.toLowerCase().endsWith('.png')) {
                filesToUpload.push({
                    file: file,
                    path: relativePath + file.name
                });
                console.log('[ResourceManager] 添加PNG:', relativePath + file.name);
            }
        } else if (entry.isDirectory) {
            console.log('[ResourceManager] 开始读取目录:', entry.name);
            const dirReader = entry.createReader();
            
            // 读取所有条目 - readEntries 每次最多返回100条，需要循环读取
            let allEntries = [];
            let batch;
            let readCount = 0;
            do {
                console.log('[ResourceManager] 调用 readEntries 第', readCount + 1, '次');
                batch = await new Promise((resolve) => {
                    dirReader.readEntries(
                        (entries) => {
                            console.log('[ResourceManager] readEntries 成功, 返回', entries.length, '条');
                            resolve(entries);
                        }, 
                        (err) => {
                            console.error('[ResourceManager] readEntries 错误:', err);
                            resolve([]); // 出错返回空数组继续
                        }
                    );
                });
                allEntries = allEntries.concat(batch);
                readCount++;
            } while (batch.length > 0);
            
            console.log('[ResourceManager] 目录', entry.name, '共有', allEntries.length, '个条目');

            for (const childEntry of allEntries) {
                await this.traverseEntry(
                    childEntry,
                    relativePath + entry.name + '/',
                    filesToUpload
                );
            }
            console.log('[ResourceManager] 目录', entry.name, '遍历完成');
        }
    }
    
    // 上传单个文件夹的文件
    async uploadFolderFiles(folderName, files) {
        if (files.length === 0) return;
        
        const category = this.currentPath || folderName;
        
        const formData = new FormData();
        formData.append('category', category);
        formData.append('name', folderName);
        formData.append('price', '0');
        
        for (const item of files) {
            formData.append('files', item.file, item.path);
        }
        
        const response = await fetch(`${this.apiBaseUrl}/api/admin/store/upload`, {
            method: 'POST',
            body: formData
        });
        
        const result = await response.json();
        
        if (!result.success) {
            throw new Error(result.message || '上传失败');
        }
        
        return result;
    }
    
    isImageFile(fileName) {
        const ext = fileName.split('.').pop().toLowerCase();
        return ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg'].includes(ext);
    }

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

    // 显示提示消息
    showHint(message, type = 'info') {
        const hintView = document.getElementById('hintView');
        const hintMessage = document.getElementById('hintMessage');
        
        if (!hintView || !hintMessage) {
            console.log(`[${type}]`, message);
            return;
        }

        // 移除之前的类型类
        hintView.classList.remove('success', 'error', 'warning', 'info');
        hintView.classList.add(type);
        
        hintMessage.textContent = message;
        hintView.classList.remove('hide');
        hintView.classList.add('show');

        // 自动隐藏
        setTimeout(() => {
            hintView.classList.remove('show');
            hintView.classList.add('hide');
        }, 3000);
    }

    showError(message) {
        this.showHint(message, 'error');
    }

    showSuccess(message) {
        this.showHint(message, 'success');
    }

    showWarning(message) {
        this.showHint(message, 'warning');
    }

    showInfo(message) {
        this.showHint(message, 'info');
    }

    // 显示确认对话框
    showConfirm(message) {
        return new Promise((resolve) => {
            const overlay = document.getElementById('globalConfirmOverlay');
            const messageEl = document.getElementById('confirmMessage');
            const okBtn = document.getElementById('confirmOkBtn');
            const cancelBtn = document.getElementById('confirmCancelBtn');

            if (!overlay || !messageEl || !okBtn || !cancelBtn) {
                // 降级到原生 confirm
                resolve(confirm(message));
                return;
            }

            messageEl.textContent = message;
            overlay.classList.add('show');

            const cleanup = () => {
                overlay.classList.remove('show');
                okBtn.removeEventListener('click', handleOk);
                cancelBtn.removeEventListener('click', handleCancel);
            };

            const handleOk = () => {
                cleanup();
                resolve(true);
            };

            const handleCancel = () => {
                cleanup();
                resolve(false);
            };

            okBtn.addEventListener('click', handleOk);
            cancelBtn.addEventListener('click', handleCancel);
        });
    }

    // 显示输入对话框
    showPrompt(message, defaultValue = '') {
        return new Promise((resolve) => {
            const overlay = document.getElementById('globalPromptOverlay');
            const messageEl = document.getElementById('promptMessage');
            const input = document.getElementById('promptInput');
            const okBtn = document.getElementById('promptOkBtn');
            const cancelBtn = document.getElementById('promptCancelBtn');

            if (!overlay || !messageEl || !input || !okBtn || !cancelBtn) {
                // 降级到原生 prompt
                resolve(prompt(message, defaultValue));
                return;
            }

            messageEl.textContent = message;
            input.value = defaultValue;
            overlay.classList.add('show');
            
            // 自动聚焦输入框
            setTimeout(() => {
                input.focus();
                input.select();
            }, 100);

            const cleanup = () => {
                overlay.classList.remove('show');
                okBtn.removeEventListener('click', handleOk);
                cancelBtn.removeEventListener('click', handleCancel);
                input.removeEventListener('keydown', handleKeydown);
            };

            const handleOk = () => {
                const value = input.value;
                cleanup();
                resolve(value);
            };

            const handleCancel = () => {
                cleanup();
                resolve(null);
            };

            const handleKeydown = (e) => {
                if (e.key === 'Enter') {
                    e.preventDefault();
                    handleOk();
                } else if (e.key === 'Escape') {
                    e.preventDefault();
                    handleCancel();
                }
            };

            okBtn.addEventListener('click', handleOk);
            cancelBtn.addEventListener('click', handleCancel);
            input.addEventListener('keydown', handleKeydown);
        });
    }
}

// 导出
if (typeof module !== 'undefined' && module.exports) {
    module.exports = ResourceManager;
} else {
    window.ResourceManager = ResourceManager;
}
