<template>
  <div class="file-list-container">
    <el-card>
      <template #header>
        <div class="card-header">
          <span>文件列表</span>
          <div class="header-actions">
            <el-button-group>
              <el-button
                :type="viewMode === 'table' ? 'primary' : ''"
                @click="viewMode = 'table'"
              >
                <el-icon><list /></el-icon>
                列表
              </el-button>
              <el-button
                :type="viewMode === 'grid' ? 'primary' : ''"
                @click="viewMode = 'grid'"
              >
                <el-icon><grid /></el-icon>
                网格
              </el-button>
            </el-button-group>
            <el-button type="primary" @click="showUploadDialog = true">
              <el-icon><upload /></el-icon>
              上传文件
            </el-button>
          </div>
        </div>
      </template>

      <!-- 搜索筛选 -->
      <div class="filter-bar">
        <el-row :gutter="16">
          <el-col :span="8">
            <el-input
              v-model="queryParams.keyword"
              placeholder="搜索文件名"
              clearable
              @clear="handleSearch"
              @keyup.enter="handleSearch"
            >
              <template #prefix>
                <el-icon><search /></el-icon>
              </template>
            </el-input>
          </el-col>
          <el-col :span="6">
            <el-select
              v-model="queryParams.file_type"
              placeholder="文件类型"
              clearable
              @change="handleSearch"
            >
              <el-option label="图片" value="image" />
              <el-option label="文档" value="document" />
              <el-option label="压缩包" value="archive" />
            </el-select>
          </el-col>
          <el-col :span="6">
            <el-date-picker
              v-model="dateRange"
              type="daterange"
              range-separator="至"
              start-placeholder="开始日期"
              end-placeholder="结束日期"
              value-format="YYYY-MM-DD"
              @change="handleSearch"
            />
          </el-col>
          <el-col :span="4">
            <el-button type="primary" @click="handleSearch">
              <el-icon><search /></el-icon>
              搜索
            </el-button>
          </el-col>
        </el-row>
      </div>

      <!-- 表格视图 -->
      <div v-if="viewMode === 'table'" class="table-view">
        <el-table
          v-loading="loading"
          :data="fileList"
          stripe
          @selection-change="handleSelectionChange"
        >
          <el-table-column type="selection" width="55" />
          <el-table-column label="文件名" prop="original_name" min-width="200">
            <template #default="{ row }">
              <div class="file-name-cell">
                <el-icon class="file-icon">
                  <component :is="getFileIcon(row.file_type)" />
                </el-icon>
                <span class="file-name">{{ row.original_name }}</span>
              </div>
            </template>
          </el-table-column>
          <el-table-column label="文件类型" prop="file_type" width="120" />
          <el-table-column label="文件大小" width="100" align="right">
            <template #default="{ row }">
              {{ formatFileSize(row.file_size) }}
            </template>
          </el-table-column>
          <el-table-column label="上传者" prop="uploader_name" width="100" />
          <el-table-column label="上传时间" width="180">
            <template #default="{ row }">
              {{ formatDateTime(row.upload_time) }}
            </template>
          </el-table-column>
          <el-table-column label="下载次数" prop="download_count" width="100" align="center" />
          <el-table-column label="操作" width="200" fixed="right">
            <template #default="{ row }">
              <el-button-group>
                <el-button
                  v-if="isImage(row)"
                  size="small"
                  @click="handlePreview(row)"
                >
                  <el-icon><view /></el-icon>
                  预览
                </el-button>
                <el-button
                  size="small"
                  @click="handleDownload(row)"
                >
                  <el-icon><download /></el-icon>
                  下载
                </el-button>
                <el-button
                  size="small"
                  @click="handleShare(row)"
                >
                  <el-icon><share /></el-icon>
                  分享
                </el-button>
                <el-button
                  size="small"
                  type="danger"
                  @click="handleDelete(row)"
                >
                  <el-icon><delete /></el-icon>
                  删除
                </el-button>
              </el-button-group>
            </template>
          </el-table-column>
        </el-table>
      </div>

      <!-- 网格视图 -->
      <div v-else class="grid-view">
        <el-row :gutter="16">
          <el-col
            v-for="file in fileList"
            :key="file.id"
            :span="6"
          >
            <div class="file-card" @click="handlePreview(file)">
              <div class="file-preview">
                <el-image
                  v-if="isImage(file)"
                  :src="file.preview_url"
                  fit="cover"
                  class="preview-image"
                >
                  <template #error>
                    <div class="image-slot">
                      <el-icon class="file-icon-large">
                        <component :is="getFileIcon(file.file_type)" />
                      </el-icon>
                    </div>
                  </template>
                </el-image>
                <div v-else class="file-icon-wrapper">
                  <el-icon class="file-icon-large">
                    <component :is="getFileIcon(file.file_type)" />
                  </el-icon>
                </div>
              </div>
              <div class="file-info">
                <div class="file-name" :title="file.original_name">
                  {{ file.original_name }}
                </div>
                <div class="file-meta">
                  <span>{{ formatFileSize(file.file_size) }}</span>
                  <span>{{ formatDateTime(file.upload_time) }}</span>
                </div>
              </div>
              <div class="file-actions" @click.stop>
                <el-button-group>
                  <el-button size="small" @click="handleDownload(file)">
                    <el-icon><download /></el-icon>
                  </el-button>
                  <el-button size="small" @click="handleShare(file)">
                    <el-icon><share /></el-icon>
                  </el-button>
                  <el-button size="small" type="danger" @click="handleDelete(file)">
                    <el-icon><delete /></el-icon>
                  </el-button>
                </el-button-group>
              </div>
            </div>
          </el-col>
        </el-row>
      </div>

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

    <!-- 上传对话框 -->
    <el-dialog
      v-model="showUploadDialog"
      title="上传文件"
      width="600px"
    >
      <file-upload
        ref="uploadRef"
        :auto-upload="false"
        @upload-success="handleUploadSuccess"
      />
    </el-dialog>

    <!-- 分享对话框 -->
    <el-dialog
      v-model="showShareDialog"
      title="分享文件"
      width="500px"
    >
      <el-form :model="shareForm" label-width="100px">
        <el-form-item label="有效期">
          <el-input-number
            v-model="shareForm.expire_days"
            :min="1"
            :max="30"
          />
          <span class="unit">天</span>
        </el-form-item>
        <el-form-item label="分享链接">
          <el-input
            v-model="shareUrl"
            readonly
          >
            <template #append>
              <el-button @click="copyShareUrl">复制</el-button>
            </template>
          </el-input>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="showShareDialog = false">取消</el-button>
        <el-button type="primary" @click="generateShareLink">生成分享链接</el-button>
      </template>
    </el-dialog>

    <!-- 图片预览 -->
    <image-preview
      v-model:visible="showImagePreview"
      :images="previewImages"
      :initial-index="previewIndex"
    />
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, computed, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
  List,
  Grid,
  Upload,
  Search,
  View,
  Download,
  Share,
  Delete,
  Document,
  Picture,
  Folder,
  Files
} from '@element-plus/icons-vue'
import { downloadFile, formatFileSize, formatDateTime } from '@/utils/file'
import FileUpload from './FileUpload.vue'
import ImagePreview from './ImagePreview.vue'
import request from '@/utils/request'

// 文件列表数据
const loading = ref(false)
const fileList = ref<any[]>([])
const total = ref(0)
const selectedFiles = ref<any[]>([])

// 视图模式
const viewMode = ref<'table' | 'grid'>('table')

// 查询参数
const queryParams = reactive({
  keyword: '',
  file_type: '',
  start_date: '',
  end_date: '',
  page: 1,
  page_size: 20
})

const dateRange = ref<[string, string]>([])

// 对话框
const showUploadDialog = ref(false)
const showShareDialog = ref(false)
const showImagePreview = ref(false)

// 分享
const shareForm = reactive({
  expire_days: 7
})
const shareUrl = ref('')
const currentShareFile = ref<any>(null)

// 预览
const previewIndex = ref(0)
const previewImages = computed(() => {
  return fileList.value
    .filter(f => isImage(f))
    .map(f => ({
      url: f.preview_url || f.download_url,
      name: f.original_name
    }))
})

// 上传组件ref
const uploadRef = ref()

// 获取文件图标
const getFileIcon = (fileType: string) => {
  if (fileType?.startsWith('image/')) {
    return Picture
  }
  if (fileType?.includes('pdf') || fileType?.includes('document')) {
    return Document
  }
  if (fileType?.includes('zip') || fileType?.includes('rar')) {
    return Folder
  }
  return Files
}

// 判断是否为图片
const isImage = (file: any) => {
  return file.file_type?.startsWith('image/')
}

// 获取文件列表
const fetchFiles = async () => {
  try {
    loading.value = true
    const params = {
      ...queryParams,
      start_date: dateRange.value?.[0] || '',
      end_date: dateRange.value?.[1] || ''
    }
    const { data } = await request.get('/api/v1/files', { params })
    fileList.value = data || []
    // 注意：实际应该从响应头获取total
  } catch (error) {
    ElMessage.error('获取文件列表失败')
  } finally {
    loading.value = false
  }
}

// 搜索
const handleSearch = () => {
  queryParams.page = 1
  fetchFiles()
}

// 选择改变
const handleSelectionChange = (files: any[]) => {
  selectedFiles.value = files
}

// 预览文件
const handlePreview = (file: any) => {
  if (!isImage(file)) {
    ElMessage.warning('该文件类型不支持预览')
    return
  }

  const index = previewImages.value.findIndex(img => img.url === file.preview_url)
  previewIndex.value = index
  showImagePreview.value = true
}

// 下载文件
const handleDownload = async (file: any) => {
  try {
    await downloadFile(file.download_url, file.original_name)
  } catch (error) {
    ElMessage.error('下载失败')
  }
}

// 分享文件
const handleShare = (file: any) => {
  currentShareFile.value = file
  shareUrl.value = ''
  showShareDialog.value = true
}

// 生成分享链接
const generateShareLink = async () => {
  if (!currentShareFile.value) return

  try {
    const { data } = await request.post(
      `/api/v1/files/${currentShareFile.value.id}/share`,
      { expire_days: shareForm.expire_days }
    )
    shareUrl.value = data.share_url
    ElMessage.success('分享链接生成成功')
  } catch (error) {
    ElMessage.error('生成分享链接失败')
  }
}

// 复制分享链接
const copyShareUrl = () => {
  navigator.clipboard.writeText(shareUrl.value)
  ElMessage.success('已复制到剪贴板')
}

// 删除文件
const handleDelete = async (file: any) => {
  try {
    await ElMessageBox.confirm('确定要删除此文件吗？', '提示', {
      type: 'warning'
    })

    await request.delete(`/api/v1/files/${file.id}`)
    ElMessage.success('删除成功')
    fetchFiles()
  } catch (error) {
    if (error !== 'cancel') {
      ElMessage.error('删除失败')
    }
  }
}

// 上传成功
const handleUploadSuccess = (response: any, file: any) => {
  ElMessage.success('上传成功')
  showUploadDialog.value = false
  fetchFiles()
}

// 初始化
onMounted(() => {
  fetchFiles()
})
</script>

<style scoped lang="scss">
.file-list-container {
  .card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;

    .header-actions {
      display: flex;
      gap: 12px;
    }
  }

  .filter-bar {
    margin-bottom: 20px;
  }

  .table-view {
    .file-name-cell {
      display: flex;
      align-items: center;
      gap: 8px;

      .file-icon {
        font-size: 20px;
        color: var(--el-color-primary);
      }

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

  .grid-view {
    .file-card {
      margin-bottom: 16px;
      border: 1px solid var(--el-border-color);
      border-radius: 4px;
      overflow: hidden;
      cursor: pointer;
      transition: all 0.3s;

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

        .file-actions {
          opacity: 1;
        }
      }

      .file-preview {
        width: 100%;
        height: 160px;
        background: var(--el-fill-color-light);
        display: flex;
        justify-content: center;
        align-items: center;

        .preview-image {
          width: 100%;
          height: 100%;
        }

        .file-icon-wrapper {
          font-size: 80px;
          color: var(--el-text-color-secondary);
        }

        .image-slot {
          width: 100%;
          height: 100%;
          display: flex;
          justify-content: center;
          align-items: center;
          background: var(--el-fill-color-light);

          .file-icon-large {
            font-size: 60px;
            color: var(--el-text-color-secondary);
          }
        }
      }

      .file-info {
        padding: 12px;

        .file-name {
          font-size: 14px;
          font-weight: 500;
          overflow: hidden;
          text-overflow: ellipsis;
          white-space: nowrap;
          margin-bottom: 8px;
        }

        .file-meta {
          display: flex;
          justify-content: space-between;
          font-size: 12px;
          color: var(--el-text-color-secondary);
        }
      }

      .file-actions {
        padding: 8px 12px;
        border-top: 1px solid var(--el-border-color);
        opacity: 0;
        transition: opacity 0.3s;
      }
    }
  }

  .pagination-container {
    margin-top: 20px;
    display: flex;
    justify-content: flex-end;
  }

  .unit {
    margin-left: 8px;
    color: var(--el-text-color-regular);
  }
}
</style>
