<script setup>
import { Delete, Edit, Folder, FolderOpened } from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { onMounted, reactive, ref, computed } from 'vue'
import { createPkgCategory, deletePkgCategory, getPkgCategoryTree, updatePkgCategory } from '@/api/packageManagement'

const props = defineProps({
  modelValue: {
    type: [String, Number],
    default: 'all',
  },
  style: {
    type: Object,
    default: () => ({}),
  },
})

const emit = defineEmits(['update:modelValue', 'select'])

const categoryTree = ref([])
const dialogVisible = ref(false)
const dialogMode = ref('create')
const editingId = ref('')
const form = reactive({ name: '' })

const dialogTitle = computed(() => (dialogMode.value === 'create' ? '新增分类' : '编辑分类'))

const normalizeCategoryTree = (treeData) => {
  const source = Array.isArray(treeData) ? treeData : []
  const children = source
    .filter((item) => String(item?.id) !== 'all')
    .map((item) => ({ id: item.id, name: item.name, parent_id: item.parent_id, children: [] }))
  return [{ id: 'all', name: '全部', parent_id: null, children }]
}

const loadCategoryTree = async () => {
  const data = await getPkgCategoryTree()
  categoryTree.value = normalizeCategoryTree(data)

  const allIds = [
    ...categoryTree.value.map((item) => String(item.id)),
    ...categoryTree.value.flatMap((item) => (item.children || []).map((c) => String(c.id))),
  ]
  if (!allIds.includes(String(props.modelValue))) {
    emit('update:modelValue', 'all')
    emit('select', 'all')
  }
}

const handleNodeClick = (node) => {
  emit('update:modelValue', node.id)
  emit('select', node.id)
}

const openCreate = () => {
  dialogMode.value = 'create'
  editingId.value = ''
  form.name = ''
  dialogVisible.value = true
}

const openEdit = (node) => {
  dialogMode.value = 'edit'
  editingId.value = node.id
  form.name = node.name
  dialogVisible.value = true
}

const submitCategory = async () => {
  const name = form.name.trim()
  if (!name) {
    ElMessage.warning('请输入分类名称')
    return
  }
  if (dialogMode.value === 'create') {
    await createPkgCategory({ name, parent_id: null })
  } else {
    await updatePkgCategory(editingId.value, { name })
  }
  dialogVisible.value = false
  ElMessage.success('分类保存成功')
  await loadCategoryTree()
}

const handleDelete = async (node) => {
  try {
    await ElMessageBox.confirm(`确定删除分类"${node.name}"吗？`, '提示', { type: 'warning' })
    await deletePkgCategory(node.id)
    ElMessage.success('分类已删除')
    if (String(props.modelValue) === String(node.id)) {
      emit('update:modelValue', 'all')
      emit('select', 'all')
    }
    await loadCategoryTree()
  } catch {
    // user cancelled
  }
}

onMounted(loadCategoryTree)
</script>

<template>
  <el-card class="pane-card" shadow="hover" :style="props.style">
    <template #header>
      <div class="pane-header">
        <span>分类树</span>
        <el-button type="primary" plain size="small" @click="openCreate">新增</el-button>
      </div>
    </template>

    <el-tree
      :data="categoryTree"
      node-key="id"
      highlight-current
      default-expand-all
      :current-node-key="modelValue || undefined"
      :expand-on-click-node="false"
      @node-click="handleNodeClick"
    >
      <template #default="{ data }">
        <div class="tree-node">
          <div class="tree-main">
            <el-icon class="tree-icon">
              <component :is="data.id === 'all' ? FolderOpened : Folder" />
            </el-icon>
            <span class="tree-name">{{ data.name }}</span>
          </div>
          <span v-if="data.id !== 'all'" class="tree-actions">
            <el-button link type="primary" :icon="Edit" @click.stop="openEdit(data)" />
            <el-button link type="danger" :icon="Delete" @click.stop="handleDelete(data)" />
          </span>
        </div>
      </template>
    </el-tree>
  </el-card>

  <el-dialog v-model="dialogVisible" :title="dialogTitle" width="420px">
    <el-form label-position="top">
      <el-form-item label="分类名称" required>
        <el-input v-model="form.name" maxlength="100" show-word-limit />
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button @click="dialogVisible = false">取消</el-button>
      <el-button type="primary" @click="submitCategory">保存</el-button>
    </template>
  </el-dialog>
</template>

<style lang="scss" scoped>
.pane-card {
  height: 100%;
  overflow: hidden;
  border-radius: 0;
  border: none;
  border-right: 1px solid var(--border-color);
  box-shadow: none !important;
  display: flex;
  flex-direction: column;
  background: var(--bg-white);

  :deep(.el-card__header) {
    padding: 0 16px;
    height: 44px;
    display: flex;
    align-items: center;
    border-bottom: 1px solid var(--border-color);
    background: #F7F8FA;
  }

  :deep(.el-card__body) {
    flex: 1;
    overflow-y: auto;
    padding: 8px 0;
  }
}

.pane-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  font-size: 14px;
  font-weight: 600;
  color: var(--text-primary);
}

.tree-node {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  min-width: 0;
  padding-right: 4px;
}

.tree-main {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}

.tree-icon {
  color: var(--primary);
  flex-shrink: 0;
  font-size: 14px;
}

.tree-name {
  font-size: 13px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--text-primary);
}

.tree-actions {
  display: none;
  flex-shrink: 0;
  gap: 0;

  .el-button {
    padding: 0 3px;
    font-size: 13px;
    color: var(--text-tertiary);

    &:hover {
      color: var(--primary);
    }
  }
}

.tree-node:hover .tree-actions {
  display: inline-flex;
}
</style>
