<script setup>
import { ref } from 'vue'
import { NIcon, NPopconfirm, NModal, NInput } from 'naive-ui'
import {
  ChevronForwardOutline, CreateOutline, AddCircleOutline, TrashOutline
} from '@vicons/ionicons5'

const props = defineProps({
  node: { type: Object, required: true },
  expandedNodes: { type: Set, required: true }
})

const emit = defineEmits(['toggle', 'add', 'delete', 'rename'])

// ========== 添加标签对话框 ==========
const showAddDialog = ref(false)
const newTagName = ref('')

function openAddDialog() {
  newTagName.value = ''
  showAddDialog.value = true
}

function confirmAdd() {
  const name = newTagName.value.trim()
  if (!name) return
  emit('add', props.node.id, name)
  showAddDialog.value = false
}

// ========== 编辑标签对话框 ==========
const showEditDialog = ref(false)
const editTagName = ref('')

function openEditDialog() {
  editTagName.value = props.node.name
  showEditDialog.value = true
}

function confirmEdit() {
  const name = editTagName.value.trim()
  if (!name || name === props.node.name) {
    showEditDialog.value = false
    return
  }
  emit('rename', props.node.id, name)
  showEditDialog.value = false
}

// ========== 展开/折叠 ==========
function onToggle(id) {
  emit('toggle', id)
}
</script>

<template>
  <div class="tree-node-branch">
    <!-- 节点行 -->
    <div class="tree-node-wrapper">
      <div
        v-if="node.children?.length"
        class="tree-toggle"
        @click="onToggle(node.id)"
      >
        <n-icon size="14" :class="{ rotated: expandedNodes.has(node.id) }">
          <ChevronForwardOutline />
        </n-icon>
      </div>
      <div v-else class="tree-toggle placeholder"></div>

      <div class="tree-node root-node">
        <span class="node-label">{{ node.name }}</span>
      </div>

      <div class="node-actions">
        <button class="icon-btn-sm" title="编辑" @click="openEditDialog">
          <n-icon size="14"><CreateOutline /></n-icon>
        </button>
        <button class="icon-btn-sm" title="添加子标签" @click="openAddDialog">
          <n-icon size="14"><AddCircleOutline /></n-icon>
        </button>
        <n-popconfirm
          @positive-click="$emit('delete', node.id)"
          positive-text="确定"
          negative-text="取消"
        >
          <template #trigger>
            <button class="icon-btn-sm danger" title="删除">
              <n-icon size="14"><TrashOutline /></n-icon>
            </button>
          </template>
          确定删除标签「{{ node.name }}」及其子标签？
        </n-popconfirm>
      </div>
    </div>

    <!-- 子节点（递归） -->
    <div v-if="expandedNodes.has(node.id) && node.children?.length" class="tree-children">
      <TreeNodeItem
        v-for="child in node.children"
        :key="child.id"
        :node="child"
        :expanded-nodes="expandedNodes"
        @toggle="onToggle"
        @add="(parentId, name) => $emit('add', parentId, name)"
        @delete="(id) => $emit('delete', id)"
        @rename="(id, name) => $emit('rename', id, name)"
      />
    </div>
  </div>

  <!-- 添加子标签对话框 -->
  <n-modal
    v-model:show="showAddDialog"
    preset="dialog"
    title="添加子标签"
    :mask-closable="false"
    positive-text="确定"
    negative-text="取消"
    @positive-click="confirmAdd"
    style="max-width: 380px"
  >
    <div style="padding: 8px 0">
      <n-input
        v-model:value="newTagName"
        placeholder="请输入标签名称"
        @keyup.enter="confirmAdd"
      />
    </div>
  </n-modal>

  <!-- 编辑标签对话框 -->
  <n-modal
    v-model:show="showEditDialog"
    preset="dialog"
    title="编辑标签"
    :mask-closable="false"
    positive-text="确定"
    negative-text="取消"
    @positive-click="confirmEdit"
    style="max-width: 380px"
  >
    <div style="padding: 8px 0">
      <n-input
        v-model:value="editTagName"
        placeholder="请输入标签名称"
        @keyup.enter="confirmEdit"
      />
    </div>
  </n-modal>
</template>

<style scoped>
.tree-node-wrapper {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 0;
}

.tree-toggle {
  width: 20px;
  height: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: var(--text-tertiary);
  flex-shrink: 0;
}

.tree-toggle.placeholder {
  visibility: hidden;
}

.tree-toggle .n-icon {
  transition: transform var(--transition-fast);
}

.tree-toggle .n-icon.rotated {
  transform: rotate(90deg);
}

.tree-node {
  flex: 1;
  padding: 6px 12px;
  border-radius: var(--radius-sm);
  cursor: default;
  transition: background var(--transition-fast);
  min-width: 0;
}

.tree-node:hover {
  background: rgba(37, 99, 235, 0.08);
}

.root-node {
  font-weight: 600;
}

.node-label {
  font-size: 14px;
  color: var(--text-primary);
}

.tree-children {
  margin-left: 10px;
  padding-left: 10px;
  border-left: 1px solid var(--border-color);
}

.node-actions {
  display: flex;
  gap: 2px;
  opacity: 0;
  transition: opacity var(--transition-fast);
}

.tree-node-wrapper:hover .node-actions {
  opacity: 1;
}

.icon-btn-sm {
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 4px;
  border: none;
  background: transparent;
  color: var(--text-tertiary);
  cursor: pointer;
  transition: all var(--transition-fast);
}

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

.icon-btn-sm.danger:hover {
  color: var(--color-danger);
  background: rgba(239, 68, 68, 0.1);
}
</style>
