<template>
  <div class="app-container tree-sidebar-manage-wrap">
    <tree-panel title="文件夹" :tree-data="folderTree" search-placeholder="请输入文件夹名称" storage-key="efinder-folder-width" :defaultExpandAll="true" @node-click="handleNodeClick" @refresh="getFolderTree" ref="folderTreeRef" />
    <div class="tree-sidebar-content">
      <div class="content-inner">
        <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch">
          <el-form-item label="文件名称" prop="name">
            <el-input v-model="queryParams.name" placeholder="请输入文件名称" clearable style="width: 240px" @keyup.enter="handleQuery" />
          </el-form-item>
          <el-form-item>
            <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
            <el-button icon="Refresh" @click="resetQuery">重置</el-button>
          </el-form-item>
        </el-form>

        <el-row :gutter="10" class="mb8">
          <el-col :span="1.5">
            <el-button type="primary" plain icon="Upload" @click="handleUpload" v-hasPermi="['efinder:file:upload']">上传文件</el-button>
          </el-col>
          <el-col :span="1.5">
            <el-button type="success" plain icon="FolderAdd" @click="handleMkdir" v-hasPermi="['efinder:folder:add']">新建文件夹</el-button>
          </el-col>
          <el-col :span="1.5">
            <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete" v-hasPermi="['efinder:file:remove']">删除</el-button>
          </el-col>
          <right-toolbar v-model:showSearch="showSearch" @queryTable="fetchFileList" />
        </el-row>

        <el-table v-loading="loading" :data="fileList" @selection-change="handleSelectionChange">
          <el-table-column type="selection" width="50" align="center" />
          <el-table-column label="文件名称" align="center" prop="name" min-width="200" :show-overflow-tooltip="true">
            <template #default="scope">
              <el-link type="primary" :underline="false" @click="handlePreview(scope.row)">
                <svg-icon :icon-class="getFileIcon(scope.row.type)" class="file-icon" />
                {{ scope.row.name }}
              </el-link>
            </template>
          </el-table-column>
          <el-table-column label="文件大小" align="center" prop="size" width="120">
            <template #default="scope">
              <span>{{ formatFileSize(scope.row.size) }}</span>
            </template>
          </el-table-column>
          <el-table-column label="文件类型" align="center" prop="type" width="100" />
          <el-table-column label="更新时间" align="center" prop="date" width="180">
            <template #default="scope">
              <span>{{ parseTime(scope.row.date) }}</span>
            </template>
          </el-table-column>
          <el-table-column label="操作" align="center" width="250" class-name="small-padding fixed-width">
            <template #default="scope">
              <el-button link type="primary" icon="Download" @click="handleDownload(scope.row)" v-hasPermi="['efinder:file:download']">下载</el-button>
              <el-button link type="primary" icon="Edit" @click="handleRename(scope.row)" v-hasPermi="['efinder:file:edit']">重命名</el-button>
              <el-button link type="primary" icon="Rank" @click="handleMove(scope.row)">移动</el-button>
              <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['efinder:file:remove']">删除</el-button>
            </template>
          </el-table-column>
        </el-table>

        <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="fetchFileList" />
      </div>
    </div>

    <el-dialog :title="title" v-model="open" width="400px" append-to-body>
      <el-form ref="formRef" :model="form" :rules="rules" label-width="80px">
        <el-form-item label="文件夹名称" prop="name" v-if="form.mkdir">
          <el-input v-model="form.name" placeholder="请输入文件夹名称" maxlength="50" />
        </el-form-item>
        <el-form-item label="文件名称" prop="name" v-if="form.rename">
          <el-input v-model="form.name" placeholder="请输入文件名称" maxlength="100" />
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitForm">确 定</el-button>
          <el-button @click="cancel">取 消</el-button>
        </div>
      </template>
    </el-dialog>

    <el-dialog title="上传文件" v-model="uploadOpen" width="500px" append-to-body>
      <el-upload
        ref="uploadRef"
        :action="uploadUrl"
        :headers="uploadHeaders"
        :data="uploadData"
        :before-upload="beforeUpload"
        :on-success="uploadSuccess"
        :on-error="uploadError"
        :auto-upload="false"
        drag
        multiple
      >
        <el-icon class="el-icon--upload"><upload-filled /></el-icon>
        <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
        <template #tip>
          <div class="el-upload__tip">支持所有类型的文件上传</div>
        </template>
      </el-upload>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitUpload">开始上传</el-button>
          <el-button @click="uploadOpen = false">取 消</el-button>
        </div>
      </template>
    </el-dialog>

    <el-dialog title="移动到文件夹" v-model="moveOpen" width="400px" append-to-body>
      <el-tree :data="folderTree" node-key="id" :props="{ children: 'children', label: 'name' }" highlight-current @node-click="handleMoveTarget" />
      <template #footer>
        <el-button type="primary" @click="submitMove">确 定</el-button>
        <el-button @click="moveOpen = false">取 消</el-button>
      </template>
    </el-dialog>
  </div>
</template>
<script setup name="Efinder">
import { folderList, getFileList, downloadFile, renameFile, moveFile, mkdir, deleteFile } from "@/api/efinder/finder"
import { getToken } from "@/utils/auth"

const router = useRouter()
const { proxy } = getCurrentInstance()

const fileList = ref([])
const folderTree = ref([])
const open = ref(false)
const uploadOpen = ref(false)
const loading = ref(true)
const showSearch = ref(true)
const title = ref("")
const total = ref(0)
const ids = ref([])
const single = ref(true)
const multiple = ref(true)
const currentPid = ref(undefined)
const folderTreeRef = ref(null)

const uploadRef = ref(null)
const uploadUrl = ref(import.meta.env.VITE_SERVICE_BASE_TITLE + "/efinder/file/upload")
const uploadHeaders = ref({ Authorization: "Bearer " + getToken() })
const uploadData = ref({})

const moveOpen = ref(false)
const moveTargetId = ref(null)
const moveRow = ref({})

const data = reactive({
  form: {},
  queryParams: {
    pageNum: 1,
    pageSize: 10,
    name: undefined,
    pid: undefined
  },
  rules: {
    name: [{ required: true, message: "名称不能为空", trigger: "blur" }]
  }
})

const { queryParams, form, rules } = toRefs(data)

function getFolderTree() {
  folderList().then(response => {
    folderTree.value = proxy.handleTree(response.data, "id")
  })
}

function fetchFileList() {
  loading.value = true
  queryParams.value.pid = currentPid.value
  getFileList(queryParams.value).then(res => {
    fileList.value = res.rows
    total.value = res.total
    loading.value = false
  })
}

function handleNodeClick(data) {
  currentPid.value = data.id
  handleQuery()
}

function handleQuery() {
  queryParams.value.pageNum = 1
  fetchFileList()
}

function resetQuery() {
  proxy.resetForm("queryRef")
  queryParams.value.pid = currentPid.value
  handleQuery()
}

function handleSelectionChange(selection) {
  ids.value = selection.map(item => item.id)
  single.value = selection.length != 1
  multiple.value = !selection.length
}

function handleUpload() {
  uploadData.value = { pid: currentPid.value }
  uploadOpen.value = true
}

function submitUpload() {
  proxy.$refs.uploadRef.submit()
}

function beforeUpload(file) {
  const isLtSize = file.size / 1024 / 1024 < 500
  if (!isLtSize) {
    proxy.$modal.msgError("上传文件大小不能超过 500MB")
    return false
  }
  return true
}

function uploadSuccess(response) {
  if (response.code === 200) {
    proxy.$modal.msgSuccess("上传成功")
    uploadOpen.value = false
    fetchFileList()
  } else {
    proxy.$modal.msgError(response.msg)
  }
}

function uploadError() {
  proxy.$modal.msgError("上传失败")
}

function handleMkdir() {
  reset()
  form.value.mkdir = true
  form.value.rename = false
  open.value = true
  title.value = "新建文件夹"
}

function handleRename(row) {
  reset()
  form.value.mkdir = false
  form.value.rename = true
  form.value.id = row.id
  form.value.name = row.name
  open.value = true
  title.value = "重命名文件"
}

function handleDownload(row) {
  const id = row.id
  downloadFile(id).then(res => {
    const blob = new Blob([res])
    const link = document.createElement("a")
    link.href = URL.createObjectURL(blob)
    link.download = row.name
    link.click()
    URL.revokeObjectURL(link.href)
    proxy.$modal.msgSuccess("下载成功")
  })
}

function handleMove(row) {
  moveRow.value = row
  moveTargetId.value = null
  moveOpen.value = true
}

function handleMoveTarget(data) {
  moveTargetId.value = data.id
}

function submitMove() {
  if (!moveTargetId.value) {
    proxy.$modal.msgWarning("请选择目标文件夹")
    return
  }
  moveFile({ id: moveRow.value.id, pid: moveTargetId.value }).then(() => {
    moveOpen.value = false
    fetchFileList()
    proxy.$modal.msgSuccess("移动成功")
  })
}

function handlePreview(row) {
  const fileType = row.type ? row.type.toLowerCase() : ""
  router.push({ path: "/efinder/viewer", query: { fileId: row.id, fileType: fileType, fileName: row.name } })
}

function handleDelete(row) {
  const fileId = row.id || ids.value
  proxy.$modal.confirm('是否确认删除选中的数据项？').then(function() {
    return deleteFile(fileId)
  }).then(() => {
    getFolderTree()
    fetchFileList()
    proxy.$modal.msgSuccess("删除成功")
  }).catch(() => {})
}

function reset() {
  form.value = {
    mkdir: false,
    rename: false,
    id: undefined,
    name: undefined
  }
  proxy.resetForm("formRef")
}

function cancel() {
  open.value = false
  reset()
}

function submitForm() {
  proxy.$refs["formRef"].validate(valid => {
    if (valid) {
      if (form.value.mkdir) {
        mkdir({ name: form.value.name, pid: currentPid.value }).then(() => {
          proxy.$modal.msgSuccess("新建成功")
          open.value = false
          getFolderTree()
        })
      } else if (form.value.rename) {
        renameFile({ id: form.value.id, name: form.value.name }).then(() => {
          proxy.$modal.msgSuccess("重命名成功")
          open.value = false
          fetchFileList()
        })
      }
    }
  })
}

function getFileIcon(fileType) {
  const iconMap = {
    pdf: "pdf",
    doc: "word",
    docx: "word",
    xls: "excel",
    xlsx: "excel",
    ppt: "ppt",
    pptx: "ppt",
    mp4: "video",
    avi: "video",
    mov: "video",
    mp3: "audio",
    wav: "audio",
    zip: "zip",
    rar: "zip",
    "7z": "zip",
    jpg: "image",
    jpeg: "image",
    png: "image",
    gif: "image",
    txt: "txt"
  }
  return iconMap[fileType] || "file"
}

function formatFileSize(size) {
  if (!size) return ""
  const units = ["B", "KB", "MB", "GB", "TB"]
  let unitIndex = 0
  let bytes = size
  while (bytes >= 1024 && unitIndex < units.length - 1) {
    bytes /= 1024
    unitIndex++
  }
  return bytes.toFixed(2) + " " + units[unitIndex]
}

onMounted(() => {
  getFolderTree()
  fetchFileList()
})
</script>

<style lang="scss" scoped>
.file-icon {
  margin-right: 4px;
  font-size: 16px;
  vertical-align: middle;
}
</style>
