<template>
  <div className="folder-header" v-if="folderList && folderList.length > 0">
    <el-input v-model="folderName" class="!w-340px" clearable placeholder="请输入文件夹名称">
      <template #prefix>
        <Icon icon="ep:search" />
      </template>
    </el-input>
    <el-space>
      <el-button type="danger" plain @click="toggleExpandAll">
        <Icon icon="ep:sort" class="mr-5px" /> 展开/折叠
      </el-button>
    </el-space>
  </div>
  <div>
    <el-tree
      ref="treeRef"
      v-if="refreshTable"
      :load="folderLoading"
      :data="folderList"
      :expand-on-click-node="false"
      :filter-node-method="filterNode"
      :props="defaultProps"
      :default-expand-all="isExpandAll"
      highlight-current
      node-key="id"
      @node-click="handleNodeClick"
    >
      <template #default="{ node, data }">
        <span class="custom-tree-node">
          <span>{{ node.label }}</span>
          <span class="btns" :class="{ show: data.id === curCategoryId }">
            <el-button type="primary" size="small" plain @click="appendFolder(data.id)"
              >新增</el-button
            >
            <el-button
              style="margin-left: 8px"
              type="warning"
              size="small"
              plain
              @click="updateFolder(data.id)"
              >修改</el-button
            >
            <el-button
              :class="{ hidden: data.children !== undefined }"
              style="margin-left: 8px"
              type="danger"
              size="small"
              plain
              @click="deleteFolder(data.id)"
              >删除</el-button
            >
          </span>
        </span>
      </template>
      <template #empty>
        <el-button type="primary" plain @click="appendFolder(0)">新增文件夹</el-button>
      </template>
    </el-tree>
  </div>

  <!-- 表单弹窗：添加/修改 -->
  <CategoryForm ref="formRef" @success="getFolderList" />
</template>

<script lang="ts" setup>
import { ElTree } from 'element-plus'
import { defaultProps, handleTree } from '@/utils/tree'
import { CategoryApi, CategoryVO } from '@/api/infra/category'
import CategoryForm from './CategoryForm.vue'
import download from '@/utils/download'

defineOptions({ name: 'CategoryFolderTree' })
const emits = defineEmits(['node-click'])

const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗

const folderLoading = ref(false)
const folderName = ref('')
const folderList = ref<Tree[]>([])
const refreshTable = ref(true) // 重新渲染表格状态
const exportLoading = ref(false) // 导出的加载中
const isExpandAll = ref(true) // 是否展开，默认全部展开
const curCategoryId = ref<number>()

const treeRef = ref<InstanceType<typeof ElTree>>()
const formRef = ref()

/** 查询文件夹列表 */
const getFolderList = async () => {
  folderLoading.value = true
  try {
    const data = await CategoryApi.getCategoryList()
    folderList.value = handleTree(data, 'id', 'parentId')
    // 重载树
    refreshTable.value = false
    await nextTick()
    refreshTable.value = true
  } finally {
    folderLoading.value = false
  }
}

/** 处理部门被点击 */
const handleNodeClick = async (row: { [key: string]: any }) => {
  curCategoryId.value = row.id
  emits('node-click', row)
}

/** 基于名字过滤 */
const filterNode = (name: string, data: Tree) => {
  if (!name) return true
  return data.name.includes(name)
}

/** 监听过滤项 */
watch(folderName, (val) => {
  treeRef.value!.filter(val)
})

/** 新增文件夹 */
const appendFolder = (id: number) => {
  formRef.value.open('create', id)
}

/** 修改文件夹 */
const updateFolder = (id: number) => {
  formRef.value.open('update', id)
}

/** 删除文件夹 */
const deleteFolder = async (id: number) => {
  try {
    // 删除的二次确认
    await message.delConfirm()
    // 发起删除
    await CategoryApi.deleteCategory(id)
    message.success(t('common.delSuccess'))
    // 刷新列表
    getFolderList()
  } catch {}
}

/** 导出按钮操作 */
const handleExport = async () => {
  try {
    // 导出的二次确认
    await message.exportConfirm()
    // 发起导出
    exportLoading.value = true
    const data = await CategoryApi.exportCategory()
    download.excel(data, '文件目录.xls')
  } catch {
  } finally {
    exportLoading.value = false
  }
}

/** 展开/折叠操作 */
const toggleExpandAll = async () => {
  refreshTable.value = false
  isExpandAll.value = !isExpandAll.value
  await nextTick()
  refreshTable.value = true
}

// invoke
getFolderList()
</script>

<style scoped lang="scss">
.folder-header {
  display: flex;
  justify-content: space-between;
  margin-bottom: 20px;
}

.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding-right: 8px;
}

.hidden {
  visibility: hidden;
}

.show {
  visibility: visible !important;
}

:deep(.el-tree-node__children) {
  margin-top: 7px;
}

:deep(.el-tree-node__content) {
  .btns {
    visibility: hidden;
  }

  &:hover {
    .btns {
      visibility: visible;
    }
  }
}
</style>
