/**
 * 文件列表组件
 */
(function() {
    'use strict';
    
    const { ref, computed, watch, nextTick, onMounted, onUnmounted, getCurrentInstance } = typeof Vue !== 'undefined' ? Vue : {};
    
    if (!Vue || !window.useFileTypes || !window.useFileSort || !window.useFileUtils) {
        console.error('Required dependencies not loaded');
        return;
    }
    
    window.FileList = {
        components: {
            FileCard: window.FileCard,
            ShareModal: typeof window !== 'undefined' && window.ShareModal ? window.ShareModal : null
        },
        props: {
            files: {
                type: Array,
                default: () => []
            },
            selectedFileType: {
                type: String,
                default: 'all'
            },
            sortBy: {
                type: String,
                default: 'date-desc'
            },
            viewMode: {
                type: String,
                default: 'grid' // grid | list
            },
            loading: {
                type: Boolean,
                default: false
            },
            currentPath: {
                type: String,
                default: '全部文件'
            },
            showNewFolderInput: {
                type: Boolean,
                default: false
            },
            folderName: {
                type: String,
                default: ''
            },
            hasMore: {
                type: Boolean,
                default: false
            },
            isLoadingMore: {
                type: Boolean,
                default: false
            },
            clearSelectionTrigger: {
                type: Number,
                default: 0
            }
        },
        emits: ['file-click', 'file-download', 'file-preview', 'file-delete', 'create-folder', 'cancel-new-folder', 'update:folder-name', 'load-more', 'file-select', 'file-unselect', 'selection-change'],
        template: `
            <div class="file-list-container">
                <!-- 分享弹窗 -->
                <component
                    v-if="showShareModal && ShareModalComponent"
                    :is="ShareModalComponent"
                    :model-value="showShareModal"
                    @update:model-value="showShareModal = $event"
                    :file="shareModalFile"
                    :active-tab="shareModalActiveTab"
                    @update:active-tab="shareModalActiveTab = $event" />
                
                <!-- 加载状态 -->
                <div v-if="loading" class="file-list-loading">
                    <el-skeleton :rows="6" animated />
                </div>
                
                <!-- 空状态 -->
                <el-empty 
                    v-else-if="tableData.length === 0 && !showNewFolderInput" 
                    description="暂无文件"
                    :image-size="120">
                    <el-button class="upload-button-table" type="primary" @click="$emit('upload')">上传文件</el-button>
                </el-empty>
                
                    <!-- 文件列表 -->
                    <!-- 使用 Element Plus Table 组件（当为列表视图且路径为"全部文件"时，或者非图片分类时） -->
                    <el-table
                        v-if="!loading && (tableData.length > 0 || showNewFolderInput) && viewMode === 'list' && (currentPath === '全部文件' || selectedFileType !== 'image')"
                        :data="tableData"
                        class="file-list-table"
                        :class="{ 'is-loading-more': isLoadingMore }"
                        stripe
                        @row-click="handleRowClick"
                        @row-mouse-enter="handleRowMouseEnter"
                        @row-mouse-leave="handleRowMouseLeave">
                    <!-- 文件名列 -->
                    <el-table-column label="文件名" min-width="200">
                        <template #default="{ row }">
                            <div v-if="row.isNewFolder" class="file-table-name-cell new-folder-cell">
                                <el-checkbox @click.stop style="visibility: hidden;" />
                                <div class="file-table-icon" style="background-color: #F59E0B15;">
                                    <el-icon :size="24" color="#F59E0B"><Folder /></el-icon>
                                </div>
                                <el-input
                                    v-model="localFolderName"
                                    placeholder="请输入文件夹名称"
                                    size="small"
                                    class="new-folder-input"
                                    @keyup.enter="handleConfirmCreate"
                                    @keyup.esc="handleCancelCreate"
                                    @click.stop
                                    ref="folderNameInputRef" />
                                <div class="new-folder-actions" @click.stop>
                                    <el-button
                                        type="primary"
                                        size="small"
                                        circle
                                        @click="handleConfirmCreate">
                                        <el-icon><Check /></el-icon>
                                    </el-button>
                                    <el-button
                                        type="default"
                                        size="small"
                                        circle
                                        @click="handleCancelCreate">
                                        <el-icon><Close /></el-icon>
                                    </el-button>
                                </div>
                            </div>
                            <div v-else class="file-table-name-cell">
                                <el-checkbox 
                                    :model-value="isFileSelected(row)"
                                    @change="(val) => handleTableCheckboxChange(row, val)"
                                    @click.stop />
                                <!-- 图片或视频显示缩略图 -->
                                <div 
                                    v-if="row._shouldShowThumbnail" 
                                    class="file-table-icon file-table-thumbnail"
                                    @click.stop="handleIconOrNameClick(row)">
                                    <img
                                        :src="row.thumbnailUrl || row.thumbnail"
                                        :alt="getDisplayFileName(row)"
                                        class="file-table-thumbnail-image"
                                        @error="handleThumbnailError" />
                                </div>
                                <!-- 其他文件类型显示图标 -->
                                <div 
                                    v-else 
                                    class="file-table-icon" 
                                    :style="{ backgroundColor: getFileTypeConfig(row).color + '15' }"
                                    @click.stop="handleIconOrNameClick(row)">
                                    <el-icon :size="24" :color="getFileTypeConfig(row).color">
                                        <component :is="getFileTypeConfig(row).icon" />
                                    </el-icon>
                                </div>
                                <span 
                                    class="file-table-name" 
                                    :title="getDisplayFileName(row)"
                                    @click.stop="handleIconOrNameClick(row)">
                                    {{ getDisplayFileName(row) }}
                                </span>
                                <!-- 操作图标（hover 时显示，移动端选中时也显示） -->
                                <div v-if="row.type !== 'folder'" class="file-table-actions-inline" :class="{ 'is-visible': isRowHovered(row) || (isMobile && isFileSelected(row)) }">
                                    <div 
                                        class="file-action-icon file-action-share"
                                        @click.stop.prevent="handleShareClick(row, $event)"
                                        title="分享">
                                        <el-icon :size="18"><Share /></el-icon>
                                    </div>
                                    <div 
                                        class="file-action-icon file-action-download"
                                        @click.stop.prevent="handleDownloadClick(row, $event)"
                                        title="下载">
                                        <el-icon :size="18"><Download /></el-icon>
                                    </div>
                                </div>
                            </div>
                        </template>
                    </el-table-column>
                    
                    <!-- 大小列 -->
                    <el-table-column prop="size" label="大小" width="120" align="left">
                        <template #default="{ row }">
                            <span v-if="row.isNewFolder">-</span>
                            <span v-else>{{ row.type === 'folder' ? '-' : formatFileSize(row.file_size || row.size) }}</span>
                        </template>
                    </el-table-column>
                    
                    <!-- 类型列 -->
                    <el-table-column label="类型" width="120" align="left">
                        <template #default="{ row }">
                            <span v-if="row.isNewFolder"></span>
                            <span v-else>{{ row.type === 'folder' ? '文件夹' : getFileTypeConfig(row).label }}</span>
                        </template>
                    </el-table-column>
                    
                    <!-- 修改时间列 -->
                    <el-table-column label="上链时间" width="180" align="left">
                        <template #default="{ row }">
                            <span v-if="row.isNewFolder">{{ formatDate(Date.now()) }}</span>
                            <span v-else>{{ row.timestamp ? formatDate(row.timestamp) : '-' }}</span>
                        </template>
                    </el-table-column>
                    
                </el-table>
                
                <!-- 图片分类：时间分组网格布局（无论视图模式如何，图片分类都使用分组布局） -->
                <div v-else-if="selectedFileType === 'image'" class="file-list-image-grouped">
                    <div v-for="group in filesGroupedByDate" :key="group.date" class="image-date-group">
                        <div class="image-date-header">
                            <!-- 单选模式：移除分组选择checkbox -->
                            <span class="image-date-title">{{ group.date }}</span>
                        </div>
                        <div class="image-date-grid">
                            <div
                                v-for="(file, index) in group.files"
                                :key="file.id || index"
                                class="image-card-wrapper"
                                @mouseenter="hoveredImageCard = file.id || index"
                                @mouseleave="hoveredImageCard = null">
                                <div 
                                    class="image-card"
                                    :class="{ 'is-selected': isFileSelected(file), 'is-hovered': hoveredImageCard === (file.id || index) }"
                                    @click="handleImageCardClick(file, $event)">
                                    <div 
                                        class="image-card-checkbox" 
                                        v-if="hoveredImageCard === (file.id || index) || isFileSelected(file)"
                                        @click.stop="toggleFileSelection(file, $event)">
                                        <el-checkbox 
                                            :model-value="isFileSelected(file)"
                                            @click.stop.prevent="toggleFileSelection(file, $event)" />
                                    </div>
                                    <img
                                        v-if="file.thumbnailUrl || file.thumbnail"
                                        :src="file.thumbnailUrl || file.thumbnail"
                                        :alt="getDisplayFileName(file)"
                                        class="image-card-thumbnail"
                                        @error="handleThumbnailError" />
                                    <div v-else class="image-card-placeholder">
                                        <el-icon :size="48" color="#9ca3af"><Picture /></el-icon>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                
                <!-- 网格视图或其他视图 -->
                <div v-else :class="['file-list', viewMode === 'list' ? 'file-list-list' : 'file-list-grid']">
                    <FileCard
                        v-for="(file, index) in displayedFiles"
                        :key="file.id || index"
                        :file="file"
                        :view-mode="viewMode"
                        :is-selected="isFileSelected(file)"
                        @click="handleFileClick"
                        @download="handleFileDownload"
                        @preview="handleFilePreview"
                        @delete="handleFileDelete"
                        @select="toggleFileSelection" />
                </div>

                <!-- 加载更多触发器（仅在hasMore为true且selectedFileType为'all'时显示，用于Intersection Observer） -->
                <!-- 分类视图（如文档、图片等）的文件是一次性加载的，不需要分页加载 -->
                <div v-if="!loading && tableData.length > 0 && hasMore && selectedFileType === 'all'" ref="loadMoreTrigger" class="load-more-trigger">
                    <div v-if="isLoadingMore" class="load-more-loading">
                        <el-icon class="is-loading"><Loading /></el-icon>
                        <span>正在加载更多...</span>
                    </div>
                    <div v-else class="load-more-trigger-hint">
                        <el-icon class="hint-loading-icon"><Loading /></el-icon>
                        <span>滚动加载更多</span>
                    </div>
                </div>
                
                <!-- 加载中的骨架屏占位符（在加载时显示，保持滚动位置稳定） -->
                <div v-if="isLoadingMore && selectedFileType === 'all'" class="load-more-skeleton">
                    <div v-for="n in 5" :key="n" class="skeleton-item">
                        <div class="skeleton-checkbox"></div>
                        <div class="skeleton-icon"></div>
                        <div class="skeleton-content">
                            <div class="skeleton-line skeleton-line-title"></div>
                            <div class="skeleton-line skeleton-line-meta"></div>
                        </div>
                    </div>
                </div>

                <!-- 没有更多了提示（仅在hasMore为false或selectedFileType不为'all'时显示） -->
                <div v-if="!loading && tableData.length > 0 && (!hasMore || selectedFileType !== 'all')" class="load-more-end mt-3">
                    <span v-if="selectedFileType !== 'all'">已显示全部{{ getCategoryName(selectedFileType) }}</span>
                    <span v-else>没有更多了</span>
                </div>
                
                <!-- 图片预览对话框（降级方案，使用 el-image） -->
                <el-dialog
                    v-model="showImagePreview"
                    :title="previewImageTitle"
                    width="80%"
                    align-center
                    class="image-preview-dialog">
                    <el-image
                        :src="previewImageUrl"
                        fit="contain"
                        style="width: 100%; max-height: 70vh;"
                        :preview-src-list="[previewImageUrl]"
                        :initial-index="0"
                        preview-teleported />
                </el-dialog>
                
                <!-- ant-design Image 预览组件 -->
                <!-- 注意：ant-design 的 Image 预览需要组件在 DOM 中可见才能工作 -->
                <!-- 使用 v-show 而不是 v-if，确保组件始终在 DOM 中 -->
                <div v-show="previewImageList.length > 0" style="position: absolute; left: -9999px; width: 200px; height: 200px; overflow: hidden; visibility: hidden;">
                    <a-image-preview-group
                        ref="imagePreviewGroupRef"
                        :preview="{ 
                            visible: previewVisible, 
                            onVisibleChange: (vis) => { 
                                console.log('Preview visibility changed:', vis);
                                previewVisible = vis; 
                            },
                            current: previewCurrent
                        }">
                        <a-image
                            v-for="(url, index) in previewImageList"
                            :key="'img-' + index"
                            :src="url"
                            :preview="true"
                            style="width: 100px; height: 100px; display: inline-block; margin: 5px;"
                            @error="(e) => console.error('Image load error for URL:', url, e)"
                            @load="() => console.log('Image loaded successfully:', url)" />
                    </a-image-preview-group>
                </div>
                
                <!-- 视频播放对话框 -->
                <el-dialog
                    v-model="showVideoPreview"
                    :title="previewVideoTitle"
                    width="80%"
                    align-center
                    class="video-preview-dialog">
                    <div v-if="isVideoLoading" class="video-loading-container">
                        <el-icon class="is-loading" :size="48"><Loading /></el-icon>
                        <p class="loading-text">加载中...</p>
                    </div>
                    <video
                        ref="videoPlayerRef"
                        :src="previewVideoUrl"
                        class="video-js vjs-default-skin"
                        controls
                        preload="auto"
                        style="width: 100%; max-height: 70vh;">
                    </video>
                </el-dialog>
            </div>
        `,
        setup(props, { emit }) {
            const { filterFilesByType, getFileType, getFileTypeConfig } = window.useFileTypes();
            const { sortFiles } = window.useFileSort();
            const { formatFileSize, formatDate } = window.useFileUtils();
            
            const localFolderName = ref(props.folderName);
            const folderNameInputRef = ref(null);
            const loadMoreTrigger = ref(null);
            let observer = null;
            const lastDataLength = ref(0); // 记录加载前的数据长度
            const firstNewDataRowRef = ref(null); // 新数据的第一行引用
            
            // 移动端检测
            const isMobile = ref(false);
            const checkMobile = () => {
                isMobile.value = window.innerWidth < 500;
            };
            
            // 表格行 hover 状态
            const hoveredRowId = ref(null);
            
            // 分享弹窗相关
            const showShareModal = ref(false);
            const shareModalFile = ref(null);
            const shareModalActiveTab = ref('link');
            
            // 检查 ShareModal 组件是否可用
            const isShareModalAvailable = computed(() => {
                const available = typeof window !== 'undefined' && typeof window.ShareModal !== 'undefined';
                console.log('isShareModalAvailable:', available, typeof window, typeof window?.ShareModal);
                return available;
            });
            
            // 获取 ShareModal 组件引用
            const ShareModalComponent = computed(() => {
                if (typeof window !== 'undefined' && window.ShareModal) {
                    return window.ShareModal;
                }
                return null;
            });
            
            // 选中文件相关
            const selectedFiles = ref(new Set());
            
            // 预览相关
            const showImagePreview = ref(false);
            const showVideoPreview = ref(false);
            const previewImageUrl = ref('');
            const previewVideoUrl = ref('');
            const previewImageTitle = ref('');
            const previewVideoTitle = ref('');
            const isVideoLoading = ref(false);
            const videoPlayerRef = ref(null);
            let videoPlayer = null;

            // 监听 folderName prop 变化
            watch(() => props.folderName, (newVal) => {
                localFolderName.value = newVal;
            });
            
            // 筛选和排序后的文件列表
            const displayedFiles = computed(() => {
                let files = [...props.files];

                // 按类型筛选
                if (props.selectedFileType !== 'all') {
                    
                    files = filterFilesByType(files, props.selectedFileType);
                }

                // 排序
                files = sortFiles(files, props.sortBy);

                // 为每个文件添加_shouldShowThumbnail属性，确保响应式更新
                files = files.map(file => {
                    // 检查是否有缩略图URL
                    const hasThumbnail = !!(file.thumbnailUrl || file.thumbnail);

                    // 检查文件类型是否为image或video
                    let isImageOrVideo = false;
                    if (hasThumbnail) {
                        // 方法1: 通过file_type字段判断
                        if (file.file_type) {
                            const fileType = file.file_type.toLowerCase();
                            isImageOrVideo = fileType === 'image' || fileType === 'video';
                        }
                        // 方法2: 通过content_type字段判断
                        if (!isImageOrVideo && file.content_type) {
                            const contentType = file.content_type.toLowerCase();
                            isImageOrVideo = contentType.includes('image/') || contentType.includes('video/');
                        }
                        // 方法3: 通过文件扩展名判断
                        if (!isImageOrVideo) {
                            const ext = (file.file_extension || file.fileExtension || '').toLowerCase().replace('.', '');
                            if (ext) {
                                const imageExts = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg'];
                                const videoExts = ['mp4', 'avi', 'mov', 'wmv', 'flv', 'mkv', 'webm'];
                                isImageOrVideo = imageExts.includes(ext) || videoExts.includes(ext);
                            }
                        }
                    }

                    // 返回带有_shouldShowThumbnail属性的文件对象
                    return {
                        ...file,
                        _shouldShowThumbnail: hasThumbnail && isImageOrVideo
                    };
                });

                return files;
            });
            
            // 表格数据（包含新建文件夹行）
            const tableData = computed(() => {
                // displayedFiles已经包含_shouldShowThumbnail属性
                let data = [...displayedFiles.value];
                
                // 如果显示新建文件夹输入框，将其添加到数据开头（列表视图时）
                if (props.showNewFolderInput && props.viewMode === 'list' && (props.currentPath === '全部文件' || props.selectedFileType !== 'image')) {
                    data.unshift({
                        isNewFolder: true,
                        id: '__new_folder__',
                        name: '',
                        type: 'folder',
                        size: '-',
                        timestamp: Date.now(),
                        _shouldShowThumbnail: false
                    });
                }

                return data;
            });
            
            // 按月份分组的文件列表（用于图片分类）
            const filesGroupedByDate = computed(() => {
                if (props.selectedFileType !== 'image') {
                    return [];
                }
                
                const groups = {};
                const files = displayedFiles.value;
                
                files.forEach(file => {
                    if (!file.timestamp) return;
                    
                    // 处理时间戳格式
                    let timestamp = file.timestamp;
                    const timestampStr = String(timestamp);
                    if (timestampStr.length === 10) {
                        timestamp = timestamp * 1000;
                    }
                    
                    const date = new Date(timestamp);
                    const year = date.getFullYear();
                    const month = String(date.getMonth() + 1).padStart(2, '0');
                    const monthKey = `${year}年${month}月`;
                    
                    if (!groups[monthKey]) {
                        groups[monthKey] = [];
                    }
                    groups[monthKey].push(file);
                });
                
                // 按月份倒序排列
                return Object.keys(groups)
                    .sort((a, b) => {
                        const dateA = new Date(a.replace(/年|月/g, '/') + '/01');
                        const dateB = new Date(b.replace(/年|月/g, '/') + '/01');
                        return dateB - dateA;
                    })
                    .map(monthKey => ({
                        date: monthKey,
                        files: groups[monthKey]
                    }));
            });
            
            // 选中文件数量
            const selectedCount = computed(() => selectedFiles.value.size);
            
            // 检查文件是否被选中
            const isFileSelected = (file) => {
                const fileId = file.id || file.pin_id || file.pinId || file.file_id || file._id || file.pinid || file.file_name || file.name;
                return selectedFiles.value.has(fileId);
            };
            
            // 切换文件选中状态（单选模式：如果选中新文件，先清除之前的选中）
            const toggleFileSelection = (file, event) => {
                if (event) {
                    event.stopPropagation();
                }
                const fileId = file.id || file.pin_id || file.pinId || file.file_id || file._id || file.pinid || file.file_name || file.name;
                
                // 单选模式：如果点击的文件已选中，则取消选中；如果未选中，先清除所有选中，再选中当前文件
                if (selectedFiles.value.has(fileId)) {
                    selectedFiles.value.delete(fileId);
                    emit('file-unselect', file);
                } else {
                    // 单选模式：先清除所有选中
                    const previousSelected = Array.from(selectedFiles.value);
                    selectedFiles.value.clear();
                    previousSelected.forEach(id => {
                        emit('file-unselect', { id });
                    });
                    // 选中当前文件
                    selectedFiles.value.add(fileId);
                    emit('file-select', file);
                }
                emit('selection-change', Array.from(selectedFiles.value));
            };
            
            // 清除所有选中
            const clearSelection = () => {
                selectedFiles.value.clear();
                emit('selection-change', []);
            };
            
            // 处理表格 checkbox 变化（单选模式）
            const handleTableCheckboxChange = (file, checked) => {
                const fileId = file.id || file.pin_id || file.pinId || file.file_id || file._id || file.pinid || file.file_name || file.name;
                
                if (checked) {
                    // 单选模式：先清除所有选中
                    const previousSelected = Array.from(selectedFiles.value);
                    selectedFiles.value.clear();
                    previousSelected.forEach(id => {
                        emit('file-unselect', { id });
                    });
                    // 选中当前文件
                    selectedFiles.value.add(fileId);
                    emit('file-select', file);
                } else {
                    // 取消选中
                    selectedFiles.value.delete(fileId);
                    emit('file-unselect', file);
                }
                emit('selection-change', Array.from(selectedFiles.value));
            };
            
            // 切换分组选中状态
            const toggleGroupSelection = (files, checked) => {
                files.forEach(file => {
                    const fileId = file.id || file.pinid || file.file_name || file.name;
                    if (checked) {
                        selectedFiles.value.add(fileId);
                        emit('file-select', file);
                    } else {
                        selectedFiles.value.delete(fileId);
                        emit('file-unselect', file);
                    }
                });
                emit('selection-change', Array.from(selectedFiles.value));
            };
            
            // 当切换分类时清除选中
            watch(() => props.selectedFileType, () => {
                clearSelection();
            });
            
            // 监听清除选择触发器
            watch(() => props.clearSelectionTrigger, () => {
                if (props.clearSelectionTrigger > 0) {
                    clearSelection();
                }
            });
            
            // hoveredImageCard 用于跟踪鼠标悬停的图片卡片
            const hoveredImageCard = ref(null);

            // 设置 Intersection Observer
            const setupIntersectionObserver = async () => {
                // 等待 DOM 更新
                await nextTick();
                
                // 如果触发器元素不存在，则返回
                if (!loadMoreTrigger.value) {
                    console.log("设置 Intersection Observer 失败: loadMoreTrigger 元素不存在");
                    return;
                }
                
                // 如果已经设置了 observer，先清理
                if (observer) {
                    console.log("清理旧的 Intersection Observer");
                    cleanupObserver();
                }
                
                console.log("设置 Intersection Observer, hasMore:", props.hasMore, "trigger element:", loadMoreTrigger.value);
                observer = new IntersectionObserver((entries) => {
                    entries.forEach(entry => {
                        console.log("Intersection Observer 触发:", {
                            isIntersecting: entry.isIntersecting,
                            hasMore: props.hasMore,
                            isLoadingMore: props.isLoadingMore,
                            intersectionRatio: entry.intersectionRatio
                        });
                        
                        // 当触发器进入视口且还有更多数据且当前没有在加载时，触发加载
                        if (entry.isIntersecting && props.hasMore && !props.isLoadingMore) {
                            // 保存加载前的数据长度
                            lastDataLength.value = tableData.value.length;
                            
                            console.log("触发加载更多事件，当前数据长度:", lastDataLength.value);
                            emit('load-more');
                        }
                    });
                }, {
                    root: null, // 相对于视口
                    rootMargin: '0px 0px 200px 0px', // 在底部提前500px触发，提高触发敏感度
                    threshold: 0.01 // 1%可见时触发，降低阈值提高敏感度
                });

                observer.observe(loadMoreTrigger.value);
                console.log("Intersection Observer 已设置并开始观察");
            };

            // 清理 Intersection Observer
            const cleanupObserver = () => {
                if (observer) {
                    if (loadMoreTrigger.value) {
                        observer.unobserve(loadMoreTrigger.value);
                    }
                    observer.disconnect();
                    observer = null;
                }
            };
            
            // 获取分类名称
            const getCategoryName = (category) => {
                const names = {
                    'all': '全部文件',
                    'recent': '最近',
                    'starred': '收藏',
                    'shared': '分享',
                    'trash': '回收站',
                    'image': '图片',
                    'video': '视频',
                    'audio': '音频',
                    'document': '文档',
                    'spreadsheet': '表格',
                    'presentation': '演示文稿',
                    'archive': '压缩包',
                    'code': '代码'
                };
                return names[category] || category;
            };
            
            // 统一的检查和设置 Observer 函数
            const checkAndSetupObserver = async () => {
                const hasMore = props.hasMore;
                const loading = props.loading;
                const dataLength = tableData.value.length;
                const selectedFileType = props.selectedFileType;
                
                console.log('FileList: checkAndSetupObserver', { 
                    hasMore, 
                    loading, 
                    dataLength,
                    selectedFileType,
                    loadMoreTriggerExists: !!loadMoreTrigger.value,
                    observerExists: !!observer
                });
                
                // 如果条件满足（有数据、不在加载中、还有更多数据、且是全部文件视图），设置 Observer
                // 分类视图（如文档、图片等）的文件是一次性加载的，不需要分页加载，所以不设置 Observer
                if (!loading && dataLength > 0 && hasMore && selectedFileType === 'all') {
                    console.log('条件满足，准备设置 Observer');
                    await setupIntersectionObserver();
                } else {
                    // 条件不满足时清理 Observer
                    console.log('条件不满足，清理 Observer', { loading, dataLength, hasMore, selectedFileType });
                    cleanupObserver();
                }
            };

            // 监听 isLoadingMore 的变化，加载完成后滚动到新数据的第一条
            watch(
                () => props.isLoadingMore,
                async (isLoading, wasLoading) => {
                    // 从加载中变为加载完成
                    if (wasLoading && !isLoading) {
                        console.log('加载完成，开始处理新数据');
                        
                        // 先清理 Observer，避免在滚动过程中触发
                        cleanupObserver();
                        
                        // 等待 DOM 更新，确保数据已渲染
                        await nextTick();
                        // 额外等待一下，确保表格行已完全渲染
                        await new Promise(resolve => setTimeout(resolve, 100));
                        
                        // 检查是否有新数据加载
                        const currentLength = tableData.value.length;
                        if (currentLength > lastDataLength.value && lastDataLength.value > 0) {
                            console.log('新数据已加载，准备滚动到新数据的第一条', {
                                lastLength: lastDataLength.value,
                                currentLength: currentLength
                            });
                            
                            // 查找新数据的第一行（表格视图）
                            const tableRows = document.querySelectorAll('.file-list-table .el-table__body tr');
                            if (tableRows.length > lastDataLength.value) {
                                // 找到新数据的第一行（索引为 lastDataLength.value）
                                const firstNewRow = tableRows[lastDataLength.value];
                                if (firstNewRow) {
                                    // 滚动到新数据的第一行，使用 instant 确保立即滚动
                                    firstNewRow.scrollIntoView({ 
                                        behavior: 'auto', // 改为 auto 确保立即滚动，不等待动画
                                        block: 'start',
                                        inline: 'nearest'
                                    });
                                    console.log('已滚动到新数据的第一条');
                                    
                                    // 立即检查 loadMoreTrigger 位置并重新设置 Observer
                                    await nextTick();
                                    
                                    // 检查 loadMoreTrigger 是否在视口内
                                    if (loadMoreTrigger.value) {
                                        const rect = loadMoreTrigger.value.getBoundingClientRect();
                                        const isInViewport = rect.top < window.innerHeight && rect.bottom > 0;
                                        
                                        console.log('滚动完成，检查 loadMoreTrigger 位置:', {
                                            top: rect.top,
                                            bottom: rect.bottom,
                                            windowHeight: window.innerHeight,
                                            isInViewport: isInViewport
                                        });
                                        
                                        // 只有当 loadMoreTrigger 不在视口内时，才重新设置 Observer
                                        // 这样可以避免立即触发下一次加载
                                        if (!isInViewport && props.hasMore && props.selectedFileType === 'all') {
                                            console.log('loadMoreTrigger 不在视口内，重新设置 Observer');
                                            setTimeout(() => {
                                                checkAndSetupObserver();
                                            }, 200);
                                        } else {
                                            console.log('loadMoreTrigger 仍在视口内，延迟设置 Observer 避免立即触发');
                                            // 延迟设置，确保用户有足够时间看到新数据
                                            setTimeout(() => {
                                                checkAndSetupObserver();
                                            }, 800);
                                        }
                                    } else {
                                        // loadMoreTrigger 不存在，延迟设置 Observer
                                        if (props.hasMore && props.selectedFileType === 'all') {
                                            setTimeout(() => {
                                                checkAndSetupObserver();
                                            }, 200);
                                        }
                                    }
                                } else {
                                    console.warn('未找到新数据的第一行');
                                    // 即使找不到行，也重新设置 Observer
                                    if (props.hasMore && props.selectedFileType === 'all') {
                                        setTimeout(() => {
                                            checkAndSetupObserver();
                                        }, 200);
                                    }
                                }
                            } else {
                                console.warn('表格行数量未增加');
                                // 即使行数未增加，也重新设置 Observer
                                if (props.hasMore && props.selectedFileType === 'all') {
                                    setTimeout(() => {
                                        checkAndSetupObserver();
                                    }, 200);
                                }
                            }
                            
                            // 重置记录
                            lastDataLength.value = 0;
                        } else {
                            console.log('没有新数据加载');
                            // 没有新数据，直接重新设置 Observer
                            if (props.hasMore && props.selectedFileType === 'all') {
                                setTimeout(() => {
                                    checkAndSetupObserver();
                                }, 200);
                            }
                        }
                    }
                }
            );
            
            // 简化 Observer 设置逻辑，只在必要时设置
            // 监听 selectedFileType 变化，当切换到分类视图时清理 Observer
            watch(
                () => props.selectedFileType,
                (newSelectedFileType) => {
                    console.log('FileList: props.selectedFileType changed to:', newSelectedFileType);
                    // 当切换到分类视图时，清理 Observer，因为分类视图不需要分页加载
                    if (newSelectedFileType !== 'all') {
                        cleanupObserver();
                    } else {
                        // 切换到全部文件视图时，延迟设置 Observer，避免立即触发
                        Vue.nextTick(() => {
                            setTimeout(() => {
                                checkAndSetupObserver();
                            }, 300);
                        });
                    }
                },
                { immediate: false }
            );
            
            // 监听 tableData 变化，确保数据更新后立即处理
            watch(
                () => tableData.value.length,
                async (newLength, oldLength) => {
                    // 如果数据长度增加且不在加载中，说明数据已更新
                    if (newLength > oldLength && !props.isLoadingMore && props.selectedFileType === 'all') {
                        console.log('检测到数据更新，tableData 长度从', oldLength, '增加到', newLength, 'lastDataLength:', lastDataLength.value);
                        
                        // 先清理 Observer，避免在滚动过程中触发
                        cleanupObserver();
                        
                        // 如果之前记录了 lastDataLength，说明是加载更多触发的
                        if (lastDataLength.value > 0 && newLength > lastDataLength.value) {
                            // 多次尝试查找新数据的第一行，确保 DOM 已更新
                            let attempts = 0;
                            const maxAttempts = 15; // 增加尝试次数
                            const findAndScroll = () => {
                                attempts++;
                                
                                // 等待 DOM 更新
                                Vue.nextTick().then(() => {
                                    // 查找新数据的第一行（表格视图）
                                    const tableRows = document.querySelectorAll('.file-list-table .el-table__body tr');
                                    console.log(`尝试 ${attempts}/${maxAttempts}: 查找表格行，当前行数:`, tableRows.length, '期望行数:', lastDataLength.value, 'tableData长度:', newLength);
                                    
                                    if (tableRows.length > lastDataLength.value) {
                                        // 找到新数据的第一行（索引为 lastDataLength.value）
                                        const firstNewRow = tableRows[lastDataLength.value];
                                        if (firstNewRow) {
                                            // 立即滚动到新数据的第一行
                                            firstNewRow.scrollIntoView({ 
                                                behavior: 'auto',
                                                block: 'start',
                                                inline: 'nearest'
                                            });
                                            console.log('数据更新后立即滚动到新数据的第一条，行索引:', lastDataLength.value);
                                            
                                            // 等待滚动完成后再检查并重新设置 Observer
                                            setTimeout(() => {
                                                // 检查 loadMoreTrigger 是否在视口内
                                                if (loadMoreTrigger.value) {
                                                    const rect = loadMoreTrigger.value.getBoundingClientRect();
                                                    const isInViewport = rect.top < window.innerHeight && rect.bottom > 0;
                                                    
                                                    console.log('滚动完成，检查 loadMoreTrigger 位置:', {
                                                        top: rect.top,
                                                        bottom: rect.bottom,
                                                        windowHeight: window.innerHeight,
                                                        isInViewport: isInViewport
                                                    });
                                                    
                                                    if (!isInViewport && props.hasMore && props.selectedFileType === 'all') {
                                                        setTimeout(() => {
                                                            checkAndSetupObserver();
                                                        }, 200);
                                                    } else {
                                                        setTimeout(() => {
                                                            checkAndSetupObserver();
                                                        }, 800);
                                                    }
                                                } else {
                                                    if (props.hasMore && props.selectedFileType === 'all') {
                                                        setTimeout(() => {
                                                            checkAndSetupObserver();
                                                        }, 200);
                                                    }
                                                }
                                            }, 100);
                                            
                                            // 重置记录
                                            lastDataLength.value = 0;
                                            return;
                                        }
                                    }
                                    
                                    // 如果还没找到，继续尝试
                                    if (attempts < maxAttempts) {
                                        setTimeout(findAndScroll, 150); // 增加等待时间
                                    } else {
                                        console.warn('多次尝试后仍未找到新数据的第一行，可能 DOM 未更新或数据未正确加载', {
                                            tableRowsLength: tableRows.length,
                                            lastDataLength: lastDataLength.value,
                                            tableDataLength: newLength
                                        });
                                        // 重置记录
                                        lastDataLength.value = 0;
                                        // 即使找不到，也重新设置 Observer
                                        if (props.hasMore && props.selectedFileType === 'all') {
                                            setTimeout(() => {
                                                checkAndSetupObserver();
                                            }, 200);
                                        }
                                    }
                                });
                            };
                            
                            // 开始查找和滚动
                            findAndScroll();
                        } else if (lastDataLength.value === 0) {
                            // 如果没有记录 lastDataLength，说明可能是其他原因导致的数据更新
                            // 直接重新设置 Observer
                            if (props.hasMore && props.selectedFileType === 'all') {
                                setTimeout(() => {
                                    checkAndSetupObserver();
                                }, 200);
                            }
                        }
                    }
                },
                { immediate: false }
            );
            
            // 只在加载完成后设置 Observer，避免频繁触发
            watch(
                () => [props.isLoadingMore, props.hasMore, props.selectedFileType],
                async ([isLoadingMore, hasMore, selectedFileType]) => {
                    // 只在加载完成且是全部文件视图时设置 Observer
                    if (!isLoadingMore && hasMore && selectedFileType === 'all') {
                        // 延迟设置，确保 DOM 已更新
                        await nextTick();
                        setTimeout(() => {
                            checkAndSetupObserver();
                        }, 200);
                    } else if (isLoadingMore || selectedFileType !== 'all') {
                        // 加载中或非全部文件视图时，清理 Observer
                        cleanupObserver();
                    }
                },
                { immediate: false }
            );

            // 组件挂载时尝试设置 Observer（作为兜底）
            onMounted(async () => {
                console.log('FileList: onMounted, checking conditions...', {
                    hasMore: props.hasMore,
                    loading: props.loading,
                    dataLength: tableData.value.length,
                    selectedFileType: props.selectedFileType,
                    loadMoreTriggerExists: !!loadMoreTrigger.value
                });
                // 等待 DOM 更新
                await nextTick();
                // 延迟设置，避免立即触发
                setTimeout(() => {
                    if (props.selectedFileType === 'all' && props.hasMore && !props.loading) {
                        checkAndSetupObserver();
                    }
                }, 500);
            });

            // 组件卸载时清理 Observer
            onUnmounted(() => {
                cleanupObserver();
            });
            
            // 当显示新建文件夹输入框时，自动聚焦
            watch(() => props.showNewFolderInput, async (newVal) => {
                if (newVal) {
                    await nextTick();
                    if (folderNameInputRef.value && folderNameInputRef.value.focus) {
                        folderNameInputRef.value.focus();
                    }
                }
            });
            
            // 确认创建文件夹
            const handleConfirmCreate = () => {
                emit('update:folder-name', localFolderName.value);
                emit('create-folder');
            };
            
            // 取消创建文件夹
            const handleCancelCreate = () => {
                localFolderName.value = '';
                emit('update:folder-name', '');
                emit('cancel-new-folder');
            };
            
            // 获取文件类型配置（用于表格显示）
            const getFileTypeConfigForTable = (file) => {
                if (file.type === 'folder') {
                    return { label: '文件夹', icon: 'Folder', color: '#F59E0B' };
                }

                // 兼容新旧数据结构
                const fileName = file.file_name || file.name || '';
                const mimeType = file.content_type || file.mimeType;

                // 如果有file_type字段，优先使用
                if (file.file_type) {
                    const type = file.file_type.toLowerCase();
                    const iconMap = {
                        'image': { label: '图片', icon: 'Picture', color: '#67C23A' },
                        'video': { label: '视频', icon: 'VideoPlay', color: '#409EFF' },
                        'audio': { label: '音频', icon: 'Headset', color: '#E6A23C' },
                        'document': { label: '文档', icon: 'Document', color: '#F56C6C' },
                        'spreadsheet': { label: '表格', icon: 'Grid', color: '#67C23A' },
                        'pdf': { label: 'PDF', icon: 'Document', color: '#F56C6C' },
                        'archive': { label: '压缩包', icon: 'Box', color: '#909399' },
                        'code': { label: '代码', icon: 'Document', color: '#606266' }
                    };
                    if (iconMap[type]) {
                        return iconMap[type];
                    }
                }

                const fileType = getFileType(fileName, mimeType);
                return getFileTypeConfig(fileType);
            };

            // 处理缩略图加载错误
            const handleThumbnailError = (event) => {
                // 缩略图加载失败时，隐藏图片，让它回退到图标显示
                const imgElement = event.target;
                const thumbnailDiv = imgElement.parentElement;
                if (thumbnailDiv) {
                    thumbnailDiv.style.display = 'none';
                }
            };

            // 处理表格行点击
            const handleRowClick = (row) => {
                // 如果是新建文件夹行，不触发文件点击
                if (row.isNewFolder) {
                    return;
                }
                emit('file-click', row);
            };
            
            // 处理文件点击
            const handleFileClick = (file) => {
                emit('file-click', file);
            };
            
            // 处理文件下载
            const handleFileDownload = (file) => {
                emit('file-download', file);
            };
            
            // 处理文件预览
            const handleFilePreview = (file) => {
                emit('file-preview', file);
            };
            
            // 处理文件删除
            const handleFileDelete = (file) => {
                emit('file-delete', file);
            };
            
            // 获取显示的文件名（如果文件名为空，显示"未知名称" + 扩展名）
            const getDisplayFileName = (file) => {
                const fileName = file.file_name || file.name || '';
                const fileExtension = file.file_extension || file.fileExtension || '';
                
                // 如果文件名为空或null，使用"未知名称" + 扩展名
                if (!fileName || fileName.trim() === '') {
                    if (fileExtension) {
                        // 如果扩展名没有点号，添加点号
                        const ext = fileExtension.startsWith('.') ? fileExtension : '.' + fileExtension;
                        return '未知名称' + ext;
                    }
                    return '未知名称';
                }
                
                return fileName;
            };
            
            // 判断是否为图片类型
            const isImageType = (file) => {
                if (file.type === 'folder') return false;
                
                const fileType = getFileType(file.file_type || file.name, file.content_type || file.mimeType);
                
                return fileType === 'image';
            };
            
            // 判断是否为视频类型
            const isVideoType = (file) => {
                if (file.type === 'folder') return false;
                const fileType = getFileType(file.file_name || file.name, file.content_type || file.mimeType);
                return fileType === 'video';
            };
            
            // 获取所有图片文件的 URL 数组（用于 ant-design Image 预览）
            const getAllImageUrls = () => {
                const imageFiles = displayedFiles.value.filter(file => {
                    if (file.type === 'folder' || file.isNewFolder) return false;
                    return isImageType(file);
                });
                
                return imageFiles.map(file => {
                    const originalUrl = file.originalUrl || file.original_url || file.url;
                    return originalUrl || null;
                }).filter(url => url !== null);
            };
            
            // ant-design Image 预览相关
            const previewImageList = ref([]);
            const previewVisible = ref(false);
            const previewCurrent = ref(0);
            const imagePreviewGroupRef = ref(null);
            
            // 处理图片卡片点击（图片分类视图）
            const handleImageCardClick = (file, event) => {
                // 如果点击的是复选框，不处理
                if (event.target.closest('.image-card-checkbox')) {
                    return;
                }
                
                // 如果当前是选择模式，切换选择状态
                if (selectedCount.value > 0 || isFileSelected(file)) {
                    toggleFileSelection(file, event);
                } else {
                    // 否则预览图片
                    handleIconOrNameClick(file);
                }
            };
            
            // 获取基础 URL
            const getBaseUrl = () => {
                return `${window.location.protocol}//${window.location.host}${window.location.pathname}`;
            };
            
            // 处理图标或文件名点击
            const handleIconOrNameClick = async (row) => {
                // 如果是文件夹，不处理
                if (row.type === 'folder' || row.isNewFolder) {
                    return;
                }
                
                const originalUrl = row.originalUrl || row.original_url || row.url;
                if (!originalUrl) {
                    console.warn('文件没有原始URL:', row);
                    return;
                }
                
                const fileName = getDisplayFileName(row);
                
                // 判断文件类型
                if (isImageType(row)) {
                    // 图片：使用 ant-design Image 预览
                    try {
                        // 获取所有图片 URL
                        const allImageUrls = getAllImageUrls();
                        
                        // 找到当前图片的索引
                        const currentIndex = allImageUrls.findIndex(url => {
                            const fileUrl = row.originalUrl || row.original_url || row.url;
                            return url === fileUrl;
                        });
                        
                        // 设置预览图片列表和当前索引
                        if (allImageUrls.length > 0) {
                            console.log('Setting preview - URLs:', allImageUrls.length, 'current index:', currentIndex);
                            console.log('Image URLs:', allImageUrls);
                            console.log('Current image URL:', row.originalUrl || row.original_url || row.url);
                            
                            // 先设置列表和索引（确保组件在 DOM 中）
                            previewImageList.value = allImageUrls;
                            previewCurrent.value = currentIndex >= 0 ? currentIndex : 0;
                            console.log('Preview current URL:', previewImageList.value[previewCurrent.value]);
                            
                            // 使用 nextTick 确保 DOM 更新
                            await nextTick();
                            console.log('After nextTick, previewImageList length:', previewImageList.value.length);
                            
                            // 检查 ant-design 组件是否存在
                            console.log('Checking ant-design availability...');
                            console.log('window.antd:', typeof window.antd, window.antd);
                            
                            // 检查 Vue 组件是否可用
                            const instance = getCurrentInstance ? getCurrentInstance() : null;
                            if (instance && instance.appContext) {
                                console.log('Vue app context available');
                                const globalProperties = instance.appContext.config.globalProperties;
                                console.log('Global properties:', Object.keys(globalProperties).filter(k => k.includes('Image') || k.includes('image')));
                            }
                            
                            // 再次等待，确保组件渲染完成
                            await nextTick();
                            
                            // 检查组件 ref 是否存在
                            console.log('imagePreviewGroupRef:', imagePreviewGroupRef.value);
                            
                            // 检查 ant-design Image 组件是否在 DOM 中
                            const imageElements = document.querySelectorAll('a-image, .ant-image');
                            console.log('Found a-image elements in DOM:', imageElements.length);
                            
                            // 检查预览组是否在 DOM 中
                            const previewGroupElements = document.querySelectorAll('a-image-preview-group, .ant-image-preview-group');
                            console.log('Found a-image-preview-group elements in DOM:', previewGroupElements.length);
                            
                            // 如果组件没有渲染，说明 ant-design 可能没有正确注册
                            if (previewGroupElements.length === 0 && imageElements.length === 0) {
                                console.warn('Ant-design Image components not found in DOM, component may not be registered');
                                console.warn('Using fallback to el-image');
                                previewImageUrl.value = originalUrl;
                                previewImageTitle.value = fileName;
                                showImagePreview.value = true;
                                return;
                            }
                            
                            console.log('Setting previewVisible to true');
                            previewVisible.value = true;
                            console.log('Preview visible state:', previewVisible.value);
                            
                            // 再次等待，让预览有时间渲染
                            await nextTick();
                            
                            // 尝试通过 ref 直接触发预览
                            if (imagePreviewGroupRef.value) {
                                console.log('imagePreviewGroupRef found, trying to access preview methods');
                                console.log('imagePreviewGroupRef.value:', Object.keys(imagePreviewGroupRef.value || {}));
                            }
                            
                            // 检查预览中的图片元素
                            setTimeout(() => {
                                console.log('Checking preview status after 200ms');
                                // 检查是否有预览相关的 DOM 元素出现
                                const previewElements = document.querySelectorAll('.ant-image-preview, .ant-image-preview-wrap, .ant-image-preview-mask');
                                console.log('Found preview elements:', previewElements.length);
                                
                                // 检查预览中的图片元素（更精确的选择器）
                                const previewImages = document.querySelectorAll('.ant-image-preview img, .ant-image-preview-image img, .ant-image-preview-wrap img');
                                console.log('Found preview images:', previewImages.length);
                                
                                // 检查预览图片容器
                                const previewImageContainer = document.querySelector('.ant-image-preview-image');
                                if (previewImageContainer) {
                                    console.log('Preview image container found');
                                    const containerImgs = previewImageContainer.querySelectorAll('img');
                                    console.log('Images in container:', containerImgs.length);
                                    containerImgs.forEach((img, idx) => {
                                        console.log(`Container image ${idx}:`, {
                                            src: img.src,
                                            currentSrc: img.currentSrc,
                                            complete: img.complete,
                                            naturalWidth: img.naturalWidth,
                                            naturalHeight: img.naturalHeight,
                                            style: window.getComputedStyle(img).display,
                                            opacity: window.getComputedStyle(img).opacity,
                                            visibility: window.getComputedStyle(img).visibility
                                        });
                                        
                                        // 如果图片没有加载或尺寸为0，尝试手动设置 src
                                        if (!img.complete || img.naturalWidth === 0) {
                                            console.warn('Image not loaded, trying to reload:', img.src);
                                            const currentSrc = img.src;
                                            img.src = '';
                                            setTimeout(() => {
                                                img.src = currentSrc;
                                                console.log('Reloaded image src:', img.src);
                                            }, 100);
                                        }
                                        
                                        // 检查图片 URL 是否可访问
                                        const testImg = new Image();
                                        testImg.onload = () => console.log('Test image loaded successfully:', img.src);
                                        testImg.onerror = () => console.error('Test image failed to load:', img.src);
                                        testImg.src = img.src;
                                    });
                                } else {
                                    console.warn('Preview image container not found');
                                }
                                
                                if (previewImages.length === 0) {
                                    console.warn('No preview images found in DOM');
                                    // 检查预览容器中是否有其他元素
                                    const previewContainer = document.querySelector('.ant-image-preview');
                                    if (previewContainer) {
                                        console.log('Preview container found, structure:', {
                                            children: previewContainer.children.length,
                                            innerHTML: previewContainer.innerHTML.substring(0, 300)
                                        });
                                    }
                                }
                                
                                if (previewElements.length === 0) {
                                    console.warn('Ant-design preview did not open, using fallback');
                                    previewVisible.value = false;
                                    previewImageUrl.value = originalUrl;
                                    previewImageTitle.value = fileName;
                                    showImagePreview.value = true;
                                }
                            }, 300);
                        } else {
                            // 如果没有图片，使用降级方案
                            previewImageUrl.value = originalUrl;
                            previewImageTitle.value = fileName;
                            showImagePreview.value = true;
                        }
                    } catch (error) {
                        console.error('Error opening image viewer:', error);
                        // 降级方案：使用 el-image 预览
                        previewImageUrl.value = originalUrl;
                        previewImageTitle.value = fileName;
                        showImagePreview.value = true;
                    }
                } else if (isVideoType(row)) {
                    // 视频：跳转到预览路由
                    const pinId = row.pin_id || row.pinId || row.id;
                    if (!pinId) {
                        showToast('文件ID不存在', 'error');
                        return;
                    }
                    
                    const baseUrl = getBaseUrl();
                    const previewUrl = `${baseUrl}#/pin/${pinId}`;
                    window.location.href = previewUrl;
                } else {
                    // 其他文件：创建 a 链接并跳转
                    const link = document.createElement('a');
                    link.href = originalUrl;
                    link.target = '_blank';
                    link.rel = 'noopener noreferrer';
                    document.body.appendChild(link);
                    link.click();
                    document.body.removeChild(link);
                }
            };
            
            // 初始化 video.js 播放器
            const initVideoPlayer = () => {
                if (!videoPlayerRef.value) {
                    console.error('Video player ref not found');
                    isVideoLoading.value = false;
                    return;
                }
                
                try {
                    // 检查 video.js 是否已加载
                    if (typeof window.videojs === 'undefined') {
                        console.error('video.js is not loaded');
                        isVideoLoading.value = false;
                        return;
                    }
                    
                    // 如果已有播放器实例，先销毁并清理
                    if (videoPlayer) {
                        try {
                            videoPlayer.dispose();
                        } catch (e) {
                            console.warn('Error disposing video player:', e);
                        }
                        videoPlayer = null;
                    }
                    
                    // 清理 video 元素，移除 video.js 添加的 class 和属性
                    const videoElement = videoPlayerRef.value;
                    if (videoElement) {
                        // 移除 video.js 添加的 class
                        videoElement.className = 'video-js vjs-default-skin';
                        // 移除 video.js 添加的属性
                        videoElement.removeAttribute('data-vjs-player');
                        // 重置 video 元素
                        videoElement.load();
                    }
                    
                    // 等待一下确保 DOM 更新
                    setTimeout(() => {
                        // 初始化 video.js
                        videoPlayer = window.videojs(videoElement, {
                            controls: true,
                            preload: 'auto',
                            fluid: true,
                            responsive: true
                        });
                        
                        // 监听加载完成
                        videoPlayer.ready(() => {
                            isVideoLoading.value = false;
                        });
                        
                        // 监听错误
                        videoPlayer.on('error', () => {
                            isVideoLoading.value = false;
                            console.error('Video player error');
                        });
                    }, 100);
                } catch (error) {
                    console.error('Failed to initialize video player:', error);
                    isVideoLoading.value = false;
                }
            };
            
            // 监听视频预览对话框关闭，清理播放器
            watch(() => showVideoPreview.value, (isOpen) => {
                if (!isOpen) {
                    // 清理播放器实例
                    if (videoPlayer) {
                        try {
                            videoPlayer.dispose();
                        } catch (e) {
                            console.warn('Error disposing video player on close:', e);
                        }
                        videoPlayer = null;
                    }
                    
                    // 清理 video 元素
                    if (videoPlayerRef.value) {
                        const videoElement = videoPlayerRef.value;
                        // 移除 video.js 添加的 class
                        videoElement.className = 'video-js vjs-default-skin';
                        // 移除 video.js 添加的属性
                        videoElement.removeAttribute('data-vjs-player');
                        // 清空 src
                        videoElement.src = '';
                        videoElement.srcObject = null;
                        // 重置 video 元素
                        videoElement.load();
                    }
                    
                    // 清空 URL 和标题
                    previewVideoUrl.value = '';
                    previewVideoTitle.value = '';
                    isVideoLoading.value = false;
                }
            });
            
            // 获取 showToast
            const showToast = (message, type = 'info') => {
                if (window.mobileActionEmitter) {
                    window.mobileActionEmitter.emit('toast', { message, type });
                } else {
                    console.log(`[${type}] ${message}`);
                }
            };
            
            // 处理行鼠标移入
            const handleRowMouseEnter = (row) => {
                if (!isMobile.value && !row.isNewFolder && row.type !== 'folder') {
                    // 尝试多种可能的 ID 字段
                    const rowId = row.id || row.pin_id || row.pinId || row.file_id || row._id;
                    hoveredRowId.value = rowId;
                }
            };
            
            // 处理行鼠标移出
            const handleRowMouseLeave = () => {
                hoveredRowId.value = null;
            };
            
            // 检查行是否被 hover
            const isRowHovered = (row) => {
                const rowId = row.id || row.pin_id || row.pinId || row.file_id || row._id;
                return hoveredRowId.value === rowId;
            };
            
            // 处理分享点击
            const handleShareClick = (file, event) => {
                if (event) {
                    event.preventDefault();
                    event.stopPropagation();
                }
                console.log('Share clicked:', file);
                console.log('ShareModal component available:', typeof window.ShareModal !== 'undefined');
                console.log('Before setting:', { showShareModal: showShareModal.value, shareModalFile: shareModalFile.value });
                
                shareModalFile.value = file;
                
                shareModalActiveTab.value = 'link';
                showShareModal.value = true;
                
                console.log('After setting:', { showShareModal: showShareModal.value, shareModalFile: shareModalFile.value });
                
                // 强制触发响应式更新
                nextTick(() => {
                    console.log('After nextTick:', { showShareModal: showShareModal.value, shareModalFile: shareModalFile.value });
                });
            };
            
            // 处理下载点击
            const handleDownloadClick = async (file, event) => {
                if (event) {
                    event.preventDefault();
                    event.stopPropagation();
                }
                try {
                    const pinId = file.pin_id || file.pinId || file.id;
                    if (!pinId) {
                        showToast('文件ID不存在', 'error');
                        return;
                    }
                    
                    // 获取 metafsApi（从 window 对象）
                    if (typeof window === 'undefined' || !window.metafsApi || typeof window.metafsApi.getOriginalImageUrl !== 'function') {
                        showToast('下载功能不可用，metafsApi 未定义', 'error');
                        return;
                    }
                    
                    const fileUrl = window.metafsApi.getOriginalImageUrl(pinId);
                    const fileName = getDisplayFileName(file);
                    
                    // 下载文件
                    const response = await fetch(fileUrl);
                    if (!response.ok) {
                        throw new Error('下载失败');
                    }
                    const blob = await response.blob();
                    const downloadUrl = window.URL.createObjectURL(blob);
                    const a = document.createElement('a');
                    a.href = downloadUrl;
                    a.download = fileName;
                    document.body.appendChild(a);
                    a.click();
                    document.body.removeChild(a);
                    window.URL.revokeObjectURL(downloadUrl);
                    
                    showToast('下载开始', 'success');
                } catch (error) {
                    console.error('Download error:', error);
                    showToast('下载失败: ' + (error.message || '未知错误'), 'error');
                }
            };
            
            onMounted(() => {
                checkMobile();
                window.addEventListener('resize', checkMobile);
            });
            
            onUnmounted(() => {
                window.removeEventListener('resize', checkMobile);
            });
            
            return {
                displayedFiles,
                tableData,
                filesGroupedByDate,
                selectedFiles,
                selectedCount,
                hoveredImageCard,
                isFileSelected,
                toggleFileSelection,
                toggleGroupSelection,
                clearSelection,
                getFileTypeConfig: getFileTypeConfigForTable,
                formatFileSize,
                formatDate,
                getCategoryName,
                handleThumbnailError,
                handleRowClick,
                handleFileClick,
                handleFileDownload,
                handleFilePreview,
                handleFileDelete,
                getDisplayFileName,
                handleIconOrNameClick,
                handleImageCardClick,
                showImagePreview,
                showVideoPreview,
                previewImageUrl,
                previewVideoUrl,
                previewImageTitle,
                previewVideoTitle,
                isVideoLoading,
                videoPlayerRef,
                previewImageList,
                previewVisible,
                previewCurrent,
                imagePreviewGroupRef,
                localFolderName,
                folderNameInputRef,
                loadMoreTrigger,
                isMobile,
                hoveredRowId,
                showShareModal,
                shareModalFile,
                shareModalActiveTab,
                isShareModalAvailable,
                ShareModalComponent,
                handleRowMouseEnter,
                handleRowMouseLeave,
                isRowHovered,
                handleShareClick,
                handleDownloadClick,
                handleConfirmCreate,
                handleCancelCreate,
                handleTableCheckboxChange
            };
        }
    };
})();

