<template>
  <div class="file-manager">
    <!-- 工具栏 -->
    <div class="toolbar">
      <div class="toolbar-left">
        <el-button-group>
          <el-button icon="ArrowLeft" :disabled="!canGoBack" @click="goBack" />
          <el-button icon="ArrowRight" :disabled="!canGoForward" @click="goForward" />
        </el-button-group>
        
        <el-button 
          icon="Top" 
          :disabled="currentFolderId === null || currentFolderId === 0"
          @click="goToParentFolder"
          style="margin-left: 8px;">
          上一级
        </el-button>
        
        <div class="path-bar">
          <el-breadcrumb separator="/">
            <el-breadcrumb-item @click="navigateToFolder(null)">
              <el-icon><HomeFilled /></el-icon>
            </el-breadcrumb-item>
            <el-breadcrumb-item 
              v-for="item in breadcrumbList" 
              :key="item.folderId" 
              @click="navigateToFolder(item)">
              {{ item.folderName }}
            </el-breadcrumb-item>
          </el-breadcrumb>
        </div>
        
        <el-input 
          v-model="searchKeyword" 
          placeholder="搜索" 
          prefix-icon="Search" 
          class="search-input" 
          clearable 
          @input="handleSearch" 
        />
      </div>
      
      <div class="toolbar-right">
        <el-checkbox 
          v-model="selectAll" 
          :indeterminate="isIndeterminate"
          @change="handleSelectAll"
          style="margin-right: 12px;">
          全选
        </el-checkbox>
        <span v-if="selectedItems.length > 0" class="selection-count">
          已选择 {{ selectedItems.length }} 项
        </span>
        
        <el-dropdown @command="handleNewCommand" trigger="click">
          <el-button type="primary">
            新建 <el-icon class="el-icon--right"><ArrowDown /></el-icon>
          </el-button>
          <template #dropdown>
            <el-dropdown-menu>
              <el-dropdown-item command="folder">
                <el-icon><FolderAdd /></el-icon> 文件夹
              </el-dropdown-item>
              <el-dropdown-item command="file">
                <el-icon><DocumentAdd /></el-icon> 文件
              </el-dropdown-item>
              <el-dropdown-item command="upload" divided>
                <el-icon><Upload /></el-icon> 上传文件
              </el-dropdown-item>
            </el-dropdown-menu>
          </template>
        </el-dropdown>
        
        <el-button type="success" icon="Upload" @click="handleUpload">上传</el-button>
        <el-button icon="Refresh" @click="handleRefresh">刷新</el-button>
        
        <el-button 
          v-if="selectedItems.length > 0" 
          type="danger" 
          icon="Delete" 
          @click="handleBatchDelete">
          删除
        </el-button>
        
        <el-button-group>
          <el-button :type="viewMode === 'grid' ? 'primary' : ''" icon="Menu" @click="viewMode = 'grid'" />
          <el-button :type="viewMode === 'list' ? 'primary' : ''" icon="List" @click="viewMode = 'list'" />
        </el-button-group>
      </div>
    </div>

    <!-- 文件列表区域 -->
    <div 
      v-loading="loading" 
      class="file-list-container"
      ref="fileListContainerRef"
      @mousedown="handleSelectionStart"
      @mousemove="handleSelectionMove"
      @mouseup="handleSelectionEnd"
      @mouseleave="handleSelectionEnd"
    >
      <!-- 框选矩形 -->
      <div 
        v-if="selectionBox.visible" 
        class="selection-box"
        :style="{
          left: selectionBox.left + 'px',
          top: selectionBox.top + 'px',
          width: selectionBox.width + 'px',
          height: selectionBox.height + 'px'
        }"
      ></div>
      
      <!-- 网格视图 -->
      <div v-if="viewMode === 'grid'" class="grid-view" ref="gridViewRef">
        <div
          v-for="folder in folderList"
          :key="'folder-' + folder.folderId"
          class="file-item folder-type"
          :class="{ selected: isSelected('folder', folder.folderId), 'drag-over': dragOverFolderId === folder.folderId }"
          :data-type="'folder'"
          :data-id="folder.folderId"
          draggable="true"
          @click.stop="handleItemClick('folder', folder)"
          @dblclick="navigateToFolder(folder)"
          @contextmenu.prevent="handleContextMenu($event, 'folder', folder)"
          @dragstart="handleDragStart($event, 'folder', folder)"
          @dragend="handleDragEnd"
          @dragover.prevent="handleDragOver($event, folder)"
          @dragleave="handleDragLeave"
          @drop.prevent="handleDrop($event, folder)"
        >
          <div class="file-icon icon-folder">
            <el-icon :size="32" color="#f9a825"><Folder /></el-icon>
          </div>
          <div class="file-name" :title="folder.folderName">{{ folder.folderName }}</div>
        </div>

        <div
          v-for="file in fileList"
          :key="'file-' + file.fileId"
          class="file-item file-type"
          :class="{ selected: isSelected('file', file.fileId) }"
          :data-type="'file'"
          :data-id="file.fileId"
          draggable="true"
          @click.stop="handleItemClick('file', file)"
          @dblclick="handleFilePreview(file)"
          @contextmenu.prevent="handleContextMenu($event, 'file', file)"
          @dragstart="handleDragStart($event, 'file', file)"
          @dragend="handleDragEnd"
        >
          <div class="file-icon" :class="getFileIconClass(file.fileName)">
            <el-icon :size="32" :color="getFileIconColor(file.fileName)"><Document /></el-icon>
          </div>
          <div class="file-name" :title="file.fileName">{{ file.fileName }}</div>
          <div class="file-size">{{ formatFileSize(file.fileSize) }}</div>
        </div>
      </div>

      <!-- 列表视图 -->
      <el-table v-else :data="[...folderList, ...fileList]" @selection-change="handleSelectionChange">
        <el-table-column type="selection" width="55" />
        <el-table-column label="名称" min-width="300">
          <template #default="scope">
            <div 
              class="name-cell" 
              @dblclick="scope.row.folderId ? navigateToFolder(scope.row) : handleFilePreview(scope.row)"
            >
              <el-icon v-if="scope.row.folderId" color="#409eff"><Folder /></el-icon>
              <el-icon v-else><Document /></el-icon>
              <span>{{ scope.row.folderName || scope.row.fileName }}</span>
            </div>
          </template>
        </el-table-column>
        <el-table-column label="大小" width="120">
          <template #default="scope">
            {{ scope.row.fileSize ? formatFileSize(scope.row.fileSize) : '-' }}
          </template>
        </el-table-column>
        <el-table-column label="修改时间" width="180">
          <template #default="scope">
            {{ parseTime(scope.row.createTime) }}
          </template>
        </el-table-column>
        <el-table-column label="操作" width="200" fixed="right">
          <template #default="scope">
            <el-button link type="primary" @click="handleRename(scope.row)">重命名</el-button>
            <el-button v-if="!scope.row.folderId" link type="primary" @click="handleDownloadFile(scope.row)">下载</el-button>
            <el-button link type="danger" @click="handleDeleteItem(scope.row)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>

      <el-empty v-if="!loading && folderList.length === 0 && fileList.length === 0" description="此文件夹为空">
        <el-button type="primary" @click="handleUpload">上传文件</el-button>
        <el-button @click="handleAddFolder">新建文件夹</el-button>
      </el-empty>
    </div>

    <!-- 新建文件夹对话框 -->
    <el-dialog :title="folderDialogTitle" v-model="folderDialogVisible" width="400px">
      <el-input v-model="folderName" placeholder="请输入文件夹名称" @keyup.enter="submitFolder" />
      <template #footer>
        <el-button @click="folderDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="submitFolder">确定</el-button>
      </template>
    </el-dialog>

    <!-- 上传对话框 -->
    <el-dialog title="上传文件" v-model="uploadDialogVisible" width="600px" :close-on-click-modal="false">
      <el-upload
        ref="uploadRef"
        :action="uploadUrl"
        :headers="uploadHeaders"
        :data="{ folderId: currentFolderId }"
        :on-success="handleUploadSuccess"
        :on-error="handleUploadError"
        :auto-upload="false"
        drag
        multiple
      >
        <el-icon class="el-icon--upload"><UploadFilled /></el-icon>
        <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
      </el-upload>
      <template #footer>
        <el-button @click="uploadDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="submitUpload">开始上传</el-button>
      </template>
    </el-dialog>

    <!-- 重命名对话框 -->
    <el-dialog :title="renameDialogTitle" v-model="renameDialogVisible" width="400px">
      <el-input v-model="renameName" placeholder="请输入名称" @keyup.enter="submitRename" />
      <template #footer>
        <el-button @click="renameDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="submitRename">确定</el-button>
      </template>
    </el-dialog>

    <!-- 文件预览对话框 -->
    <el-dialog 
      v-model="previewDialogVisible" 
      :title="previewFile?.fileName || '文件预览'" 
      width="80%" 
      :close-on-click-modal="true"
      destroy-on-close
    >
      <div class="preview-container">
        <!-- 图片预览 -->
        <div v-if="previewType === 'image'" class="preview-image">
          <el-image :src="previewUrl" fit="contain" style="max-height: 70vh;" />
        </div>
        <!-- 视频预览 -->
        <div v-else-if="previewType === 'video'" class="preview-video">
          <video :src="previewUrl" controls style="max-width: 100%; max-height: 70vh;" />
        </div>
        <!-- 音频预览 -->
        <div v-else-if="previewType === 'audio'" class="preview-audio">
          <audio :src="previewUrl" controls style="width: 100%;" />
        </div>
        <!-- PDF预览 -->
        <div v-else-if="previewType === 'pdf'" class="preview-pdf">
          <iframe :src="previewUrl" style="width: 100%; height: 70vh; border: none;" />
        </div>
        <!-- 文本预览 -->
        <div v-else-if="previewType === 'text'" class="preview-text">
          <pre style="max-height: 70vh; overflow: auto; background: #f5f7fa; padding: 16px; border-radius: 4px;">{{ previewContent }}</pre>
        </div>
        <!-- 不支持预览 -->
        <div v-else class="preview-unsupported">
          <el-empty description="该文件类型暂不支持预览">
            <el-button type="primary" @click="handleDownloadFile(previewFile)">下载文件</el-button>
          </el-empty>
        </div>
      </div>
    </el-dialog>

    <!-- 右键菜单 -->
    <div 
      v-show="contextMenuVisible" 
      class="context-menu"
      :style="{ left: contextMenuX + 'px', top: contextMenuY + 'px' }"
    >
      <div class="menu-item" @click="handleClipboardCopy">
        <el-icon><CopyDocument /></el-icon> 复制
      </div>
      <div class="menu-item" @click="handleClipboardCut">
        <el-icon><Scissor /></el-icon> 剪切
      </div>
      <div v-if="clipboard.length > 0" class="menu-item" @click="handleClipboardPaste">
        <el-icon><DocumentAdd /></el-icon> 粘贴 ({{ clipboard.length }})
      </div>
      <div class="menu-divider"></div>
      <div class="menu-item" @click="handleRename(contextMenuItem)">
        <el-icon><Edit /></el-icon> 重命名
      </div>
      <div v-if="contextMenuType === 'file'" class="menu-item" @click="handleDownloadFile(contextMenuItem)">
        <el-icon><Download /></el-icon> 下载
      </div>
      <div class="menu-item" @click="handleShare(contextMenuItem)">
        <el-icon><Share /></el-icon> 分享
      </div>
      <div class="menu-item" @click="handleCopy(contextMenuItem)">
        <el-icon><Folder /></el-icon> 复制到...
      </div>
      <div class="menu-item" @click="handleMove(contextMenuItem)">
        <el-icon><FolderRemove /></el-icon> 移动到...
      </div>
      <div class="menu-item danger" @click="handleDeleteItem(contextMenuItem)">
        <el-icon><Delete /></el-icon> 删除
      </div>
    </div>

    <!-- 移动/复制目标文件夹选择对话框 -->
    <el-dialog :title="folderSelectTitle" v-model="folderSelectDialogVisible" width="500px">
      <el-tree
        ref="folderTreeRef"
        :data="folderTree"
        :props="{ label: 'label', children: 'children' }"
        node-key="id"
        default-expand-all
        highlight-current
        @node-click="handleFolderTreeClick"
      >
        <template #default="{ node, data }">
          <span class="folder-tree-node">
            <el-icon color="#f9a825"><Folder /></el-icon>
            <span>{{ data.label }}</span>
          </span>
        </template>
      </el-tree>
      <template #footer>
        <el-button @click="folderSelectDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="submitFolderSelect" :disabled="!selectedTargetFolderId">确定</el-button>
      </template>
    </el-dialog>

    <!-- 分享对话框 -->
    <el-dialog 
      v-model="shareDialogVisible" 
      width="480px" 
      class="share-dialog" 
      align-center
      destroy-on-close
    >
      <template #header>
        <div class="dialog-header">
          <span class="dialog-title">文件分享</span>
        </div>
      </template>
      
      <!-- 已有分享 -->
      <div v-if="existingShare" class="share-content">
        <div class="share-status-icon success">
          <el-icon><Share /></el-icon>
        </div>
        <h3 class="share-status-title">此文件已分享</h3>
        
        <div class="share-info-card">
          <div class="info-item">
            <span class="label">分享链接</span>
            <div class="value-group">
              <el-input :model-value="existingShare.shareUrl" readonly size="large">
                <template #suffix>
                  <el-icon class="copy-icon" @click="copyExistingShareLink"><CopyDocument /></el-icon>
                </template>
              </el-input>
            </div>
          </div>
          
          <div class="info-row">
            <div class="info-item" v-if="existingShare.sharePassword">
              <span class="label">提取码</span>
              <div class="value-tag">{{ existingShare.sharePassword }}</div>
            </div>
            <div class="info-item">
              <span class="label">有效期至</span>
              <div class="value-text">{{ existingShare.expireTime ? proxy.parseTime(existingShare.expireTime) : '永久有效' }}</div>
            </div>
          </div>
        </div>
        
        <div class="share-actions">
          <el-button type="danger" plain icon="Delete" @click="handleCancelShare" class="full-width-btn">取消当前分享</el-button>
        </div>
      </div>
      
      <!-- 创建新分享 -->
      <div v-else class="share-content">
        <div v-if="!shareResult.url">
          <div class="share-form-header">
            <div class="file-icon-wrapper">
              <el-icon v-if="shareType === 'folder'"><Folder /></el-icon>
              <el-icon v-else><Document /></el-icon>
            </div>
            <div class="file-name">{{ shareItem?.folderName || shareItem?.fileName }}</div>
          </div>
          
          <el-form :model="shareForm" label-position="top" class="modern-form">
            <el-form-item label="有效期">
              <el-select v-model="shareForm.expireDays" style="width: 100%" size="large">
                <el-option :value="1" label="1天" />
                <el-option :value="7" label="7天" />
                <el-option :value="30" label="30天" />
                <el-option :value="0" label="永久有效" />
              </el-select>
            </el-form-item>
            <el-form-item label="访问权限">
              <div class="switch-card">
                <div class="switch-info">
                  <span class="switch-label">提取码保护</span>
                  <span class="switch-desc">{{ shareForm.needPassword ? '仅拥有提取码的用户可访问' : '任何知道链接的用户都可访问' }}</span>
                </div>
                <el-switch v-model="shareForm.needPassword" />
              </div>
            </el-form-item>
          </el-form>
        </div>
        
        <!-- 分享成功 -->
        <div v-else class="share-success-content">
          <div class="share-status-icon success animate">
            <el-icon><CircleCheck /></el-icon>
          </div>
          <h3 class="share-status-title">分享链接已生成</h3>
          
          <div class="share-result-card">
            <div class="result-item">
              <div class="label">链接地址</div>
              <el-input v-model="shareResult.url" readonly size="large">
                <template #append>
                  <el-button @click="copyShareUrl">复制</el-button>
                </template>
              </el-input>
            </div>
            
            <div class="result-item" v-if="shareResult.password">
              <div class="label">提取码</div>
              <div class="password-group">
                <el-tag type="success" effect="dark" size="large" class="password-tag">{{ shareResult.password }}</el-tag>
                <el-button link type="primary" @click="copySharePassword">复制</el-button>
              </div>
            </div>
          </div>
          
          <div class="share-footer-actions">
            <el-button type="primary" size="large" class="full-width-btn" @click="copyShareAll">一键复制所有信息</el-button>
          </div>
        </div>
      </div>
      
      <template #footer>
        <div v-if="!existingShare && !shareResult.url" class="dialog-footer">
          <el-button @click="shareDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="submitShare" :loading="shareLoading">创建分享</el-button>
        </div>
        <div v-else class="dialog-footer centered">
          <el-button @click="shareDialogVisible = false">关闭</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup name="FileManager">
import { 
  HomeFilled, Folder, Document, FolderAdd, Upload, UploadFilled, 
  ArrowDown, ArrowLeft, ArrowRight, Top, Menu, List, Edit, Download, Delete, Search,
  Share, CopyDocument, FolderRemove, Scissor, DocumentAdd, Refresh, CircleCheck
} from '@element-plus/icons-vue'
import { 
  listFolder, addFolder, updateFolder, delFolder, getFolderTree,
  listFile, downloadFile, delFile, updateFile,
  moveFile, copyFile, copyFolder,
  createFileShare, createFolderShare, cancelFileShare,
  getFileShare, getFolderShare
} from '@/api/system/file'
import { getToken } from '@/utils/auth'

const { proxy } = getCurrentInstance()

const loading = ref(false)
const viewMode = ref('grid')
const currentFolderId = ref(0)
const breadcrumbList = ref([])
const folderList = ref([])
const fileList = ref([])
const selectedItems = ref([])
const searchKeyword = ref('')

// 全选
const selectAll = ref(false)
const isIndeterminate = computed(() => {
  const totalItems = folderList.value.length + fileList.value.length
  return selectedItems.value.length > 0 && selectedItems.value.length < totalItems
})

// 剪贴板
const clipboard = ref([])
const clipboardAction = ref('') // 'copy' or 'cut'

// 拖拽
const draggedItems = ref([])
const dragOverFolderId = ref(null)

// 导航历史
const navigationHistory = ref([])
const currentHistoryIndex = ref(-1)

const canGoBack = computed(() => currentHistoryIndex.value > 0)
const canGoForward = computed(() => currentHistoryIndex.value < navigationHistory.value.length - 1)

// 右键菜单
const contextMenuVisible = ref(false)
const contextMenuX = ref(0)
const contextMenuY = ref(0)
const contextMenuType = ref('')
const contextMenuItem = ref(null)

// 对话框
const folderDialogVisible = ref(false)
const folderDialogTitle = ref('')
const folderName = ref('')
const currentFolder = ref(null)

const uploadDialogVisible = ref(false)
const uploadUrl = import.meta.env.VITE_APP_BASE_API + '/system/file/upload'
const uploadHeaders = { Authorization: 'Bearer ' + getToken() }
const uploadRef = ref(null)

const renameDialogVisible = ref(false)
const renameDialogTitle = ref('')
const renameType = ref('')
const renameItem = ref(null)
const renameName = ref('')

// 预览相关
const previewDialogVisible = ref(false)
const previewFile = ref(null)
const previewType = ref('')
const previewUrl = ref('')
const previewContent = ref('')

// 移动/复制相关
const folderSelectDialogVisible = ref(false)
const folderSelectTitle = ref('')
const folderSelectMode = ref('') // 'move' or 'copy'
const folderTree = ref([])
const folderTreeRef = ref(null)
const selectedTargetFolderId = ref(null)
const operatingItem = ref(null)

// 分享相关
const shareDialogVisible = ref(false)
const shareItem = ref(null)
const shareType = ref('') // 'file' or 'folder'
const shareForm = ref({
  expireDays: 7,
  needPassword: true
})
const existingShare = ref(null) // 已有分享

// 框选相关
const fileListContainerRef = ref(null)
const gridViewRef = ref(null)
const selectionBox = ref({
  visible: false,
  startX: 0,
  startY: 0,
  left: 0,
  top: 0,
  width: 0,
  height: 0
})
const isSelecting = ref(false)
const shareLoading = ref(false)
const shareResultDialogVisible = ref(false)
const shareResult = ref({
  url: '',
  password: ''
})

/** 加载数据 */
function loadData() {
  loading.value = true
  Promise.all([
    listFolder({ parentId: currentFolderId.value }),
    listFile({ folderId: currentFolderId.value })
  ]).then(([folderRes, fileRes]) => {
    folderList.value = folderRes.rows || folderRes.data || []
    fileList.value = fileRes.rows || fileRes.data || []
    loading.value = false
  }).catch(() => {
    loading.value = false
  })
}

/** 导航到文件夹 */
function navigateToFolder(folder) {
  const newFolderId = folder ? folder.folderId : 0
  
  // 更新历史
  if (currentHistoryIndex.value < navigationHistory.value.length - 1) {
    navigationHistory.value = navigationHistory.value.slice(0, currentHistoryIndex.value + 1)
  }
  navigationHistory.value.push(newFolderId)
  currentHistoryIndex.value = navigationHistory.value.length - 1
  
  currentFolderId.value = newFolderId
  
  // 更新面包屑
  if (folder) {
    const index = breadcrumbList.value.findIndex(item => item.folderId === folder.folderId)
    if (index >= 0) {
      breadcrumbList.value = breadcrumbList.value.slice(0, index + 1)
    } else {
      breadcrumbList.value.push(folder)
    }
  } else {
    breadcrumbList.value = []
  }
  
  selectedItems.value = []
  loadData()
}

/** 返回上一级 */
function goToParentFolder() {
  if (breadcrumbList.value.length > 1) {
    navigateToFolder(breadcrumbList.value[breadcrumbList.value.length - 2])
  } else {
    navigateToFolder(null)
  }
}

/** 后退 */
function goBack() {
  if (canGoBack.value) {
    currentHistoryIndex.value--
    currentFolderId.value = navigationHistory.value[currentHistoryIndex.value]
    loadData()
  }
}

/** 前进 */
function goForward() {
  if (canGoForward.value) {
    currentHistoryIndex.value++
    currentFolderId.value = navigationHistory.value[currentHistoryIndex.value]
    loadData()
  }
}

/** 搜索 */
function handleSearch() {
  // TODO: 实现搜索功能
}

/** 刷新 */
function handleRefresh() {
  loadData()
  proxy.$modal.msgSuccess('刷新成功')
}

/** 全选 */
function handleSelectAll(val) {
  if (val) {
    selectedItems.value = [
      ...folderList.value.map(f => ({ type: 'folder', id: f.folderId, item: f })),
      ...fileList.value.map(f => ({ type: 'file', id: f.fileId, item: f }))
    ]
  } else {
    selectedItems.value = []
  }
}

// 监听选中项变化，更新全选状态
watch(selectedItems, (newVal) => {
  const totalItems = folderList.value.length + fileList.value.length
  if (newVal.length === totalItems && totalItems > 0) {
    selectAll.value = true
  } else {
    selectAll.value = false
  }
}, { deep: true })

/** 新建命令 */
function handleNewCommand(command) {
  if (command === 'folder') {
    handleAddFolder()
  } else if (command === 'file') {
    // TODO: 新建文件功能
    proxy.$modal.msgWarning('新建文件功能开发中')
  } else if (command === 'upload') {
    handleUpload()
  }
}

/** 新建文件夹 */
function handleAddFolder() {
  folderDialogTitle.value = '新建文件夹'
  folderName.value = ''
  currentFolder.value = null
  folderDialogVisible.value = true
}

/** 提交文件夹 */
function submitFolder() {
  if (!folderName.value.trim()) {
    proxy.$modal.msgWarning('请输入文件夹名称')
    return
  }
  
  const data = {
    folderName: folderName.value,
    parentId: currentFolderId.value
  }
  
  if (currentFolder.value) {
    data.folderId = currentFolder.value.folderId
    updateFolder(data).then(() => {
      proxy.$modal.msgSuccess('修改成功')
      folderDialogVisible.value = false
      loadData()
    })
  } else {
    addFolder(data).then(() => {
      proxy.$modal.msgSuccess('创建成功')
      folderDialogVisible.value = false
      loadData()
    })
  }
}

/** 上传 */
function handleUpload() {
  uploadDialogVisible.value = true
}

function submitUpload() {
  uploadRef.value.submit()
}

function handleUploadSuccess() {
  proxy.$modal.msgSuccess('上传成功')
  uploadDialogVisible.value = false
  loadData()
}

function handleUploadError() {
  proxy.$modal.msgError('上传失败')
}

/** 选择项目 */
function handleItemClick(type, item) {
  const id = type === 'folder' ? item.folderId : item.fileId
  const index = selectedItems.value.findIndex(s => s.type === type && s.id === id)
  
  if (index >= 0) {
    selectedItems.value.splice(index, 1)
  } else {
    selectedItems.value.push({ type, id, item })
  }
}

function isSelected(type, id) {
  return selectedItems.value.some(s => s.type === type && s.id === id)
}

function handleSelectionChange(selection) {
  selectedItems.value = selection.map(item => ({
    type: item.folderId ? 'folder' : 'file',
    id: item.folderId || item.fileId,
    item
  }))
}

/** 右键菜单 */
function handleContextMenu(event, type, item) {
  contextMenuType.value = type
  contextMenuItem.value = item
  contextMenuX.value = event.clientX
  contextMenuY.value = event.clientY
  contextMenuVisible.value = true
}

/** 重命名 */
function handleRename(item) {
  closeContextMenu()
  if (!item) return
  
  renameType.value = item.folderId ? 'folder' : 'file'
  renameItem.value = item
  renameName.value = item.folderName || item.fileName
  renameDialogTitle.value = '重命名'
  renameDialogVisible.value = true
}

function submitRename() {
  if (!renameName.value.trim()) {
    proxy.$modal.msgWarning('请输入名称')
    return
  }
  
  if (renameType.value === 'folder') {
    updateFolder({
      folderId: renameItem.value.folderId,
      folderName: renameName.value
    }).then(() => {
      proxy.$modal.msgSuccess('修改成功')
      renameDialogVisible.value = false
      loadData()
    })
  } else {
    updateFile({
      fileId: renameItem.value.fileId,
      fileName: renameName.value
    }).then(() => {
      proxy.$modal.msgSuccess('修改成功')
      renameDialogVisible.value = false
      loadData()
    })
  }
}

/** 下载文件 */
function handleDownloadFile(file) {
  closeContextMenu()
  if (!file) return
  
  downloadFile(file.fileId).then(response => {
    const blob = new Blob([response])
    const link = document.createElement('a')
    link.href = URL.createObjectURL(blob)
    link.download = file.fileName
    link.click()
    URL.revokeObjectURL(link.href)
  })
}

/** 预览文件 */
function handleFilePreview(file) {
  if (!file) return
  
  previewFile.value = file
  const fileName = file.fileName || ''
  const ext = fileName.split('.').pop()?.toLowerCase() || ''
  
  // 判断文件类型
  const imageExts = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg']
  const videoExts = ['mp4', 'webm', 'ogg', 'mov', 'avi']
  const audioExts = ['mp3', 'wav', 'ogg', 'aac', 'flac']
  const textExts = ['txt', 'json', 'xml', 'html', 'css', 'js', 'ts', 'vue', 'md', 'yaml', 'yml', 'ini', 'conf', 'log']
  
  if (imageExts.includes(ext)) {
    previewType.value = 'image'
  } else if (videoExts.includes(ext)) {
    previewType.value = 'video'
  } else if (audioExts.includes(ext)) {
    previewType.value = 'audio'
  } else if (ext === 'pdf') {
    previewType.value = 'pdf'
  } else if (textExts.includes(ext)) {
    previewType.value = 'text'
    // 加载文本内容
    loadTextContent(file)
  } else {
    previewType.value = 'unsupported'
  }
  
  // 设置预览URL
  previewUrl.value = import.meta.env.VITE_APP_BASE_API + '/system/file/preview/' + file.fileId
  previewDialogVisible.value = true
}

/** 加载文本内容 */
async function loadTextContent(file) {
  try {
    const response = await downloadFile(file.fileId)
    const text = await response.text()
    previewContent.value = text
  } catch (error) {
    previewContent.value = '加载失败'
  }
}

/** 删除项目 */
function handleDeleteItem(item) {
  closeContextMenu()
  if (!item) return
  
  const isFolder = !!item.folderId
  const name = item.folderName || item.fileName
  
  proxy.$modal.confirm(`确定删除"${name}"吗？`).then(() => {
    if (isFolder) {
      return delFolder(item.folderId)
    } else {
      return delFile(item.fileId)
    }
  }).then(() => {
    proxy.$modal.msgSuccess('删除成功')
    loadData()
  }).catch(() => {})
}

/** 批量删除 */
function handleBatchDelete() {
  if (selectedItems.value.length === 0) return
  
  proxy.$modal.confirm(`确定删除选中的 ${selectedItems.value.length} 项吗？`).then(async () => {
    for (const item of selectedItems.value) {
      if (item.type === 'folder') {
        await delFolder(item.id)
      } else {
        await delFile(item.id)
      }
    }
    proxy.$modal.msgSuccess('删除成功')
    selectedItems.value = []
    loadData()
  }).catch(() => {})
}

/** 剪贴板 - 复制 */
function handleClipboardCopy() {
  closeContextMenu()
  clipboard.value = [...selectedItems.value]
  clipboardAction.value = 'copy'
  proxy.$modal.msgSuccess(`已复制 ${clipboard.value.length} 项`)
}

/** 剪贴板 - 剪切 */
function handleClipboardCut() {
  closeContextMenu()
  clipboard.value = [...selectedItems.value]
  clipboardAction.value = 'cut'
  proxy.$modal.msgSuccess(`已剪切 ${clipboard.value.length} 项`)
}

/** 剪贴板 - 粘贴 */
async function handleClipboardPaste() {
  closeContextMenu()
  if (clipboard.value.length === 0) {
    proxy.$modal.msgWarning('剪贴板为空')
    return
  }
  
  const targetFolderId = currentFolderId.value || 0
  const action = clipboardAction.value
  
  proxy.$modal.msg(`正在${action === 'copy' ? '复制' : '移动'} ${clipboard.value.length} 项...`)
  
  try {
    let successCount = 0
    let failCount = 0
    
    for (const item of clipboard.value) {
      try {
        if (action === 'copy') {
          if (item.type === 'folder') {
            await copyFolder(item.id, targetFolderId)
          } else {
            await copyFile(item.id, targetFolderId)
          }
          successCount++
        } else if (action === 'cut') {
          if (item.type === 'folder') {
            await updateFolder({
              folderId: item.id,
              folderName: item.item.folderName,
              parentId: targetFolderId
            })
          } else {
            await updateFile({
              fileId: item.id,
              fileName: item.item.fileName,
              folderId: targetFolderId
            })
          }
          successCount++
        }
      } catch (error) {
        failCount++
        console.error(`${action === 'copy' ? '复制' : '移动'}失败:`, error)
      }
    }
    
    if (successCount > 0) {
      proxy.$modal.msgSuccess(`${action === 'copy' ? '复制' : '移动'}成功 ${successCount} 项${failCount > 0 ? `，失败 ${failCount} 项` : ''}`)
      
      if (action === 'cut') {
        clipboard.value = []
        clipboardAction.value = ''
      }
      
      selectedItems.value = []
      loadData()
    } else {
      proxy.$modal.msgError('操作失败')
    }
  } catch (error) {
    proxy.$modal.msgError('操作失败')
  }
}

/** 拖拽开始 */
function handleDragStart(event, type, item) {
  const id = type === 'folder' ? item.folderId : item.fileId
  const isItemSelected = isSelected(type, id)
  
  if (isItemSelected && selectedItems.value.length > 0) {
    draggedItems.value = [...selectedItems.value]
  } else {
    draggedItems.value = [{ type, id, item }]
  }
  
  event.dataTransfer.effectAllowed = 'move'
}

/** 拖拽结束 */
function handleDragEnd() {
  draggedItems.value = []
  dragOverFolderId.value = null
}

/** 拖拽经过 */
function handleDragOver(event, folder) {
  event.preventDefault()
  dragOverFolderId.value = folder.folderId
  event.dataTransfer.dropEffect = 'move'
}

/** 拖拽离开 */
function handleDragLeave() {
  dragOverFolderId.value = null
}

/** 拖拽放置 */
async function handleDrop(event, targetFolder) {
  event.preventDefault()
  dragOverFolderId.value = null
  
  if (draggedItems.value.length === 0) return
  
  const targetFolderId = targetFolder.folderId
  
  // 检查是否拖拽到自己
  const dragSelf = draggedItems.value.some(item => 
    item.type === 'folder' && item.id === targetFolderId
  )
  
  if (dragSelf) {
    proxy.$modal.msgWarning('不能将文件夹移动到自己内部')
    return
  }
  
  proxy.$modal.msg(`正在移动 ${draggedItems.value.length} 项到 ${targetFolder.folderName}...`)
  
  try {
    let successCount = 0
    let failCount = 0
    
    for (const item of draggedItems.value) {
      try {
        if (item.type === 'folder') {
          await updateFolder({
            folderId: item.id,
            folderName: item.item.folderName,
            parentId: targetFolderId
          })
        } else {
          await updateFile({
            fileId: item.id,
            fileName: item.item.fileName,
            folderId: targetFolderId
          })
        }
        successCount++
      } catch (error) {
        failCount++
        console.error('移动失败:', error)
      }
    }
    
    if (successCount > 0) {
      proxy.$modal.msgSuccess(`移动成功 ${successCount} 项${failCount > 0 ? `，失败 ${failCount} 项` : ''}`)
      selectedItems.value = []
      loadData()
    } else {
      proxy.$modal.msgError('移动失败')
    }
  } catch (error) {
    proxy.$modal.msgError('移动失败')
  }
}

/** 分享 */
async function handleShare(item) {
  closeContextMenu()
  if (!item) return
  
  const type = item.folderId ? 'folder' : 'file'
  
  shareType.value = type
  shareItem.value = item
  shareForm.value = { expireDays: 7, needPassword: true }
  shareResult.value = { url: '', password: '' }
  existingShare.value = null
  
  // 检查是否已有分享
  if (type === 'file' && item.fileId) {
    try {
      const response = await getFileShare(item.fileId)
      if (response.code === 200 && response.data) {
        const baseUrl = window.location.origin
        const shareCode = response.data.shareCode
        const sharePassword = response.data.sharePassword
        
        let shareUrl = `${baseUrl}/share/${shareCode}`
        if (sharePassword) {
          shareUrl += `?code=${sharePassword}`
        }
        
        existingShare.value = {
          ...response.data,
          shareUrl: shareUrl
        }
      }
    } catch (error) {
      console.log('没有现有分享')
    }
  } else if (type === 'folder' && item.folderId) {
    try {
      const response = await getFolderShare(item.folderId)
      if (response.code === 200 && response.data) {
        const baseUrl = window.location.origin
        const shareCode = response.data.shareCode
        const sharePassword = response.data.sharePassword
        
        let shareUrl = `${baseUrl}/share/${shareCode}`
        if (sharePassword) {
          shareUrl += `?code=${sharePassword}`
        }
        
        existingShare.value = {
          ...response.data,
          shareUrl: shareUrl
        }
      }
    } catch (error) {
      console.log('没有现有文件夹分享')
    }
  }
  
  shareDialogVisible.value = true
}

async function submitShare() {
  if (!shareItem.value) return
  
  shareLoading.value = true
  try {
    const isFolder = shareType.value === 'folder'
    let response
    
    if (isFolder) {
      response = await createFolderShare(shareItem.value.folderId, shareForm.value.expireDays, shareForm.value.needPassword)
    } else {
      response = await createFileShare(shareItem.value.fileId, shareForm.value.expireDays, shareForm.value.needPassword)
    }
    
    if (response.code === 200) {
      const baseUrl = window.location.origin
      const shareCode = response.data.shareCode
      const sharePassword = response.data.sharePassword
      
      let shareUrl = `${baseUrl}/share/${shareCode}`
      if (sharePassword) {
        shareUrl += `?code=${sharePassword}`
      }
      
      shareResult.value = {
        url: shareUrl,
        password: sharePassword || ''
      }
      proxy.$modal.msgSuccess('创建分享成功')
    } else {
      proxy.$modal.msgError(response.msg || '创建分享失败')
    }
  } catch (error) {
    proxy.$modal.msgError('创建分享失败')
  } finally {
    shareLoading.value = false
  }
}

/** 取消分享 */
async function handleCancelShare() {
  if (!shareItem.value) return
  
  try {
    await proxy.$modal.confirm('确定要取消此分享吗？取消后链接将失效')
    
    const isFolder = shareType.value === 'folder'
    const id = isFolder ? shareItem.value.folderId : shareItem.value.fileId
    
    await cancelFileShare(id)
    
    proxy.$modal.msgSuccess('已取消分享')
    existingShare.value = null
  } catch (error) {
    if (error !== 'cancel') {
      proxy.$modal.msgError('取消分享失败')
    }
  }
}

/** 复制已有分享链接 */
function copyExistingShareLink() {
  if (existingShare.value) {
    const text = existingShare.value.sharePassword 
      ? `链接: ${existingShare.value.shareUrl}\n提取码: ${existingShare.value.sharePassword}`
      : existingShare.value.shareUrl
    navigator.clipboard.writeText(text)
    proxy.$modal.msgSuccess('已复制到剪贴板')
  }
}

function copyShareUrl() {
  navigator.clipboard.writeText(shareResult.value.url)
  proxy.$modal.msgSuccess('链接已复制')
}

function copySharePassword() {
  navigator.clipboard.writeText(shareResult.value.password)
  proxy.$modal.msgSuccess('提取码已复制')
}

function copyShareAll() {
  const text = shareResult.value.password 
    ? `链接: ${shareResult.value.url}\n提取码: ${shareResult.value.password}`
    : shareResult.value.url
  navigator.clipboard.writeText(text)
  proxy.$modal.msgSuccess('已复制到剪贴板')
}

/** 复制 */
async function handleCopy(item) {
  closeContextMenu()
  if (!item) return
  
  operatingItem.value = item
  folderSelectMode.value = 'copy'
  folderSelectTitle.value = '复制到'
  selectedTargetFolderId.value = null
  
  try {
    const response = await getFolderTree()
    folderTree.value = [{ id: 0, label: '根目录', children: response.data || [] }]
    folderSelectDialogVisible.value = true
  } catch (error) {
    proxy.$modal.msgError('加载文件夹失败')
  }
}

/** 移动 */
async function handleMove(item) {
  closeContextMenu()
  if (!item) return
  
  operatingItem.value = item
  folderSelectMode.value = 'move'
  folderSelectTitle.value = '移动到'
  selectedTargetFolderId.value = null
  
  try {
    const response = await getFolderTree()
    folderTree.value = [{ id: 0, label: '根目录', children: response.data || [] }]
    folderSelectDialogVisible.value = true
  } catch (error) {
    proxy.$modal.msgError('加载文件夹失败')
  }
}

function handleFolderTreeClick(data) {
  selectedTargetFolderId.value = data.id
}

async function submitFolderSelect() {
  if (selectedTargetFolderId.value === null || !operatingItem.value) return
  
  const isFolder = !!operatingItem.value.folderId
  const targetId = selectedTargetFolderId.value
  
  try {
    if (folderSelectMode.value === 'copy') {
      if (isFolder) {
        await copyFolder(operatingItem.value.folderId, targetId)
      } else {
        await copyFile(operatingItem.value.fileId, targetId)
      }
      proxy.$modal.msgSuccess('复制成功')
    } else {
      if (isFolder) {
        proxy.$modal.msgError('暂不支持移动文件夹')
        return
      }
      await moveFile(operatingItem.value.fileId, targetId)
      proxy.$modal.msgSuccess('移动成功')
    }
    
    folderSelectDialogVisible.value = false
    loadData()
  } catch (error) {
    proxy.$modal.msgError(folderSelectMode.value === 'copy' ? '复制失败' : '移动失败')
  }
}

/** 关闭右键菜单 */
function closeContextMenu() {
  contextMenuVisible.value = false
}

/** 框选开始 */
function handleSelectionStart(e) {
  // 只在网格视图下启用框选，且点击的不是文件项
  if (viewMode.value !== 'grid') return
  if (e.target.closest('.file-item')) return
  if (e.button !== 0) return // 只响应左键
  
  const container = fileListContainerRef.value
  if (!container) return
  
  const rect = container.getBoundingClientRect()
  const scrollTop = container.scrollTop
  const scrollLeft = container.scrollLeft
  
  selectionBox.value.startX = e.clientX - rect.left + scrollLeft
  selectionBox.value.startY = e.clientY - rect.top + scrollTop
  selectionBox.value.left = selectionBox.value.startX
  selectionBox.value.top = selectionBox.value.startY
  selectionBox.value.width = 0
  selectionBox.value.height = 0
  selectionBox.value.visible = true
  isSelecting.value = true
  
  // 如果不是按住 Ctrl/Cmd，则清除之前的选择
  if (!e.ctrlKey && !e.metaKey) {
    selectedItems.value = []
  }
}

/** 框选移动 */
function handleSelectionMove(e) {
  if (!isSelecting.value || !selectionBox.value.visible) return
  
  const container = fileListContainerRef.value
  if (!container) return
  
  const rect = container.getBoundingClientRect()
  const scrollTop = container.scrollTop
  const scrollLeft = container.scrollLeft
  
  const currentX = e.clientX - rect.left + scrollLeft
  const currentY = e.clientY - rect.top + scrollTop
  
  // 计算选择框的位置和大小
  selectionBox.value.left = Math.min(selectionBox.value.startX, currentX)
  selectionBox.value.top = Math.min(selectionBox.value.startY, currentY)
  selectionBox.value.width = Math.abs(currentX - selectionBox.value.startX)
  selectionBox.value.height = Math.abs(currentY - selectionBox.value.startY)
  
  // 实时更新选中的项目
  updateSelectionFromBox()
}

/** 框选结束 */
function handleSelectionEnd() {
  if (!isSelecting.value) return
  
  isSelecting.value = false
  selectionBox.value.visible = false
}

/** 根据框选区域更新选中项 */
function updateSelectionFromBox() {
  if (!gridViewRef.value) return
  
  const container = fileListContainerRef.value
  const containerRect = container.getBoundingClientRect()
  const scrollTop = container.scrollTop
  const scrollLeft = container.scrollLeft
  
  const boxRect = {
    left: selectionBox.value.left,
    top: selectionBox.value.top,
    right: selectionBox.value.left + selectionBox.value.width,
    bottom: selectionBox.value.top + selectionBox.value.height
  }
  
  const items = gridViewRef.value.querySelectorAll('.file-item')
  const newSelection = []
  
  items.forEach(item => {
    const itemRect = item.getBoundingClientRect()
    // 转换为相对于容器的坐标（考虑滚动）
    const itemRelRect = {
      left: itemRect.left - containerRect.left + scrollLeft,
      top: itemRect.top - containerRect.top + scrollTop,
      right: itemRect.right - containerRect.left + scrollLeft,
      bottom: itemRect.bottom - containerRect.top + scrollTop
    }
    
    // 检查是否与选择框相交
    if (isRectIntersect(boxRect, itemRelRect)) {
      const type = item.dataset.type
      const id = parseInt(item.dataset.id)
      
      if (type && id) {
        // 找到对应的数据项
        let dataItem = null
        if (type === 'folder') {
          dataItem = folderList.value.find(f => f.folderId === id)
        } else {
          dataItem = fileList.value.find(f => f.fileId === id)
        }
        
        if (dataItem) {
          newSelection.push({ type, id, item: dataItem })
        }
      }
    }
  })
  
  selectedItems.value = newSelection
}

/** 判断两个矩形是否相交 */
function isRectIntersect(rect1, rect2) {
  return !(
    rect1.right < rect2.left ||
    rect1.left > rect2.right ||
    rect1.bottom < rect2.top ||
    rect1.top > rect2.bottom
  )
}

/** 格式化文件大小 */
function formatFileSize(bytes) {
  if (!bytes) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB', 'TB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

/** 获取文件图标样式类 */
function getFileIconClass(fileName) {
  const ext = (fileName || '').split('.').pop()?.toLowerCase() || ''
  const imageExts = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg']
  const videoExts = ['mp4', 'webm', 'ogg', 'mov', 'avi', 'mkv']
  const audioExts = ['mp3', 'wav', 'ogg', 'aac', 'flac']
  const docExts = ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'pdf']
  const codeExts = ['js', 'ts', 'vue', 'html', 'css', 'scss', 'json', 'java', 'py', 'go']
  const archiveExts = ['zip', 'rar', '7z', 'tar', 'gz']
  
  if (imageExts.includes(ext)) return 'icon-image'
  if (videoExts.includes(ext)) return 'icon-video'
  if (audioExts.includes(ext)) return 'icon-audio'
  if (docExts.includes(ext)) return 'icon-doc'
  if (codeExts.includes(ext)) return 'icon-code'
  if (archiveExts.includes(ext)) return 'icon-archive'
  return 'icon-default'
}

/** 获取文件图标颜色 */
function getFileIconColor(fileName) {
  const ext = (fileName || '').split('.').pop()?.toLowerCase() || ''
  const imageExts = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg']
  const videoExts = ['mp4', 'webm', 'ogg', 'mov', 'avi', 'mkv']
  const audioExts = ['mp3', 'wav', 'ogg', 'aac', 'flac']
  const docExts = ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'pdf']
  const codeExts = ['js', 'ts', 'vue', 'html', 'css', 'scss', 'json', 'java', 'py', 'go']
  const archiveExts = ['zip', 'rar', '7z', 'tar', 'gz']
  
  if (imageExts.includes(ext)) return '#67c23a'
  if (videoExts.includes(ext)) return '#e6a23c'
  if (audioExts.includes(ext)) return '#f56c6c'
  if (docExts.includes(ext)) return '#409eff'
  if (codeExts.includes(ext)) return '#9b59b6'
  if (archiveExts.includes(ext)) return '#909399'
  return '#606266'
}

/** 键盘快捷键处理 */
function handleKeyDown(event) {
  // 如果在输入框中，不处理快捷键
  if (event.target.tagName === 'INPUT' || event.target.tagName === 'TEXTAREA') {
    return
  }
  
  // Ctrl+A: 全选
  if (event.ctrlKey && event.key === 'a') {
    event.preventDefault()
    selectAll.value = true
    handleSelectAll(true)
  }
  
  // Delete: 删除选中项
  if (event.key === 'Delete' && selectedItems.value.length > 0) {
    event.preventDefault()
    if (selectedItems.value.length === 1) {
      const item = selectedItems.value[0]
      contextMenuItem.value = item.item
      contextMenuType.value = item.type
      handleDeleteItem(item.item)
    } else {
      handleBatchDelete()
    }
  }
  
  // Escape: 取消选择/关闭菜单
  if (event.key === 'Escape') {
    if (contextMenuVisible.value) {
      closeContextMenu()
    } else if (selectedItems.value.length > 0) {
      selectedItems.value = []
    }
  }
  
  // F2: 重命名
  if (event.key === 'F2' && selectedItems.value.length === 1) {
    event.preventDefault()
    const item = selectedItems.value[0]
    handleRename(item.item)
  }
  
  // F5: 刷新
  if (event.key === 'F5') {
    event.preventDefault()
    handleRefresh()
  }
  
  // Ctrl+N: 新建文件夹
  if (event.ctrlKey && event.key === 'n') {
    event.preventDefault()
    handleAddFolder()
  }
  
  // Ctrl+U: 上传文件
  if (event.ctrlKey && event.key === 'u') {
    event.preventDefault()
    handleUpload()
  }
  
  // Backspace: 返回上一级
  if (event.key === 'Backspace' && currentFolderId.value !== null && currentFolderId.value !== 0) {
    event.preventDefault()
    goToParentFolder()
  }
  
  // Ctrl+C: 复制
  if (event.ctrlKey && event.key === 'c' && selectedItems.value.length > 0) {
    event.preventDefault()
    handleClipboardCopy()
  }
  
  // Ctrl+X: 剪切
  if (event.ctrlKey && event.key === 'x' && selectedItems.value.length > 0) {
    event.preventDefault()
    handleClipboardCut()
  }
  
  // Ctrl+V: 粘贴
  if (event.ctrlKey && event.key === 'v' && clipboard.value.length > 0) {
    event.preventDefault()
    handleClipboardPaste()
  }
}

// 点击页面关闭右键菜单
onMounted(() => {
  document.addEventListener('click', closeContextMenu)
  document.addEventListener('keydown', handleKeyDown)
  navigationHistory.value = [0]
  currentHistoryIndex.value = 0
  loadData()
})

onUnmounted(() => {
  document.removeEventListener('click', closeContextMenu)
  document.removeEventListener('keydown', handleKeyDown)
})
</script>

<style lang="scss" scoped>
.file-manager {
  height: calc(100vh - 84px);
  display: flex;
  flex-direction: column;
  background: #f5f7fa;
}

.toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px 20px;
  background: #ffffff;
  border-bottom: 1px solid #ebeef5;
  gap: 16px;
  flex-wrap: wrap;
  
  .toolbar-left {
    display: flex;
    align-items: center;
    gap: 12px;
    flex: 1;
    min-width: 0;
  }
  
  .toolbar-right {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-shrink: 0;
  }
  
  .path-bar {
    padding: 10px 16px;
    background: #f5f7fa;
    border-radius: 8px;
    flex: 1;
    min-width: 200px;
    max-width: 500px;
    
    .el-breadcrumb {
      line-height: 1;
      font-size: 14px;
    }
    
    :deep(.el-breadcrumb__item) {
      cursor: pointer;
      
      .el-breadcrumb__inner {
        transition: color 0.2s;
        
        &:hover {
          color: #409eff;
        }
      }
    }
  }
  
  .search-input {
    width: 220px;
    
    :deep(.el-input__wrapper) {
      border-radius: 8px;
    }
  }
}

.file-list-container {
  flex: 1;
  overflow: auto;
  padding: 20px;
  position: relative;
  user-select: none;
  
  &::-webkit-scrollbar {
    width: 6px;
    height: 6px;
  }
  
  &::-webkit-scrollbar-thumb {
    background: #d1d5db;
    border-radius: 3px;
  }
}

// 框选矩形
.selection-box {
  position: absolute;
  background: rgba(64, 158, 255, 0.1);
  border: 1px solid rgba(64, 158, 255, 0.6);
  border-radius: 2px;
  pointer-events: none;
  z-index: 100;
}

.grid-view {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 20px;
  
  .file-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 20px 16px;
    background: #ffffff;
    border-radius: 12px;
    cursor: pointer;
    transition: all 0.25s ease;
    border: 2px solid transparent;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
    
    &:hover {
      background: #ffffff;
      transform: translateY(-2px);
      box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
    }
    
    &.selected {
      background: #ecf5ff;
      border-color: #409eff;
      box-shadow: 0 4px 12px rgba(64, 158, 255, 0.15);
    }
    
    &.drag-over {
      background: #e6f7e6;
      border-color: #67c23a;
      box-shadow: 0 4px 12px rgba(103, 194, 58, 0.25);
      transform: scale(1.02);
    }
    
    .file-icon {
      margin-bottom: 12px;
      width: 64px;
      height: 64px;
      display: flex;
      align-items: center;
      justify-content: center;
      background: #f0f5ff;
      border-radius: 12px;
      transition: all 0.2s;
    }
    
    &:hover .file-icon {
      background: #e6f0ff;
      transform: scale(1.05);
    }
    
    .file-name {
      font-size: 13px;
      font-weight: 500;
      text-align: center;
      word-break: break-all;
      display: -webkit-box;
      -webkit-line-clamp: 2;
      -webkit-box-orient: vertical;
      overflow: hidden;
      color: #303133;
      line-height: 1.4;
    }
    
    .file-size {
      font-size: 12px;
      color: #909399;
      margin-top: 6px;
    }
  }
  
  // 文件夹图标背景色
  .folder-type {
    .file-icon.icon-folder {
      background: #fff8e1;
    }
  }
  
  // 文件类型图标背景色
  .file-type {
    .file-icon {
      &.icon-image { background: #f0fdf4; }
      &.icon-video { background: #fffbeb; }
      &.icon-audio { background: #fef2f2; }
      &.icon-doc { background: #eff6ff; }
      &.icon-code { background: #faf5ff; }
      &.icon-archive { background: #f5f5f5; }
      &.icon-default { background: #f5f7fa; }
    }
  }
}

// 列表视图优化
:deep(.el-table) {
  border-radius: 12px;
  overflow: hidden;
  
  .el-table__header-wrapper {
    th {
      background: #f5f7fa !important;
      font-weight: 600;
    }
  }
  
  .el-table__row {
    transition: background 0.2s;
    
    &:hover > td {
      background: #f5f9ff !important;
    }
  }
}

.name-cell {
  display: flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  padding: 8px 0;
  
  .el-icon {
    font-size: 20px;
  }
  
  span {
    font-weight: 500;
    transition: color 0.2s;
  }
  
  &:hover span {
    color: #409eff;
  }
}

.context-menu {
  position: fixed;
  background: #ffffff;
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
  padding: 8px 0;
  z-index: 3000;
  min-width: 160px;
  border: 1px solid rgba(0, 0, 0, 0.05);
  
  .menu-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 16px;
    cursor: pointer;
    font-size: 14px;
    color: #606266;
    transition: all 0.15s;
    
    .el-icon {
      font-size: 16px;
    }
    
    &:hover {
      background: #f5f7fa;
      color: #409eff;
    }
    
    &.danger {
      color: #f56c6c;
      
      &:hover {
        background: #fff5f5;
        color: #f56c6c;
      }
    }
  }
  
  .menu-divider {
    height: 1px;
    background: #ebeef5;
    margin: 6px 0;
  }
}

// 选中数量
.selection-count {
  font-size: 13px;
  color: #409eff;
  margin-right: 12px;
  font-weight: 500;
}

.preview-container {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 400px;
  background: #fafafa;
  border-radius: 8px;
  padding: 20px;
  
  .preview-image,
  .preview-video,
  .preview-audio,
  .preview-pdf,
  .preview-text {
    width: 100%;
    display: flex;
    justify-content: center;
  }
  
  .preview-image {
    :deep(.el-image) {
      border-radius: 8px;
      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
    }
  }
  
  .preview-video video {
    border-radius: 8px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  }
  
  .preview-text pre {
    width: 100%;
    white-space: pre-wrap;
    word-wrap: break-word;
    background: #ffffff;
    border-radius: 8px;
    font-family: 'Monaco', 'Menlo', monospace;
    font-size: 13px;
    line-height: 1.6;
  }
}

// 空状态优化
:deep(.el-empty) {
  padding: 60px 0;
  
  .el-empty__description {
    margin-top: 16px;
    color: #909399;
  }
  
  .el-empty__bottom {
    margin-top: 20px;
    display: flex;
    gap: 12px;
  }
}

// 对话框优化
:deep(.el-dialog) {
  border-radius: 12px;
  
  .el-dialog__header {
    padding: 20px 24px 16px;
    border-bottom: 1px solid #f0f2f5;
  }
  
  .el-dialog__body {
    padding: 24px;
  }
  
  .el-dialog__footer {
    padding: 16px 24px 20px;
    border-top: 1px solid #f0f2f5;
  }
}

// 上传区域优化
:deep(.el-upload-dragger) {
  border-radius: 12px;
  border: 2px dashed #dcdfe6;
  transition: all 0.2s;
  padding: 40px 20px;
  
  &:hover {
    border-color: #409eff;
    background: #f5f9ff;
  }
  
  .el-icon--upload {
    font-size: 48px;
    color: #909399;
    margin-bottom: 16px;
  }
  
  .el-upload__text {
    color: #606266;
    font-size: 14px;
    
    em {
      color: #409eff;
      font-style: normal;
    }
  }
}

// 文件夹树选择
.folder-tree-node {
  display: flex;
  align-items: center;
  gap: 8px;
  
  .el-icon {
    font-size: 18px;
  }
}

:deep(.el-tree) {
  .el-tree-node__content {
    height: 36px;
    border-radius: 6px;
    margin: 2px 0;
    
    &:hover {
      background: #f5f7fa;
    }
  }
  
  .el-tree-node.is-current > .el-tree-node__content {
    background: #ecf5ff;
    color: #409eff;
  }
}

// 分享结果
.share-result {
  .share-tip {
    text-align: center;
    margin-top: 20px;
    padding-top: 20px;
    border-top: 1px solid #f0f2f5;
  }
}

// 分享成功
.share-success {
  text-align: center;
  
  .success-icon {
    font-size: 48px;
    color: #67C23A;
    margin-bottom: 16px;
  }
  
  .success-text {
    font-size: 16px;
    color: #303133;
    margin-bottom: 20px;
  }
  
  .el-form {
    text-align: left;
  }
  
  .share-tip {
    margin-top: 20px;
    padding-top: 20px;
    border-top: 1px solid #f0f2f5;
  }
}

// 分享弹窗样式
.share-dialog {
  border-radius: 12px;
  overflow: hidden;
  
  :deep(.el-dialog__header) {
    margin: 0;
    padding: 20px 24px;
    border-bottom: 1px solid #f0f2f5;
    
    .dialog-title {
      font-size: 18px;
      font-weight: 600;
      color: #303133;
    }
  }
  
  :deep(.el-dialog__body) {
    padding: 24px;
  }
  
  :deep(.el-dialog__footer) {
    padding: 16px 24px;
    border-top: 1px solid #f0f2f5;
    background: #fcfcfc;
  }
}

.share-content {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.share-status-icon {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto 8px;
  
  &.success {
    background: #f0f9eb;
    color: #67c23a;
  }
  
  &.animate {
    animation: scaleIn 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
  }
  
  .el-icon {
    font-size: 32px;
  }
}

@keyframes scaleIn {
  from { transform: scale(0); }
  to { transform: scale(1); }
}

.share-status-title {
  text-align: center;
  font-size: 18px;
  font-weight: 600;
  color: #303133;
  margin: 0 0 8px;
}

.share-info-card, .share-result-card {
  background: #f8f9fa;
  border-radius: 8px;
  padding: 16px;
  border: 1px solid #ebeef5;
}

.info-item, .result-item {
  margin-bottom: 16px;
  
  &:last-child {
    margin-bottom: 0;
  }
  
  .label {
    font-size: 13px;
    color: #909399;
    margin-bottom: 8px;
    display: block;
  }
}

.value-group {
  .copy-icon {
    cursor: pointer;
    color: #909399;
    transition: color 0.2s;
    
    &:hover {
      color: #409eff;
    }
  }
}

.info-row {
  display: flex;
  gap: 24px;
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px dashed #dcdfe6;
  
  .info-item {
    margin-bottom: 0;
    flex: 1;
  }
}

.value-tag {
  font-family: monospace;
  font-size: 16px;
  font-weight: 600;
  color: #67c23a;
  background: #f0f9eb;
  padding: 4px 8px;
  border-radius: 4px;
  display: inline-block;
}

.value-text {
  font-size: 14px;
  color: #606266;
  line-height: 28px;
}

.share-form-header {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 24px;
  padding-bottom: 20px;
  border-bottom: 1px solid #f0f2f5;
  
  .file-icon-wrapper {
    width: 48px;
    height: 48px;
    border-radius: 8px;
    background: #ecf5ff;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #409eff;
    font-size: 24px;
  }
  
  .file-name {
    font-size: 16px;
    font-weight: 500;
    color: #303133;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
}

.switch-card {
  background: #f8f9fa;
  border-radius: 8px;
  padding: 12px 16px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  border: 1px solid #ebeef5;
  
  .switch-info {
    display: flex;
    flex-direction: column;
    gap: 4px;
    
    .switch-label {
      font-size: 14px;
      font-weight: 500;
      color: #303133;
    }
    
    .switch-desc {
      font-size: 12px;
      color: #909399;
    }
  }
}

.password-group {
  display: flex;
  align-items: center;
  gap: 12px;
  
  .password-tag {
    font-family: monospace;
    letter-spacing: 1px;
    padding: 0 16px;
  }
}

.full-width-btn {
  width: 100%;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  
  &.centered {
    justify-content: center;
  }
}
</style>
