<template>
  <div class="main-container">
      <div class="page-header">
          <div class="header-top">
              <el-button
                  type="text"
                  :icon="ArrowLeft"
                  @click="handleGoBack"
                  class="back-button"
              >
                  {{t('vabI18n.knowledge.document.buttons.back')}}
              </el-button>
              <h2 class="page-title">{{ datasetName }}</h2>
          </div>

          <!-- 面包屑导航 -->
          <div class="breadcrumb-container">
              <el-breadcrumb separator="/">
                  <el-breadcrumb-item @click="navigateToRoot" class="breadcrumb-clickable">
                      <el-icon><House /></el-icon>
                      <span>{{t('vabI18n.knowledge.document.breadcrumb.root', '根目录')}}</span>
                  </el-breadcrumb-item>
                  <el-breadcrumb-item
                      v-for="(folder, index) in breadcrumbPath"
                      :key="folder.id"
                      @click="navigateToFolder(folder, index)"
                      :class="{ 'breadcrumb-clickable': index < breadcrumbPath.length - 1 }"
                  >
                      <span>{{ folder.name }}</span>
                  </el-breadcrumb-item>
              </el-breadcrumb>
          </div>

          <div class="page-description">
              {{t('vabI18n.knowledge.document.header.description')}} {{ pagination.total }} {{ $t(pagination.total > 1
    ? 'vabI18n.knowledge.document.header.descriptionEnds'
    : 'vabI18n.knowledge.document.header.descriptionEnd') }}
          </div>
      </div>

      <!-- 主要内容区域 -->
      <div class="content-layout">
          <div
              class="file-manager-container"
              @contextmenu.prevent="handleRightClick"
              @click="hideContextMenu"
          >
          <!-- 操作栏 -->
          <div class="action-bar">
              <div class="left-group">
                  <el-input
                      v-model="searchKeyword"
                      :placeholder="$t('vabI18n.knowledge.document.search.placeholder')"
                      class="search-input"
                      clearable
                  >
                      <template #prefix>
                          <el-icon><Search /></el-icon>
                      </template>
                  </el-input>
                  <el-button type="primary" :icon="Search" @click="handleSearch">{{t('vabI18n.knowledge.document.buttons.search')}}</el-button>
              </div>

              <div class="right-group">
                  <el-button
                      v-if="selectedRows.length > 0"
                      type="danger"
                      :icon="Delete"
                      @click="handleBatchDelete"
                      class="batch-delete-btn"
                  >
                      {{t('vabI18n.knowledge.document.buttons.batchDelete', { count: selectedRows.length })}}
                  </el-button>
                  <el-button :icon="Refresh" @click="handleRefresh">{{t('vabI18n.knowledge.document.buttons.refresh')}}</el-button>

                  <el-button type="primary" :icon="Upload" @click="triggerFileInput">{{t('vabI18n.knowledge.document.buttons.upload')}}</el-button>
              </div>
          </div>

          <!-- 文件表格 -->
          <el-table
              v-loading="tableLoading"
              :element-loading-text="$t('vabI18n.knowledge.document.messages.loading')"
              :data="fileList"
              stripe
              class="file-table"
              :row-style="{ height: '50px' }"
              :header-row-style="{ height: '50px' }"
              @selection-change="handleSelectionChange"
              @row-dblclick="handleRowDoubleClick"
              @sort-change="handleSortChange"
          >
              <el-table-column type="selection" width="55" />
              <el-table-column
                  :label="$t('vabI18n.knowledge.document.table.index')"
                  width="80"
                  align="center"
                  type="index"
                  :index="indexMethod"
              />
              <el-table-column prop="fileName" :label="t('vabI18n.knowledge.document.table.fileName')" min-width="250" sortable="custom" :sort-orders="['ascending', 'descending']">
                  <template #default="{ row }">
                      <div class="file-name-cell">
                          <img
                              v-if="row.type === 'file'"
                              :src="getFileTypeIcon(row.fileType)"
                              alt="文件图标"
                              class="file-icon"
                          />
                          <el-icon v-else class="folder-icon" size="20" color="#409eff">
                              <Folder />
                          </el-icon>
                          <span class="file-name" :title="row.fileName">{{ row.fileName }}</span>
                      </div>
                  </template>
              </el-table-column>
              <el-table-column prop="parseStatus" :label="t('vabI18n.knowledge.document.table.status')" width="120" align="center">
                  <template #default="{ row }">
                      <!-- 文件夹不显示状态 -->
                      <template v-if="row.type === 'file'">
                          <el-tag
                              :type="getStatusTagType(row.status)"
                              :class="{ 'rotating-tag': ['preprocessing', 'indexing', 'waiting', 'queued'].includes(row.status) }"
                          >
                              <el-icon
                                  :class="{ 'is-loading': ['preprocessing', 'indexing', 'waiting', 'queued'].includes(row.status) }"
                              >
                                  <component :is="getStatusIcon(row.status)" />
                              </el-icon>
                              {{ row.parseStatus }}
                          </el-tag>
                      </template>
                      <span v-else class="folder-status">--</span>
                  </template>
              </el-table-column>
              <el-table-column prop="createDate" :label="t('vabI18n.knowledge.document.table.createDate')" width="180" sortable="custom" :sort-orders="['ascending', 'descending']" />
              <el-table-column prop="charCount" :label="t('vabI18n.knowledge.document.table.charCount')" width="120" align="right" sortable="custom" :sort-orders="['ascending', 'descending']">
                  <template #default="{ row }">
                      <span class="char-count" v-if="row.type === 'file'">{{ formatFileSize(row.charCount) }}</span>
                      <span v-else class="folder-indicator">--</span>
                  </template>
              </el-table-column>
              <el-table-column :label="t('vabI18n.knowledge.document.table.actions')" width="380" fixed="right">
                  <template #default="{ row }">
                      <div class="action-buttons">
                          <!-- 文件操作 -->
                          <template v-if="row.type === 'file'">
                              <el-button
                                  :type="row.status === 'completed' ? 'primary' : 'info'"
                                  :icon="View"
                                  text
                                  class="action-btn"
                                  :disabled="row.status !== 'completed'"
                                  :class="{ 'disabled-btn': row.status !== 'completed' }"
                                  @click="row.status === 'completed' ? handlePreview(row) : null"
                              >
                                  {{t('vabI18n.knowledge.document.buttons.preview')}}
                              </el-button>
                              <el-button
                                  :type="row.status === 'completed' ? 'success' : 'info'"
                                  :icon="Download"
                                  text
                                  class="action-btn"
                                  :disabled="row.status !== 'completed'"
                                  :class="{ 'disabled-btn': row.status !== 'completed' }"
                                  @click="row.status === 'completed' ? handleDownload(row) : null"
                              >
                                  {{t('vabI18n.knowledge.document.buttons.download')}}
                              </el-button>
                              <el-button 
                                  type="warning" 
                                  :icon="Upload" 
                                  text 
                                  class="action-btn" 
                                  @click="handleFileReplaceFromRow(row)"
                              >
                                  替换
                              </el-button>
                          </template>
                          <!-- 文件夹操作 -->
                          <template v-else>
                              <el-button
                                  type="primary"
                                  :icon="View"
                                  text
                                  class="action-btn"
                                  @click="handleOpenFolder(row)"
                              >
                                  {{t('vabI18n.knowledge.document.buttons.open', '打开')}}
                              </el-button>
                          </template>
                          <!-- 共同操作 -->
                          <el-button
                              type="warning"
                              :icon="Edit"
                              text
                              class="action-btn"
                              @click="handleRename(row)"
                          >
                              {{t('vabI18n.knowledge.document.buttons.rename')}}
                          </el-button>
                          <el-button
                              type="danger"
                              :icon="Delete"
                              text
                              class="action-btn"
                              @click="handleDelete(row)"
                          >
                              {{t('vabI18n.knowledge.document.buttons.delete')}}
                          </el-button>
                      </div>
                  </template>
              </el-table-column>
          </el-table>

          <!-- 分页 -->
          <div class="pagination-wrapper">
              <el-pagination
                  v-model:current-page="pagination.current"
                  v-model:page-size="pagination.size"
                  :page-sizes="[10, 20, 50, 100]"
                  :total="pagination.total"
                  layout="total, sizes, prev, pager, next, jumper"
                  @current-change="handlePaginationChange"
                  @size-change="handlePaginationChange"
              />
          </div>
      </div>
      </div>

      <!-- 上传文件对话框 - 使用新的DocUpload组件 -->
      <el-dialog
          v-model="uploadDialogVisible"
          :title="t('vabI18n.knowledge.document.buttons.upload')"
          width="900px"
          :close-on-click-modal="false"
          class="upload-dialog"
      >
          <DocUpload
              :visible="uploadDialogVisible"
              :dataset-id="datasetId"
              :parent-id="currentParentId"
              @update:visible="uploadDialogVisible = $event"
              @success="handleUploadSuccess"
          />
      </el-dialog>
      
      <!-- 文件替换对话框 -->
      <el-dialog 
          v-model="replaceDialogVisible" 
          title="替换文件" 
          width="900px" 
          :close-on-click-modal="false"
          class="upload-dialog"
      >
          <div v-if="replaceTargetFile" class="replace-info">
              <div class="target-file-info">
                  <h4>将要替换的文件：</h4>
                  <div class="file-info-card">
                      <img 
                          :src="getFileTypeIcon(replaceTargetFile.fileType)" 
                          alt="文件图标" 
                          class="file-icon"
                      />
                      <div class="file-details">
                          <div class="file-name">{{ replaceTargetFile.fileName }}</div>
                          <div class="file-meta">
                              <span>大小：{{ formatFileSize(replaceTargetFile.charCount) }}</span>
                              <span>创建时间：{{ replaceTargetFile.createDate }}</span>
                          </div>
                      </div>
                  </div>
              </div>
          </div>
          <DocUpload 
              :visible="replaceDialogVisible"
              :dataset-id="datasetId"
              :parent-id="currentParentId"
              :replace-file-id="replaceTargetFile?.id"
              @update:visible="replaceDialogVisible = $event"
              @success="handleReplaceSuccess"
          />
      </el-dialog>
      
      <!-- 预览抽屉 -->

    <el-drawer
      v-model="previewDrawerVisible"
      :title="t('vabI18n.knowledge.document.preview.title')"
      :direction="'rtl'"
      size="80%"
    class="preview-drawer"
    :close-on-click-modal="false"
      @close="handleClose"
    >
    <div v-loading="previewLoading" class="drawer-content-container" style="display: flex; height: 100%;">

      <!-- 左侧分段数据容器 -->
      <div class="segment-list-container" style="width: 30%; border-right: 1px solid #ebeef5; overflow-y: auto; padding: 10px;">
        <h3>分段数据</h3>
        <el-form v-if="segmentList.length > 0">
          <el-form-item
            v-for="(segment) in segmentList"
            :key="segment.id"
            style="cursor: pointer; margin-bottom: 5px;"
          >
            <span>分段{{segment.position}}：</span>
            <h4>{{segment.content}}</h4>
          </el-form-item>
        </el-form>
        <div v-else>
          暂无分段数据
        </div>
      </div>

      <!-- 右侧原预览内容 -->
      <div class="preview-content-container" style="flex: 1; padding: 10px; overflow-y: auto;">
        <!-- TXT 文件预览 -->
        <div v-if="previewFileType === 'txt'" class="text-preview-container">
          <pre class="text-preview">{{ previewTextContent }}</pre>
        </div>

        <!-- Markdown 文件预览 -->
        <div v-if="['md', 'markdown', 'mdx'].includes(previewFileType.toLowerCase())"
             class="markdown-preview-container">
          <div class="markdown-preview" v-html="previewMarkdownContent"></div>
        </div>

        <vue-office-pdf
          v-if="previewFileType === 'pdf'"
          :src="previewFileUrl"
          @rendered="renderedHandler"
          @error="errorHandler"
        />

        <vue-office-docx
          v-if="previewFileType == 'doc' || previewFileType == 'docx'"
          :src="previewFileUrl"
          @rendered="renderedHandler"
          @error="errorHandler"
        />

        <vue-office-excel
          v-if="previewFileType == 'xlsx' || previewFileType == 'xls' || previewFileType == 'csv'"
          :src="previewFileUrl"
          style="height: 100vh;"
          @rendered="renderedHandler"
          @error="errorHandler"
        />
      </div>
    </div>
    </el-drawer>


    <!-- 重命名对话框 -->
      <el-dialog
          v-model="renameDialogVisible"
          :title="t('vabI18n.knowledge.document.renameDialog.title')"
          width="480px"
          class="rename-dialog"
          :close-on-click-modal="false"
          align-center
      >
          <div class="dialog-content">
              <div class="dialog-icon">
                  <el-icon size="48" color="#409eff"><Edit /></el-icon>
              </div>
              <el-form :model="renameForm" label-width="0px" class="rename-form">
                  <el-form-item>
                      <div class="form-label">{{t('vabI18n.knowledge.document.renameDialog.label')}}</div>
                      <el-input
                          v-model="renameForm.newName"
                          :placeholder="t('vabI18n.knowledge.document.renameDialog.placeholder')"
                          size="large"
                          class="rename-input"
                          @keyup.enter="handleRenameConfirm"
                      >
                          <template #prefix>
                              <el-icon><Document /></el-icon>
                          </template>
                      </el-input>
              </el-form-item>
          </el-form>
          </div>
          <template #footer>
              <div class="dialog-footer">
                  <el-button size="large" @click="renameDialogVisible = false">
                      {{t('vabI18n.knowledge.document.renameDialog.cancel')}}
                  </el-button>
                  <el-button type="primary" size="large" @click="handleRenameConfirm">
                      <el-icon><Check /></el-icon>
                      {{t('vabI18n.knowledge.document.renameDialog.confirm')}}
                  </el-button>
              </div>
          </template>
      </el-dialog>

      <!-- 创建文件夹对话框 -->
      <el-dialog
          v-model="createFolderDialogVisible"
          :title="t('vabI18n.knowledge.document.createFolderDialog.title', '创建文件夹')"
          width="520px"
          class="create-folder-dialog"
          :close-on-click-modal="false"
          align-center
      >
          <div class="dialog-content">
              <div class="dialog-icon">
                  <el-icon size="48" color="#67c23a"><FolderAdd /></el-icon>
              </div>
              <el-form :model="createFolderForm" :rules="createFolderRules" ref="createFolderFormRef" label-width="0px" class="create-folder-form">
                  <el-form-item prop="folderName">
                      <div class="form-label">{{t('vabI18n.knowledge.document.createFolderDialog.label', '文件夹名称')}}</div>
                  <el-input
                      v-model="createFolderForm.folderName"
                      :placeholder="t('vabI18n.knowledge.document.createFolderDialog.placeholder', '请输入文件夹名称')"
                          size="large"
                          class="folder-name-input"
                      @keyup.enter="handleCreateFolderConfirm"
                      >
                          <template #prefix>
                              <el-icon><Folder /></el-icon>
                          </template>
                      </el-input>
              </el-form-item>
          </el-form>
          </div>
          <template #footer>
              <div class="dialog-footer">
                  <el-button size="large" @click="createFolderDialogVisible = false">
                      {{t('vabI18n.knowledge.document.createFolderDialog.cancel', '取消')}}
                  </el-button>
                  <el-button
                      type="primary"
                      size="large"
                      @click="handleCreateFolderConfirm"
                      :loading="createFolderLoading"
                  >
                      <el-icon><Plus /></el-icon>
                      {{t('vabI18n.knowledge.document.createFolderDialog.confirm', '创建')}}
                  </el-button>
              </div>
          </template>
      </el-dialog>

      <!-- 右键菜单 -->
      <transition name="context-menu-fade">
      <div
          v-if="contextMenuVisible"
          class="context-menu"
          :style="{ left: contextMenuPosition.x + 'px', top: contextMenuPosition.y + 'px' }"
          @click.stop
      >
              <div class="context-menu-header">
                  <div class="menu-title">操作菜单</div>
              </div>
          <div class="context-menu-item" @click="handleRefresh">
                  <div class="item-icon">
              <el-icon><Refresh /></el-icon>
                  </div>
                  <div class="item-content">
                      <div class="item-title">{{t('vabI18n.knowledge.document.contextMenu.refresh', '刷新')}}</div>
                      <div class="item-desc">刷新文件列表</div>
                  </div>
          </div>
          <div class="context-menu-item" @click="handleCreateFolderFromContext">
                  <div class="item-icon">
              <el-icon><FolderAdd /></el-icon>
          </div>
                  <div class="item-content">
                      <div class="item-title">{{t('vabI18n.knowledge.document.contextMenu.createFolder', '新建文件夹')}}</div>
                      <div class="item-desc">在当前目录创建文件夹</div>
      </div>
              </div>
          </div>
      </transition>

  </div>
</template>

<script setup lang="ts">
import { useRoute, useRouter } from 'vue-router'
import { ref, reactive, computed, onMounted, onUnmounted } from 'vue'
import VueOfficePdf from '@vue-office/pdf'
import { getDatasetDocPage, uploadDocument, deleteDocument, downloadDocument, previewDocumentUrl, renameDocument, createFolder, CreateFolderReq} from '@/api/dataset'
import {getSegmentList} from "@/api/Segment"
import DocUpload from './DocUpload.vue'
//引入VueOfficeDocx组件
import VueOfficeDocx from '@vue-office/docx'
//引入相关样式
import '@vue-office/docx/lib/index.css'
//引入VueOfficeExcel组件
import VueOfficeExcel from '@vue-office/excel'
//引入相关样式
import '@vue-office/excel/lib/index.css'


import VueOfficePptx from '@vue-office/pptx'

// 引入 markdown 解析器和代码高亮
import { marked } from 'marked'
import hljs from 'highlight.js'
import 'highlight.js/styles/github.css'

import { ElLoading, ElMessage, ElNotification, ElMessageBox } from 'element-plus'


import {
Search,
Refresh,
Upload,
Download,
View,
Edit,
Delete,
Check,
Close,
Loading,
Document,
InfoFilled,
ArrowLeft,
Folder,
FolderAdd,
House,
Plus
} from '@element-plus/icons-vue'
import { watch } from 'vue'
import { useI18n } from 'vue-i18n'
const { t, locale } = useI18n()



const userStore = useUserStore()
const aclStore = useAclStore()
const { token } = userStore

const route = useRoute();
const router = useRouter();
const datasetId = ref('');
const datasetName = ref('');
const previewLoading = ref(true)

const uploadDialogVisible = ref(false)
const replaceDialogVisible = ref(false)
const replaceTargetFile = ref<FileItem | null>(null)

// 重命名相关
const renameDialogVisible = ref(false)
const renameForm = reactive({
id: '',
newName: ''
})

// 创建文件夹相关
const createFolderDialogVisible = ref(false)
const createFolderLoading = ref(false)
const createFolderFormRef = ref()
const createFolderForm = reactive({
folderName: ''
})

// 表单验证规则
const createFolderRules = {
folderName: [
  { required: true, message: t('vabI18n.knowledge.document.createFolderDialog.rules.nameRequired', '文件夹名称不能为空'), trigger: 'blur' },
  { max: 50, message: t('vabI18n.knowledge.document.createFolderDialog.rules.nameMaxLength', '文件夹名称不能超过50个字符'), trigger: 'blur' },
  { pattern: /^[^<>:"/\\|?*]+$/, message: t('vabI18n.knowledge.document.createFolderDialog.rules.namePattern', '文件夹名称不能包含特殊字符'), trigger: 'blur' }
]
}
const segmentList= ref([])
// 右键菜单相关
const contextMenuVisible = ref(false)
const contextMenuPosition = reactive({
x: 0,
y: 0
})

// 面包屑导航相关
const currentParentId = ref<number | undefined>(undefined)
const breadcrumbPath = ref<Array<{id: number, name: string}>>([])

// 面包屑导航项接口
interface BreadcrumbItem {
id: number;
name: string;
}



const handleClose = () => {
  uploadDialogVisible.value = false
  segmentList.value = []
}


// 组件卸载时清理
onUnmounted(() => {
// 清理右键菜单事件监听器
document.removeEventListener('click', hideContextMenu)
// 停止自动刷新定时器
stopAutoRefresh()
})

const getFileTypeIcon = (fileType: string) => {
  const icons = require.context('@/assets/img/filetype-icon', false, /\.png$/)
  // console.log(icons)
  // console.log('所有图标 keys:', icons.keys())

  const getIconUrl = (iconName: string) => {
    const fullName = `./${iconName}.png`
    if (icons.keys().includes(fullName)) {
      return icons(fullName)
    } else {
      // console.warn('图标不存在:', fullName)
      return ''
    }
  }

const iconMap: Record<string, string> = {
  'pdf': getIconUrl('pdf'),
  'doc': getIconUrl('word'),
  'docx': getIconUrl('word'),
  'xls': getIconUrl('excel'),
  'xlsx': getIconUrl('excel'),
  'ppt': getIconUrl('ppt'),
  'pptx': getIconUrl('ppt'),
  'txt': getIconUrl('txt'),
  'md': getIconUrl('txt'),
  'markdown': getIconUrl('txt'),
  'mdx': getIconUrl('txt'),
  'html': getIconUrl('txt'),
  'htm': getIconUrl('txt'),
  'csv': getIconUrl('excel'),
  'vtt': getIconUrl('txt'),
  'properties': getIconUrl('txt'),
  'xml': getIconUrl('xml'),
  'zip': getIconUrl('zip'),
  'mp4': getIconUrl('video'),
  'avi': getIconUrl('video'),
  'mp3': getIconUrl('audio'),
  'wav': getIconUrl('audio'),
  'jpg': getIconUrl('img'),
  'jpeg': getIconUrl('img'),
  'png': getIconUrl('img'),
  'gif': getIconUrl('img'),
}
return iconMap[fileType.toLowerCase()] || getIconUrl('unknown')
}

// 多选相关
const selectedRows = ref<FileItem[]>([])

interface FileItem {
id: string
fileName: string
fileType: string
parseStatus: string
previewConvert?: string
size?: string
charCount: number
createDate: string
status: string
// 新增字段，适配TDatasetFiles
type: string // file-文件, folder-文件夹
parentId?: number
path: string
mimeType?: string
difyDocId?: string
difyStoragePath?: string
sourceUrl?: string // 新增：文档源URL，用于下载和预览
}

// 搜索关键词
const searchKeyword = ref('')

// 分页数据
const pagination = reactive({
current: 1,
size: 20,
total: 0
})

// 排序数据
const sortConfig = reactive({
orderBy: 'name',
orderDirection: 'ASC'
})

// 文件列表数据
const fileList = ref<FileItem[]>([])


//预览右抽屉状态
const previewDrawerVisible = ref(false)
const previewFileType = ref('')
const previewFileUrl = ref('')
// 添加文本内容预览状态
const previewTextContent = ref('')
const previewMarkdownContent = ref('')

// 选择变化处理
const handleSelectionChange = (selection: FileItem[]) => {
selectedRows.value = selection
}

// 批量删除处理
const handleBatchDelete = async () => {
if (selectedRows.value.length === 0) {
  ElMessage.warning(t('vabI18n.knowledge.document.messages.noFileSelected'))
  return
}

try {
  await ElMessageBox.confirm(
  t('vabI18n.knowledge.document.messages.batchDeleteConfirm', {
    count: selectedRows.value.length
  }),
  t('vabI18n.knowledge.document.messages.deleteConfirmTitle'),
  {
    confirmButtonText: t('vabI18n.knowledge.document.buttons.confirm'),
    cancelButtonText: t('vabI18n.knowledge.document.buttons.cancel'),
    type: 'warning'
  }
)

  const handleClose = () => {
    previewDrawerVisible.value = false,
      segmentList.value = []
  }
  const loading = ElLoading.service({
    lock: true,
    text: t('vabI18n.knowledge.document.messages.deleteing'),
    background: 'rgba(0, 0, 0, 0.7)'
  })

  try {
    // 批量删除
    for (const row of selectedRows.value) {
      await deleteDocument(parseInt(row.id))
    }

    ElNotification({
      title: t('vabI18n.knowledge.document.messages.deleteSuccessOk'),
      message: t('vabI18n.knowledge.document.messages.batchDeleteSuccess') + ` ${selectedRows.value.length} ` + t('vabI18n.knowledge.document.messages.batchDeleteSuccessEnd'),
      type: 'success'
    })

    // 清空选择
    selectedRows.value = []
    // 刷新文件列表
    await fetchDocuments()
  } finally {
    loading.close()
  }
} catch (error) {
  console.error('批量删除失败:', error)
  ElNotification({
    title: t('vabI18n.knowledge.document.errors.deleteFailed'),
    message: error instanceof Error ? error.message : t('vabI18n.knowledge.document.messages.deleteFailed'),
    type: 'error'
  })
}
}

const originalExtension = ref('')
// 重命名处理
const handleRename = (row: FileItem) => {
renameForm.id = row.id
const parts = row.fileName.split('.')
if (parts.length > 1) {
  originalExtension.value = parts.pop()!
  renameForm.newName = parts.join('.')
} else {
  originalExtension.value = ''
renameForm.newName = row.fileName
}

renameDialogVisible.value = true
}

// 重命名确认
const handleRenameConfirm = async () => {

const newName = (originalExtension.value
  ? renameForm.newName.trim() + '.' + originalExtension.value
  : renameForm.newName.trim())

if (!newName || newName === '.') {
  ElMessage.warning(t('vabI18n.knowledge.document.messages.FilenamecantEmpty'))
  return
}

try {
  await renameDocument({
    fileId: parseInt(renameForm.id),
    newName: newName
})
  ElNotification({
    title: t('vabI18n.knowledge.document.errors.renameSuccess'),
    message: t('vabI18n.knowledge.document.messages.renameSuccess'),
    type: 'success'
  })

  renameDialogVisible.value = false
  await fetchDocuments()
} catch (error) {
  ElNotification({
    title: t('vabI18n.knowledge.document.errors.renameFailed'),
    message: t('vabI18n.knowledge.document.messages.renameFailed'),
    type: 'error'
  })
}
}


// 数字格式化
const formatNumber = (num: number) => {
return num.toLocaleString()
}

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

// 处理取消上传
// 监听预览抽屉关闭事件，清理预览内容
watch(previewDrawerVisible, (newVal) => {
if (!newVal) {
  previewTextContent.value = ''
  previewMarkdownContent.value = ''
  previewFileUrl.value = ''
  previewFileType.value = ''
}
})

import { useUserStore } from '@/store/modules/user'
import { useAclStore } from '@/store/modules/acl'
import vab from '~/library/plugins/vab'

// 事件处理函数
const renderedHandler = () => {
previewLoading.value = false
console.log("渲染完成")
}

const errorHandler = () => {
previewLoading.value = false
console.log("渲染失败")
}

const triggerFileInput = () => {
  uploadDialogVisible.value = true
}

// 文件替换处理 - 从行操作触发
const handleFileReplaceFromRow = (row: FileItem) => {
  replaceTargetFile.value = row
  replaceDialogVisible.value = true
}

const indexMethod = (index: number) => {
return (pagination.current - 1) * pagination.size + index + 1
}



// 处理DocUpload组件的上传成功回调
const handleUploadSuccess = async () => {
uploadDialogVisible.value = false
await fetchDocuments()
// ElNotification({
//   title: t('vabI18n.knowledge.document.messages.uploadSuccess'),
//   message: t('vabI18n.knowledge.document.messages.uploadSuccessEnd'),
//   type: 'success'
// })
}

// 处理文件替换成功回调
const handleReplaceSuccess = async () => {
replaceDialogVisible.value = false
replaceTargetFile.value = null
selectedRows.value = [] // 清空选择
await fetchDocuments()
ElNotification({
  title: '替换成功',
  message: '文件替换成功',
  type: 'success'
})
}

//文件下载
const handleDownload = async (row: FileItem) => {
try {
    // 使用新的API下载方式，传入fileId（数字类型）
    const response = await downloadDocument(parseInt(row.id))

    // 创建 Blob 对象
    const blob = new Blob([response.data], { type: 'application/octet-stream' })

    // 创建下载链接
    const url = window.URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.href = url
    link.download = row.fileName // 使用文件原始名称
    link.style.display = 'none'
    document.body.appendChild(link)
    link.click()

    // 清理
    document.body.removeChild(link)
    window.URL.revokeObjectURL(url)

} catch (error) {
  ElNotification({
    title: t('vabI18n.knowledge.document.errors.downloadFailed'),
    message: error instanceof Error ? error.message : t('vabI18n.knowledge.document.messages.NoKnowError'),
    type: 'error'
  })
}
}

//获取预览路径
const fetchPreviewUrl = async (fileId: number) => {
const response = await previewDocumentUrl(fileId)
console.log("response",response)
return response.data
}

// 获取文件文本内容（用于txt和markdown预览）
const fetchFileContent = async (fileId: number, fileType: string) => {
try {
  // 对于txt和markdown文件，我们需要获取原始文本内容
  // 这里可以通过下载接口获取文件内容，然后转为文本
  const response = await downloadDocument(fileId)

  // 将响应数据转为文本
  if (response.data instanceof Blob) {
    const text = await response.data.text()
    return text
  } else if (typeof response.data === 'string') {
    return response.data
  } else {
    return JSON.stringify(response.data)
  }
} catch (error) {
  console.error('获取文件内容失败:', error)
  throw error
}
}

const handlePreview = async (row: FileItem) => {
  // 显示抽屉
  previewDrawerVisible.value = true
  previewLoading.value = true

  previewFileType.value = row.fileType;

  try {
      // 对于txt和markdown文件，获取文本内容
      if (['txt', 'md', 'markdown', 'mdx'].includes(row.fileType.toLowerCase())) {
          const content = await fetchFileContent(parseInt(row.id), row.fileType)

          if (row.fileType.toLowerCase() === 'txt') {
              previewTextContent.value = content
          } else if (['md', 'markdown', 'mdx'].includes(row.fileType.toLowerCase())) {
              // 配置并解析 markdown
              const renderer = new marked.Renderer()

              marked.setOptions({
                  breaks: true,
                  gfm: true
              })


              previewMarkdownContent.value = marked.parse(content) as string
          }
      } else {
          // 优先使用sourceUrl进行预览
          if (row.sourceUrl) {
              previewFileUrl.value = row.sourceUrl
              console.log("previewFileUrl (from sourceUrl)", previewFileUrl.value)
          } else {
              // 兜底：使用新的API获取预览URL
              previewFileUrl.value = await fetchPreviewUrl(parseInt(row.id))
              console.log("previewFileUrl (from API)", previewFileUrl.value)
          }
      }
    const resp = await getSegmentList({
      datasetId:datasetId.value,
      documentId: row.difyDocId
    })
    if (resp.data?.length) {
      segmentList.value = resp.data
    }
  } catch (error) {
      ElNotification({
          title: t('vabI18n.knowledge.document.errors.previewFailed'),
          message: error instanceof Error ? error.message : t('vabI18n.knowledge.document.messages.getFileContentFailed'),
          type: 'error'
      })
  } finally {
      previewLoading.value = false
  }
}



// 在script setup部分添加loading状态
const tableLoading = ref(false)

// 定时器相关
const refreshTimer = ref<NodeJS.Timeout | null>(null)

// 启动定时器
const startAutoRefresh = () => {
  stopAutoRefresh() // 先清除可能存在的定时器
  refreshTimer.value = setInterval(() => {
    // 只有在非加载状态下才自动刷新
    if (!tableLoading.value) {
      fetchDocuments()
    }
  }, 30000) // 5秒刷新一次
}

// 停止定时器
const stopAutoRefresh = () => {
  if (refreshTimer.value) {
    clearInterval(refreshTimer.value)
    refreshTimer.value = null
  }
}

// 修改fetchDocuments函数
const fetchDocuments = async () => {
tableLoading.value = true
try {
  const params = {
    difyDatasetId: datasetId.value,
    parentId: currentParentId.value, // 使用当前文件夹ID
    fileName: searchKeyword.value || undefined,
    orderBy: sortConfig.orderBy,
    orderDirection: sortConfig.orderDirection,
    pageNo: pagination.current,
    pageSize: pagination.size
  }

  const { data } = await getDatasetDocPage(params)

  // 映射API数据到表格结构，适配新的TDatasetFiles字段
  fileList.value = data.content.map((item: any) => ({
    id: item.id,
    fileName: item.name,
    parseStatus: formatIndexStatus(item.indexingStatus),
    fileType: item.extension?.replace('.', '').toLowerCase() || item.name.split('.').pop()?.toLowerCase() || '',
    charCount: item.size || 0, // 使用文件大小，如果有字符数可以后续添加
    createDate: formatTimestamp(Math.floor(new Date(item.createdAt).getTime() / 1000)),
    status: item.indexingStatus,
    // 新增字段
    type: item.type,
    parentId: item.parentId,
    path: item.path,
    mimeType: item.mimeType,
    difyDocId: item.difyDocId,
    difyStoragePath: item.difyStoragePath,
    sourceUrl: item.sourceUrl // 新增：映射sourceUrl字段
  }))

  pagination.total = data.total
  pagination.current = data.pageNo

} catch (error) {
  console.error('获取文档列表失败:', error)
  ElNotification({
    title: t('vabI18n.knowledge.document.errors.fetchFailed'),
    message: error instanceof Error ? error.message : t('vabI18n.knowledge.document.messages.NoKnowError'),
    type: 'error'
  })
} finally {
  tableLoading.value = false
}
}

// 添加刷新方法
const handleRefresh = () => {
searchKeyword.value = ''
pagination.current = 1
selectedRows.value = []
fetchDocuments()
}

// 返回知识库列表
const handleGoBack = () => {
router.push('/datasets')
}

const formatTimestampToLocaleString = (timestamp: number): string => {
const date = new Date(timestamp * 1000)
return date.toLocaleString()
}

// 工具函数
const formatTimestamp = (timestamp: number): string => {
const date = new Date(timestamp * 1000)
return date.toLocaleDateString('zh-CN') + ' ' + date.toLocaleTimeString('zh-CN')
}

const formatIndexStatus = (status: string): string => {
const statusMap: Record<string, string> = {
  'preprocessing': '预处理',
  'indexing': '解析中',
  'waiting': '等待中',
  'queued': '排队中',
  'failed': '解析失败',
  'completed': '解析成功'
}
return statusMap[status] || '未知状态'
}

// 获取状态对应的标签类型
const getStatusTagType = (status: string): 'success' | 'primary' | 'warning' | 'info' | 'danger' => {
const typeMap: Record<string, 'success' | 'primary' | 'warning' | 'info' | 'danger'> = {
  'preprocessing': 'info',
  'indexing': 'warning',
  'waiting': 'info',
  'queued': 'info', // 修改为info类型，显示较深灰色
  'failed': 'danger',
  'completed': 'success'
}
return typeMap[status] || 'info'
}

// 获取状态对应的图标
const getStatusIcon = (status: string) => {
const iconMap: Record<string, any> = {
  'preprocessing': Loading,
  'indexing': Loading,
  'waiting': Loading,
  'queued': Loading,
  'failed': Close,
  'completed': Check
}
return iconMap[status] || InfoFilled
}

const handleDelete = async (row: FileItem) => {
try {
  // 确认对话框
  await ElMessageBox.confirm(t('vabI18n.knowledge.document.messages.deleteConfirm'), t('vabI18n.knowledge.deleteConfirm.title'), {
    confirmButtonText: t('vabI18n.knowledge.deleteConfirm.confirm'),
    cancelButtonText: t('vabI18n.knowledge.deleteConfirm.cancel'),
    type: 'warning'
  })

  // 调用删除接口
  await deleteDocument(parseInt(row.id))

  // 成功处理
  ElNotification({
    title: t('vabI18n.knowledge.document.messages.deleteSuccessOk'),
    message: `${t('vabI18n.knowledge.document.messages.deleteSuccess')}"${row.fileName}"${t('vabI18n.knowledge.document.messages.deleteSuccessEnd')}`,
    type: 'success'
  })

  // 刷新文件列表
  await fetchDocuments()
} catch (error) {
  console.error('删除文件失败:', error)
  ElNotification({
    title: t('vabI18n.knowledge.document.errors.deleteFailed'),
    message: error instanceof Error ? error.message : t('vabI18n.knowledge.document.messages.NoKnowError'),
    type: 'error'
  })
}
}

onMounted(async () => {
datasetId.value = route.params.id as string
datasetName.value  = route.query.name as string
// 这里可以调用API获取详细数据
await fetchDocuments()
// 启动自动刷新定时器
startAutoRefresh()
})

// 分页变化处理
const handlePaginationChange = () => {
fetchDocuments()
}

// 搜索处理
const handleSearch = () => {
pagination.current = 1
fetchDocuments()
}

// 排序变化处理
const handleSortChange = (sortInfo: any) => {
  if (sortInfo.prop && sortInfo.order) {
    // 映射前端字段到后端字段
    const fieldMapping: Record<string, string> = {
      'fileName': 'name',
      'createDate': 'created_at',
      'charCount': 'size'
    }
    
    sortConfig.orderBy = fieldMapping[sortInfo.prop] || sortInfo.prop
    sortConfig.orderDirection = sortInfo.order === 'ascending' ? 'ASC' : 'DESC'
    
    // 重置到第一页并刷新数据
    pagination.current = 1
    fetchDocuments()
  }
}

// 处理文件夹打开
const handleOpenFolder = (row: FileItem) => {
// 设置当前文件夹ID并更新面包屑路径
currentParentId.value = parseInt(row.id)
breadcrumbPath.value.push({
  id: parseInt(row.id),
  name: row.fileName
})

// 重置分页到第一页
pagination.current = 1
// 刷新文件列表
fetchDocuments()
}

// 表格行双击处理
const handleRowDoubleClick = (row: FileItem) => {
if (row.type === 'folder') {
  handleOpenFolder(row)
} else if (row.type === 'file' && row.status === 'completed') {
  // 如果是文件且状态为已完成，则预览
  handlePreview(row)
}
}

// 面包屑导航处理
const navigateToRoot = () => {
currentParentId.value = undefined
breadcrumbPath.value = []
pagination.current = 1
fetchDocuments()
}

const navigateToFolder = (folder: BreadcrumbItem, index: number) => {
// 如果点击的不是最后一个面包屑项，则导航到该文件夹
if (index < breadcrumbPath.value.length - 1) {
  currentParentId.value = folder.id
  breadcrumbPath.value = breadcrumbPath.value.slice(0, index + 1)
  pagination.current = 1
  fetchDocuments()
}
}

// 右键菜单处理
const handleRightClick = (event: MouseEvent) => {
// 只在空白区域右键时显示菜单
const target = event.target as HTMLElement
if (target.closest('.el-table') || target.closest('.action-bar')) {
  return
}

contextMenuPosition.x = event.clientX
contextMenuPosition.y = event.clientY
contextMenuVisible.value = true

// 监听点击事件来隐藏菜单
document.addEventListener('click', hideContextMenu)
}

const hideContextMenu = () => {
contextMenuVisible.value = false
document.removeEventListener('click', hideContextMenu)
}

// 从右键菜单创建文件夹
const handleCreateFolderFromContext = () => {
hideContextMenu()
createFolderForm.folderName = ''
createFolderDialogVisible.value = true
}

// 创建文件夹确认
const handleCreateFolderConfirm = async () => {
if (!createFolderFormRef.value) return

try {
  await createFolderFormRef.value.validate()
} catch {
  return
}

createFolderLoading.value = true

try {
  const folderData: CreateFolderReq = {
    datasetId: datasetId.value,
    folderName: createFolderForm.folderName,
    parentId: currentParentId.value, // 在当前目录下创建文件夹
    ownerId: aclStore.getUserId || 1 // 从acl store获取用户ID
  }

  await createFolder(folderData)

  ElNotification({
    title: t('vabI18n.knowledge.document.messages.createFolderSuccess', '创建成功'),
    message: t('vabI18n.knowledge.document.messages.createFolderSuccessMessage', `文件夹"${createFolderForm.folderName}"创建成功`),
    type: 'success'
  })

  createFolderDialogVisible.value = false
  createFolderForm.folderName = ''

  // 刷新文件列表
  await fetchDocuments()
} catch (error) {
  console.error('创建文件夹失败:', error)
  ElNotification({
    title: t('vabI18n.knowledge.document.errors.createFolderFailed', '创建失败'),
    message: error instanceof Error ? error.message : t('vabI18n.knowledge.document.messages.createFolderFailed', '创建文件夹失败'),
    type: 'error'
  })
} finally {
  createFolderLoading.value = false
}
}
</script>

<style lang="scss" scoped>
.main-container {
padding: 20px;
background: #f5f7fa;
min-height: 100vh;
}

.page-header {
margin-bottom: 24px;

.header-top {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 8px;

  .back-button {
    color: #409eff;
    font-size: 14px;
    padding: 8px 12px;

    &:hover {
      background-color: #ecf5ff;
      color: #337ecc;
    }
  }
}

.page-title {
  font-size: 24px;
  font-weight: 600;
  color: #303133;
  margin: 0;
}

.page-description {
  font-size: 14px;
  color: #909399;
  margin: 0;
}

.breadcrumb-container {
  margin: 12px 0;

  .breadcrumb-clickable {
    cursor: pointer;

    &:hover {
      color: #409eff;
    }
  }

  ::v-deep .el-breadcrumb__inner {
    display: flex;
    align-items: center;
    gap: 4px;

    &.is-link:hover {
      color: #409eff;
    }
  }

  ::v-deep .el-breadcrumb__item:last-child .el-breadcrumb__inner {
    color: #303133;
    font-weight: 500;
  }
}
}

// 内容布局样式
.content-layout {
display: flex;
gap: 20px;
position: relative;
transition: all 0.3s ease;
}



.file-manager-container {
background: white;
border-radius: 8px;
padding: 24px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
}

.action-bar {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
padding-bottom: 16px;
border-bottom: 1px solid #ebeef5;
}

.left-group {
display: flex;
align-items: center;
gap: 12px;
}

.search-input {
width: 280px;
}

.right-group {
display: flex;
align-items: center;
gap: 12px;
}

.batch-delete-btn {
animation: fadeIn 0.3s ease-in-out;
}

@keyframes fadeIn {
from { opacity: 0; transform: translateX(-10px); }
to { opacity: 1; transform: translateX(0); }
}

@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}

@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.05); }
100% { transform: scale(1); }
}

@keyframes bounce {
0%, 20%, 50%, 80%, 100% { transform: translateY(0); }
40% { transform: translateY(-10px); }
60% { transform: translateY(-5px); }
}

.file-table {
border-radius: 8px;
overflow: hidden;
box-shadow: 0 1px 6px rgba(0, 0, 0, 0.1);

::v-deep .el-table__header {
  background: #fafafa;
}

::v-deep .el-table__header th {
  background: #fafafa;
  color: #606266;
  font-weight: 600;
  border-bottom: 2px solid #e4e7ed;
  height: 50px;
}

::v-deep .el-table__body tr {
  transition: all 0.2s ease;

  &:hover {
    background: #f5f7fa !important;
  }
}

::v-deep .el-table__body td {
  height: 50px;
  border-bottom: 1px solid #ebeef5;
}
}

.file-name-cell {
display: flex;
align-items: center;
gap: 10px;

.file-icon {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  object-fit: contain;
}

.folder-icon {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

.file-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 500;
}
}

.char-count {
font-family: 'Consolas', 'Monaco', monospace;
font-weight: 500;
}

.action-buttons {
display: flex;
align-items: center;
gap: 4px;
flex-wrap: nowrap;

.action-btn {
  font-size: 12px;
  padding: 4px 6px;
  border-radius: 4px;
  transition: all 0.2s ease;
  white-space: nowrap;
  flex-shrink: 0;

  &:hover:not(.disabled-btn) {
    transform: translateY(-1px);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
  }

  &.disabled-btn {
    color: #c0c4cc !important;
    cursor: not-allowed !important;
    background: transparent !important;
    border-color: transparent !important;

    &:hover {
      transform: none !important;
      box-shadow: none !important;
      color: #c0c4cc !important;
      background: transparent !important;
    }
  }
}
}

.pagination-wrapper {
margin-top: 24px;
display: flex;
justify-content: flex-end;
padding-top: 16px;
border-top: 1px solid #ebeef5;
}

// 上传对话框样式
.upload-dialog {
::v-deep .el-dialog {
  border-radius: 16px;
  overflow: hidden;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.15);
}

::v-deep .el-dialog__header {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  border-radius: 0;
  padding: 24px 32px;
}

::v-deep .el-dialog__title {
  color: white;
  font-weight: 600;
  font-size: 20px;
}

::v-deep .el-dialog__close {
  color: white;
  font-size: 20px;

  &:hover {
    color: rgba(255, 255, 255, 0.8);
    transform: scale(1.1);
  }
}

::v-deep .el-dialog__body {
  padding: 32px;
  background: #fafbfc;
}

::v-deep .el-dialog__footer {
  padding: 20px 32px 32px;
  background: #fafbfc;
  border-top: 1px solid #e9ecef;
}
}

// 重命名对话框样式
.rename-dialog {
::v-deep .el-dialog {
  border-radius: 20px;
  overflow: hidden;
  box-shadow: 0 25px 80px rgba(64, 158, 255, 0.15);
  backdrop-filter: blur(10px);
}

::v-deep .el-dialog__header {
  background: linear-gradient(135deg, #409eff 0%, #36cfc9 100%);
  color: white;
  border-radius: 0;
  padding: 24px 32px;
  text-align: center;
}

::v-deep .el-dialog__title {
  color: white;
  font-weight: 700;
  font-size: 20px;
  letter-spacing: 0.5px;
}

::v-deep .el-dialog__close {
  color: white;
  font-size: 20px;

  &:hover {
    color: rgba(255, 255, 255, 0.8);
    transform: scale(1.1) rotate(90deg);
    transition: all 0.3s ease;
  }
}

::v-deep .el-dialog__body {
  padding: 40px 32px 32px;
  background: linear-gradient(135deg, #f8fbff 0%, #f0f9ff 100%);
}

.dialog-content {
  text-align: center;

  .dialog-icon {
    margin-bottom: 24px;
    animation: pulse 2s infinite;
  }

  .rename-form {
    .form-label {
      font-size: 16px;
      font-weight: 600;
      color: #303133;
      margin-bottom: 16px;
      text-align: left;
    }

    .rename-input {
      ::v-deep .el-input__wrapper {
        border-radius: 12px;
        box-shadow: 0 4px 12px rgba(64, 158, 255, 0.1);
        border: 2px solid transparent;
        transition: all 0.3s ease;

        &:hover {
          box-shadow: 0 6px 16px rgba(64, 158, 255, 0.15);
        }

        &.is-focus {
          border-color: #409eff;
          box-shadow: 0 8px 20px rgba(64, 158, 255, 0.2);
        }
      }
    }
  }
}

.dialog-footer {
  display: flex;
  justify-content: center;
  gap: 16px;
  padding: 20px 0;
  background: linear-gradient(135deg, #f8fbff 0%, #f0f9ff 100%);

  .el-button {
    border-radius: 12px;
    padding: 12px 24px;
    font-weight: 600;
    transition: all 0.3s ease;

    &:hover {
      transform: translateY(-2px);
      box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1);
    }

    &.el-button--primary {
      background: linear-gradient(135deg, #409eff 0%, #36cfc9 100%);
      border: none;

      &:hover {
        background: linear-gradient(135deg, #337ecc 0%, #2bb0a8 100%);
      }
    }
  }
}
}

// 创建文件夹对话框样式
.create-folder-dialog {
::v-deep .el-dialog {
  border-radius: 20px;
  overflow: hidden;
  box-shadow: 0 25px 80px rgba(103, 194, 58, 0.15);
  backdrop-filter: blur(10px);
}

::v-deep .el-dialog__header {
  background: linear-gradient(135deg, #67c23a 0%, #85ce61 100%);
  color: white;
  border-radius: 0;
  padding: 24px 32px;
  text-align: center;
}

::v-deep .el-dialog__title {
  color: white;
  font-weight: 700;
  font-size: 20px;
  letter-spacing: 0.5px;
}

::v-deep .el-dialog__close {
  color: white;
  font-size: 20px;

  &:hover {
    color: rgba(255, 255, 255, 0.8);
    transform: scale(1.1) rotate(90deg);
    transition: all 0.3s ease;
  }
}

::v-deep .el-dialog__body {
  padding: 40px 32px 32px;
  background: linear-gradient(135deg, #f6ffed 0%, #f0f9ff 100%);
}

.dialog-content {
  text-align: center;

  .dialog-icon {
    margin-bottom: 24px;
    animation: bounce 2s infinite;
  }

  .create-folder-form {
    .form-label {
      font-size: 16px;
      font-weight: 600;
      color: #303133;
      margin-bottom: 16px;
      text-align: left;
    }

    .folder-name-input {
      ::v-deep .el-input__wrapper {
        border-radius: 12px;
        box-shadow: 0 4px 12px rgba(103, 194, 58, 0.1);
        border: 2px solid transparent;
        transition: all 0.3s ease;

        &:hover {
          box-shadow: 0 6px 16px rgba(103, 194, 58, 0.15);
        }

        &.is-focus {
          border-color: #67c23a;
          box-shadow: 0 8px 20px rgba(103, 194, 58, 0.2);
        }
      }
    }
  }
}

.dialog-footer {
  display: flex;
  justify-content: center;
  gap: 16px;
  padding: 20px 0;
  background: linear-gradient(135deg, #f6ffed 0%, #f0f9ff 100%);

  .el-button {
    border-radius: 12px;
    padding: 12px 24px;
    font-weight: 600;
    transition: all 0.3s ease;

    &:hover {
      transform: translateY(-2px);
      box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1);
    }

    &.el-button--primary {
      background: linear-gradient(135deg, #67c23a 0%, #85ce61 100%);
      border: none;

      &:hover {
        background: linear-gradient(135deg, #529e2b 0%, #6cb33f 100%);
      }
    }
  }
}
}




// 文件替换信息样式
.replace-info {
margin-bottom: 24px;
padding: 20px;
background: #f8f9fa;
border-radius: 8px;
border-left: 4px solid #e6a23c;

.target-file-info {
  h4 {
    margin: 0 0 16px 0;
    color: #303133;
    font-size: 16px;
    font-weight: 600;
  }
  
  .file-info-card {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 16px;
    background: white;
    border-radius: 6px;
    border: 1px solid #ebeef5;
    
    .file-icon {
      width: 32px;
      height: 32px;
      flex-shrink: 0;
      object-fit: contain;
    }
    
    .file-details {
      flex: 1;
      
      .file-name {
        font-size: 14px;
        font-weight: 600;
        color: #303133;
        margin-bottom: 4px;
      }
      
      .file-meta {
        display: flex;
        gap: 16px;
        font-size: 12px;
        color: #909399;
        
        span {
          &:not(:last-child)::after {
            content: '•';
            margin-left: 8px;
            color: #dcdfe6;
          }
        }
      }
    }
  }
}
}

// 预览抽屉样式
.preview-drawer {
::v-deep .el-drawer__header {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border-bottom: none;
  margin-bottom: 0;
  padding: 24px 32px;
  color: white;
  box-shadow: 0 4px 20px rgba(102, 126, 234, 0.15);

  .el-drawer__title {
    font-weight: 700;
    color: white;
    font-size: 18px;
    letter-spacing: 0.5px;
  }

  .el-drawer__close-btn {
    color: white;
    font-size: 20px;

    &:hover {
      color: rgba(255, 255, 255, 0.8);
      transform: scale(1.1);
    }
  }
}

::v-deep .el-drawer__body {
  background: #fafbfc;
  padding: 0;
}
}

// TXT 文件预览样式
.text-preview-container {
height: 100%;
overflow: auto;
padding: 20px;
background: #fafafa;

.text-preview {
  font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
  font-size: 14px;
  line-height: 1.6;
  color: #303133;
  background: white;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  padding: 16px;
  margin: 0;
  white-space: pre-wrap;
  word-wrap: break-word;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
}

// Markdown 文件预览样式
.markdown-preview-container {
height: 100%;
overflow: auto;
padding: 20px;
background: #fafafa;

.markdown-preview {
  background: white;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  padding: 24px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);

  // Markdown 内容样式
  h1, h2, h3, h4, h5, h6 {
    margin-top: 0;
    margin-bottom: 16px;
    font-weight: 600;
    line-height: 1.25;
    color: #24292e;
  }

  h1 {
    font-size: 2em;
    border-bottom: 1px solid #eaecef;
    padding-bottom: 0.3em;
  }

  h2 {
    font-size: 1.5em;
    border-bottom: 1px solid #eaecef;
    padding-bottom: 0.3em;
  }

  h3 {
    font-size: 1.25em;
  }

  p {
    margin-bottom: 16px;
    line-height: 1.6;
    color: #24292e;
  }

  ul, ol {
    padding-left: 2em;
    margin-bottom: 16px;
  }

  li {
    margin-bottom: 0.25em;
  }

  blockquote {
    padding: 0 1em;
    color: #6a737d;
    border-left: 0.25em solid #dfe2e5;
    margin: 0 0 16px 0;
  }

  code {
    padding: 0.2em 0.4em;
    margin: 0;
    font-size: 85%;
    background-color: rgba(27, 31, 35, 0.05);
    border-radius: 3px;
    font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
  }

  pre {
    padding: 16px;
    overflow: auto;
    font-size: 85%;
    line-height: 1.45;
    background-color: #f6f8fa;
    border-radius: 6px;
    margin-bottom: 16px;

    code {
      display: inline;
      max-width: auto;
      padding: 0;
      margin: 0;
      overflow: visible;
      line-height: inherit;
      word-wrap: normal;
      background-color: transparent;
      border: 0;
    }
  }

  table {
    border-spacing: 0;
    border-collapse: collapse;
    margin-bottom: 16px;
    width: 100%;
    overflow: auto;

    th, td {
      padding: 6px 13px;
      border: 1px solid #dfe2e5;
    }

    th {
      font-weight: 600;
      background-color: #f6f8fa;
    }

    tr:nth-child(2n) {
      background-color: #f6f8fa;
    }
  }

  img {
    max-width: 100%;
    height: auto;
    border-radius: 4px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  }

  a {
    color: #0366d6;
    text-decoration: none;

    &:hover {
      text-decoration: underline;
    }
  }

  hr {
    height: 0.25em;
    padding: 0;
    margin: 24px 0;
    background-color: #e1e4e8;
    border: 0;
  }
}
}

// 状态标签动画
::v-deep .el-tag {
transition: all 0.3s ease;

.el-icon {
  margin-right: 4px;
}

&.rotating-tag .el-icon.is-loading {
  animation: spin 1s linear infinite;
}

// 不同状态的标签样式
&[type="info"] {
  background-color: #f4f4f5;
  border-color: #d3d4d6;
  color: #909399;
}

&[type="warning"] {
  background-color: #fdf6ec;
  border-color: #f5dab1;
  color: #e6a23c;
}

&[type="success"] {
  background-color: #f0f9ff;
  border-color: #b3d8ff;
  color: #67c23a;
}

&[type="danger"] {
  background-color: #fef0f0;
  border-color: #fbc4c4;
  color: #f56c6c;
}
}

// 深度解析对话框样式
.deep-analysis-dialog {
::v-deep .el-dialog__header {
  background: linear-gradient(135deg, #409eff 0%, #67c23a 100%);
  color: white;
  border-radius: 8px 8px 0 0;
}

::v-deep .el-dialog__title {
  color: white;
  font-weight: 600;
}
}

// 任务统计样式
.task-statistics {
display: flex;
gap: 24px;
margin-bottom: 20px;

.stat-item {
  flex: 1;
  text-align: center;
  padding: 16px;
  background: linear-gradient(135deg, #f8f9ff 0%, #e8f4fd 100%);
  border-radius: 8px;
  border: 1px solid #e1e8f0;

  .stat-number {
    font-size: 24px;
    font-weight: 700;
    color: #409eff;
    margin-bottom: 4px;
  }

  .stat-label {
    font-size: 12px;
    color: #666;
    text-transform: uppercase;
    letter-spacing: 0.5px;
  }
}
}

.empty-state {
padding: 40px 20px;
text-align: center;
}

.task-list {
max-height: 500px;
overflow-y: auto;
padding: 10px 0;
}

.task-item {
border: 1px solid #ebeef5;
border-radius: 12px;
margin-bottom: 16px;
padding: 20px;
background: #fafafa;
transition: all 0.3s ease;

&:hover {
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.1);
  transform: translateY(-3px);
}

&.completed {
  background: linear-gradient(135deg, #f0f9ff 0%, #e6fffa 100%);
  border-color: #67c23a;
}
}

.task-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
gap: 24px;
}

.task-info {
flex: 1;

.task-name {
  margin: 0 0 12px 0;
  font-size: 16px;
  font-weight: 600;
  color: #303133;
  word-break: break-all;
}

.task-dataset, .task-id, .task-time {
  margin: 6px 0;
  font-size: 13px;
  color: #909399;
}

.task-dataset {
  color: #67c23a;
  font-weight: 500;
}
}

.task-progress {
flex: 0 0 220px;

.progress-status {
  margin-top: 8px;
  text-align: center;

  .status-tag {
    font-weight: 600;
  }
}

::v-deep .el-progress__text {
  font-weight: 600;
}
}

// 右键菜单样式
.context-menu {
position: fixed;
background: white;
border: none;
border-radius: 16px;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.15);
padding: 0;
z-index: 3000;
min-width: 240px;
backdrop-filter: blur(20px);
overflow: hidden;

.context-menu-header {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  padding: 16px 20px 12px;
  border-bottom: none;

  .menu-title {
    font-size: 14px;
    font-weight: 600;
    letter-spacing: 0.5px;
  }
}

.context-menu-item {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  padding: 16px 20px;
  cursor: pointer;
  transition: all 0.3s ease;
  border-bottom: 1px solid #f0f2f5;

  &:last-child {
    border-bottom: none;
  }

  &:hover {
    background: linear-gradient(135deg, #f8fbff 0%, #e8f4fd 100%);
    transform: translateX(4px);
  }

  .item-icon {
    width: 40px;
    height: 40px;
    border-radius: 10px;
    background: linear-gradient(135deg, #409eff 0%, #36cfc9 100%);
    display: flex;
    align-items: center;
    justify-content: center;
    color: white;
    font-size: 18px;
    flex-shrink: 0;
    transition: all 0.3s ease;
  }

  .item-content {
    flex: 1;
    padding-top: 2px;

    .item-title {
      font-size: 15px;
      font-weight: 600;
      color: #303133;
      margin-bottom: 4px;
      line-height: 1.4;
    }

    .item-desc {
      font-size: 12px;
      color: #909399;
      line-height: 1.3;
    }
  }

  &:hover .item-icon {
    transform: scale(1.1);
    box-shadow: 0 8px 20px rgba(64, 158, 255, 0.3);
  }
}
}

// 右键菜单动画
.context-menu-fade-enter-active {
transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
}

.context-menu-fade-leave-active {
transition: all 0.2s cubic-bezier(0.25, 0.8, 0.25, 1);
}

.context-menu-fade-enter-from {
opacity: 0;
transform: scale(0.8) translateY(-10px);
}

.context-menu-fade-leave-to {
opacity: 0;
transform: scale(0.9) translateY(-5px);
}

// 响应式设计
@media (max-width: 768px) {
.main-container {
  padding: 12px;
}


.action-bar {
  flex-direction: column;
  gap: 12px;
  align-items: stretch;
}

.left-group,
.right-group {
  justify-content: center;
}

.search-input {
  width: 100%;
}

.action-buttons {
  flex-direction: column;
  gap: 4px;
}
}
.segment-list-container {
  width: 30%;
  border-right: 1px solid #ebeef5;
  overflow-y: auto;
  padding: 16px;
  background: #f9fafc;
  display: flex;
  flex-direction: column;
  gap: 12px;

  h3 {
    margin-bottom: 12px;
    font-size: 16px;
    font-weight: 600;
    color: #303133;
  }

  .el-form-item {
    cursor: pointer;
    padding: 16px;            // 内边距增加
    border-radius: 8px;
    background: white;
    transition: all 0.2s ease;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
    min-height: 100px;        // 增加最小高度，让卡片更高
    display: flex;
    flex-direction: column;
    justify-content: center;  // 让内容垂直居中

    &:hover {
      background: #f0f4ff;
      transform: translateX(2px);
      box-shadow: 0 4px 12px rgba(64, 158, 255, 0.15);
    }

    span {
      font-size: 14px;
      font-weight: 500;
      color: #606266;
      margin-top: 4px;
      word-break: break-word; // 防止长文本溢出
    }

    h4 {
      font-family: "Microsoft YaHei", "微软雅黑", sans-serif; // 设置微软雅黑字体
      font-size: 14px;
      font-weight: 600;
      color: #4a4a4a;
      margin: 0;
      line-height: 1.6;
      display: -webkit-box;
      -webkit-line-clamp: 4;
      -webkit-box-orient: vertical;
      overflow: hidden;
      text-overflow: ellipsis;
      word-break: break-word;
    }
  }

  .empty-state {
    text-align: center;
    color: #909399;
    font-size: 14px;
    margin-top: 20px;
  }
}

/* 右侧预览内容保持原有样式 */
.preview-content-container {
  flex: 1;
  padding: 10px;
  overflow-y: auto;
  background: #ffffff;
  border-radius: 0 8px 8px 0;
}



</style>
