<template>
  <div class="material-catalog">
    <el-scrollbar>
      <el-tree
        class="p-3"
        node-key="id"
        :data="catalogList"
        :current-node-key="props.modelValue"
        :expand-on-click-node="false"
        empty-text=""
        highlight-current
        @node-click="handleCatSelect"
      >
        <template v-slot="{ data }">
          <div class="flex flex-1 items-center min-w-0 pr-3 relative">
            <img class="w-[18px] h-[18px] mr-2" src="@/assets/images/icon_folder.png" />
            <span class="flex-1 truncate mr-1 text-base">{{ data.name }}</span>
            <el-dropdown
              popper-class="text-center"
              v-if="data.id && data.id > 0 && !props.isPicker"
              :hide-on-click="false"
              class="catalog-dropdown"
              @command="handleCommand($event, data)"
            >
              <el-icon :size="14"><MoreFilled /></el-icon>
              <template #dropdown>
                <el-dropdown-menu>
                  <el-dropdown-item command="add">添加分组</el-dropdown-item>
                  <el-dropdown-item command="edit">编辑分组</el-dropdown-item>
                  <el-dropdown-item command="delete">删除分组</el-dropdown-item>
                </el-dropdown-menu>
              </template>
            </el-dropdown>
          </div>
        </template>
      </el-tree>
    </el-scrollbar>
    <div class="p-3 border-t border-br">
      <el-button class="w-full" type="primary" plain @click="openCateDialog()"> 添加分组 </el-button>
    </div>
  </div>
  <!-- 添加/编辑分组弹窗 -->
  <popup v-model="cateDialogVisible" width="450px" :title="cateDialogTitle" @confirm="handleCateSave">
    <el-form ref="cateFormRef" :model="cateForm" :rules="cateFormRules" label-width="100px">
      <el-form-item label="父分组" prop="pid">
        <el-tree-select
          class="w-full"
          v-model="cateForm.pid"
          :data="parentCateLists"
          placeholder="请选择父分组"
          node-key="id"
          :props="{ label: 'name', children: 'children' }"
          check-strictly
          default-expand-all
        />
      </el-form-item>
      <el-form-item label="分组名称" prop="name">
        <el-input
          ref="nameInput"
          v-model="cateForm.name"
          placeholder="请输入分组名称"
          :maxlength="20"
          show-word-limit
        />
      </el-form-item>
    </el-form>
  </popup>
</template>

<script setup lang="ts">
import type { FormInstance } from 'element-plus'
import { materialCateAdd, materialCateEdit, materialCateDelete } from '@/api/material'

// 组件属性
const props = defineProps<{
  modelValue: string | number
  cateLists: any[]
  isPicker: boolean
  type: string
}>()
// 组件事件
const emit = defineEmits<{
  (e: 'update:modelValue', value: string | number): void
  (e: 'getList'): void
}>()
// 目录分类列表
const catalogList = computed(() => {
  const list = JSON.parse(JSON.stringify(props.cateLists))
  list.unshift({ name: '全部', id: '' })
  return list
})
// 添加/编辑分组相关
const cateDialogVisible = ref(false)
const cateFormRef = shallowRef<FormInstance>()
const nameInput = ref<HTMLInputElement | null>()
const parentCateLists = ref<any[]>([])
const cateForm = reactive({
  pid: 0,
  id: 0,
  name: ''
})
const cateFormRules = reactive({
  name: [
    {
      required: true,
      message: '请输入分组名称',
      trigger: ['blur', 'change']
    }
  ]
})
const cateDialogTitle = computed(() => {
  return cateForm.id ? '编辑分组' : '添加分组'
})
// 过滤掉当前分类及其子分类
const filterParentCates = (cates: any[], excludeId?: number): any[] => {
  if (!excludeId) return cates
  return cates
    .filter((cate) => cate.id !== excludeId)
    .map((cate) => {
      const filteredCate = { ...cate }
      if (cate.children && cate.children.length > 0) {
        filteredCate.children = filterParentCates(cate.children, excludeId)
      }
      return filteredCate
    })
}
// 打开添加/编辑分组弹窗
const openCateDialog = (pid?: number, id?: number, name?: string) => {
  Object.assign(cateForm, {
    pid: pid || 0,
    id: id || 0,
    name: name || ''
  })
  const list = JSON.parse(JSON.stringify(props.cateLists))
  list.unshift({ name: '顶级', id: 0 })
  parentCateLists.value = filterParentCates(list, id)
  cateDialogVisible.value = true
  setTimeout(() => {
    if (nameInput.value) {
      nameInput.value.focus()
    }
  }, 100)
}
// 保存分组
const handleCateSave = async () => {
  if (!cateFormRef.value) return
  try {
    await cateFormRef.value.validate()
    if (cateForm.id) {
      await materialCateEdit(cateForm)
      ElMessage.success('分组编辑成功')
    } else {
      await materialCateAdd({
        type: props.type,
        name: cateForm.name,
        pid: cateForm.pid
      })
      ElMessage.success('分组添加成功')
    }
    cateDialogVisible.value = false
    emit('getList')
  } catch (error: any) {
    if (error.name !== 'Error') {
      // 表单验证失败，不显示错误信息
      return
    }
    console.error('保存分组失败:', error)
  }
}
// 分类操作方法
const handleCatSelect = (item: any) => {
  emit('update:modelValue', item.id)
}
// 删除分类
const handleDeleteCate = async (id: number, children?: number) => {
  const msg = children ? '删除文件夹将会永久删除文件夹及其所有内容，您确定要继续吗？' : '确定要删除该分组吗？'
  ElMessageBox.confirm(msg, '温馨提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  })
    .then(() => {
      materialCateDelete({ id })
        .then(() => {
          ElMessage.success('删除成功')
          if (id === props.modelValue) emit('update:modelValue', '')
          emit('getList')
        })
        .catch(() => {})
    })
    .catch(() => {})
}
// 处理分类下拉菜单命令
const handleCommand = (command: string, item: any) => {
  if (command === 'add') {
    openCateDialog(item.id)
  } else if (command === 'edit') {
    openCateDialog(item.pid, item.id, item.name)
  } else if (command === 'delete') {
    handleDeleteCate(item.id, item.children?.length || 0)
  }
}
</script>

<style lang="scss" scoped>
.material-catalog {
  @apply border-r border-br flex flex-col w-[200px];

  :deep(.el-tree-node) {
    margin-top: 4px;

    &:first-child {
      margin-top: 0;
    }

    .el-tree-node__content {
      @apply h-9 rounded transition-all duration-300 relative;

      .catalog-dropdown {
        opacity: 0;
        visibility: hidden;
        transition: all 0.2s ease;
        width: 0;
        display: inline-flex;
        align-items: center;
        justify-content: center;
      }

      &:hover {
        background-color: var(--el-color-primary-light-9);

        .catalog-dropdown {
          opacity: 1;
          visibility: visible;
          width: 14px;
          margin-left: 4px;
        }
      }
    }

    &.is-current .el-tree-node__content {
      color: var(--el-color-primary);
    }

    .el-tree-node__children {
      margin-top: 4px;

      .el-tree-node {
        .el-tree-node__content {
          color: var(--el-tree-text-color);
        }

        &.is-current .el-tree-node__content {
          color: var(--el-color-primary);
        }
      }
    }
  }
}
</style>
