<script setup>
import { NIcon } from 'naive-ui'
import { AddOutline, TrashOutline, ChevronForwardOutline } from '@vicons/ionicons5'

const props = defineProps({
  nodes: { type: Array, default: () => [] },
  level: { type: Number, default: 0 },
  selectedId: { type: [Number, null], default: null },
  expandedIds: { type: Set, default: () => new Set() },
  editingId: { type: [Number, null], default: null },
  editingName: { type: String, default: '' },
  addingParentId: { type: [Number, null, undefined], default: undefined },
  addingName: { type: String, default: '' }
})

const emit = defineEmits([
  'select', 'toggle', 'add', 'delete', 'edit-start', 'edit-confirm', 'edit-cancel',
  'add-confirm', 'add-cancel', 'update:editingName', 'update:addingName'
])

const indent = 16 + props.level * 16
</script>

<template>
  <template v-for="node in nodes" :key="node.id">
    <div
      class="category-item"
      :class="{ active: selectedId === node.id }"
    >
      <div class="cat-left" @click="emit('select', node.id)" :style="{ paddingLeft: indent + 'px' }">
        <button v-if="node.children?.length" class="expand-btn" @click.stop="emit('toggle', node.id)">
          <n-icon size="12" :class="{ rotated: expandedIds.has(node.id) }">
            <ChevronForwardOutline />
          </n-icon>
        </button>
        <span v-else class="expand-placeholder"></span>

        <template v-if="editingId === node.id">
          <input
            class="inline-input"
            :value="editingName"
            @input="$emit('update:editingName', $event.target.value)"
            @keyup.enter="emit('edit-confirm')"
            @keyup.escape="emit('edit-cancel')"
            @blur="emit('edit-confirm')"
            autofocus
          />
        </template>
        <template v-else>
          <span class="cat-name" @dblclick="emit('edit-start', { id: node.id, name: node.name })">{{ node.name }}</span>
        </template>
      </div>

      <div class="cat-actions" v-if="editingId !== node.id">
        <button class="icon-btn-sm" @click.stop="emit('add', node.id)" title="添加子分类">
          <n-icon size="12"><AddOutline /></n-icon>
        </button>
        <button class="icon-btn-sm delete-icon" @click.stop="emit('delete', { id: node.id, name: node.name })" title="删除">
          <n-icon size="12"><TrashOutline /></n-icon>
        </button>
      </div>
    </div>

    <!-- 展开的子分类 -->
    <template v-if="node.children?.length && expandedIds.has(node.id)">
      <KbCategoryTree
        :nodes="node.children"
        :level="level + 1"
        :selected-id="selectedId"
        :expanded-ids="expandedIds"
        :editing-id="editingId"
        :editing-name="editingName"
        :adding-parent-id="addingParentId"
        :adding-name="addingName"
        @select="emit('select', $event)"
        @toggle="emit('toggle', $event)"
        @add="emit('add', $event)"
        @delete="emit('delete', $event)"
        @edit-start="emit('edit-start', $event)"
        @edit-confirm="emit('edit-confirm')"
        @edit-cancel="emit('edit-cancel')"
        @add-confirm="emit('add-confirm')"
        @add-cancel="emit('add-cancel')"
        @update:editing-name="emit('update:editingName', $event)"
        @update:adding-name="emit('update:addingName', $event)"
      />
    </template>

    <!-- 当前节点的子分类下的添加输入框 -->
    <div v-if="addingParentId === node.id && expandedIds.has(node.id)" class="category-item adding" :style="{ paddingLeft: (indent + 16) + 'px' }">
      <span class="expand-placeholder"></span>
      <input
        class="inline-input"
        :value="addingName"
        @input="$emit('update:addingName', $event.target.value)"
        placeholder="输入分类名称"
        @keyup.enter="emit('add-confirm')"
        @keyup.escape="emit('add-cancel')"
        @blur="emit('add-cancel')"
        autofocus
      />
    </div>
  </template>
</template>

<style scoped>
.category-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 6px 16px 6px 0;
  cursor: pointer;
  transition: all 0.15s;
  min-height: 32px;
}

.category-item:hover {
  background: rgba(37, 99, 235, 0.06);
}

.category-item.active {
  background: rgba(37, 99, 235, 0.12);
}

.category-item.active .cat-name {
  color: var(--color-accent);
  font-weight: 500;
}

.category-item.adding {
  cursor: default;
}

.cat-left {
  display: flex;
  align-items: center;
  gap: 4px;
  flex: 1;
  min-width: 0;
}

.expand-btn {
  background: none;
  border: none;
  padding: 2px;
  cursor: pointer;
  color: var(--text-tertiary);
  display: flex;
  align-items: center;
  transition: transform 0.2s;
}

.expand-btn .rotated {
  transform: rotate(90deg);
}

.expand-placeholder {
  width: 16px;
  min-width: 16px;
}

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

.cat-actions {
  display: flex;
  align-items: center;
  gap: 2px;
  opacity: 0;
  transition: opacity 0.15s;
  padding-right: 16px;
}

.category-item:hover .cat-actions {
  opacity: 1;
}

.icon-btn-sm {
  background: none;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  padding: 2px;
  border-radius: 3px;
  display: flex;
  align-items: center;
  transition: all 0.15s;
}

.icon-btn-sm:hover {
  color: var(--color-accent);
  background: rgba(37, 99, 235, 0.1);
}

.icon-btn-sm.delete-icon:hover {
  color: var(--color-danger);
}

.inline-input {
  background: rgba(37, 99, 235, 0.08);
  border: 1px solid rgba(37, 99, 235, 0.2);
  border-radius: 4px;
  padding: 2px 8px;
  font-size: 13px;
  color: var(--text-primary);
  outline: none;
  width: 100%;
  font-family: inherit;
}

.inline-input:focus {
  border-color: var(--color-accent);
  box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.15);
}
</style>
