<script setup lang="ts">
import {
  NButton,
  NForm,
  NFormItem,
  NInput,
  NModal,
  NTree,
  type TreeOption,
  useDialog,
  useMessage,
} from 'naive-ui'
import { h, ref, watch } from 'vue'
import SvgIcon from '@/components/custom/svg-icon.vue'

const emit = defineEmits<{
  (e: 'update:category', node: any): void
}>()

const message = useMessage()
const dialog = useDialog()

// Mock Data - 模拟分类树数据
const treeData = ref<TreeOption[]>([
  {
    key: 'stage-1',
    label: '汉字听写',
    children: [
      {
        key: 'q-type-1',
        label: '请根据提示书写正确的汉字。',
        isLeaf: true,
      },
      {
        key: 'q-type-2',
        label: '请根据拼音书写同音字。',
        isLeaf: true,
      },
    ],
  },
  {
    key: 'stage-2',
    label: '汉字加一加',
    children: [
      {
        key: 'q-type-3',
        label: '请写出含有“”的汉字。',
        isLeaf: true,
      },
    ],
  },
  {
    key: 'poem',
    label: '词语大比拼',
    children: [
      {
        key: 'q-type-4',
        label: '词语听写',
        children: [
          {
            key: 'q-type-4-1',
            label: '请根据拼音书写正确的词语。',
            isLeaf: true,
          },
        ],
      },
      {
        key: 'q-type-5',
        label: '成语写一写',
        children: [
          {
            key: 'q-type-5-1',
            label: '请写出含有反义字的四字成语。',
            isLeaf: true,
          },
          {
            key: 'q-type-5-2',
            label: '请根据图片书写正确的成语',
            isLeaf: true,
          },
        ],
      },
    ],
  },
  {
    key: 'stage-extra-1',
    label: '换字组成语',
    children: [
      {
        key: 'q-type-extra-1',
        label: '请换一个字，组成新的成语。',
        isLeaf: true,
      },
    ],
  },
])

const selectedKeys = ref<string[]>([])
const expandedKeys = ref<string[]>(['root', 'stage-1'])

// Modal State
const showCategoryModal = ref(false)
const categoryModalType = ref<1 | 2>(1) // 1级或2级分类
const categoryForm = ref({ name: '' })

// 记录当前操作类型：add-root, add-child, edit
const categoryOperation = ref<'add-root' | 'add-child' | 'edit'>('add-root')
// 记录当前操作的目标节点（编辑时为该节点，添加子节点时为父节点）
const currentOperationNode = ref<TreeOption | null>(null)

// 递归查找节点
function findNodeByKey(key: string, nodes: TreeOption[]): TreeOption | null {
  for (const node of nodes) {
    if (node.key === key)
      return node
    if (node.children) {
      const found = findNodeByKey(key, node.children)
      if (found)
        return found
    }
  }
  return null
}

watch(selectedKeys, (newKeys) => {
  if (newKeys.length === 0) {
    emit('update:category', null)
    return
  }
  const key = newKeys[0]
  const node = findNodeByKey(key, treeData.value)
  if (node) {
    emit('update:category', {
      label: node.label,
      level: node.isLeaf ? 3 : 1,
      key: node.key,
      isLeaf: node.isLeaf,
      children: node.children,
    })
  }
  else {
    emit('update:category', null)
  }
})

// 打开新增根节点弹窗
function handleAddRootCategory() {
  categoryOperation.value = 'add-root'
  categoryModalType.value = 1
  categoryForm.value.name = ''
  currentOperationNode.value = null
  showCategoryModal.value = true
}

// 打开新增子节点弹窗
function handleAddChildCategory(parentNode: TreeOption) {
  categoryOperation.value = 'add-child'
  categoryModalType.value = 2 // 视为下一级
  categoryForm.value.name = ''
  currentOperationNode.value = parentNode
  showCategoryModal.value = true
}

// 打开编辑节点弹窗
function handleEditCategory(node: TreeOption) {
  categoryOperation.value = 'edit'
  categoryForm.value.name = node.label as string
  currentOperationNode.value = node
  showCategoryModal.value = true
}

// 递归删除节点 如果节点有子节点，无法删除
function deleteNode(nodes: TreeOption[], key: string | number): boolean {
  const index = nodes.findIndex(n => n.key === key)
  if (index !== -1) {
    // 检查是否有子节点
    if (nodes[index].children && nodes[index].children.length > 0) {
      throw new Error('该分类下有子分类，无法删除')
    }
    nodes.splice(index, 1)
    return true
  }
  for (const node of nodes) {
    if (node.children) {
      if (deleteNode(node.children, key))
        return true
    }
  }
  return false
}

function handleDeleteCategory(node: TreeOption) {
  dialog.warning({
    title: '警告',
    content: `确定要删除分类 "${node.label}" 吗？此操作无法撤销。`,
    positiveText: '确定',
    negativeText: '取消',
    onPositiveClick: () => {
      try {
        deleteNode(treeData.value, node.key!)
        // 如果删除的是当前选中的节点，清空选中
        if (selectedKeys.value.includes(node.key as string)) {
          selectedKeys.value = []
        }
        message.success('删除成功')
      }
      catch (error: any) {
        message.error(error.message || '删除失败')
      }
    },
  })
}

function submitCategory() {
  if (!categoryForm.value.name) {
    message.error('请输入分类名称')
    return
  }

  if (categoryOperation.value === 'add-root') {
    // 新增根节点
    const newKey = `root-${Date.now()}`
    treeData.value.push({
      key: newKey,
      label: categoryForm.value.name,
      children: [],
    })
    message.success('分类添加成功')
  }
  else if (categoryOperation.value === 'add-child' && currentOperationNode.value) {
    // 新增子节点
    if (!currentOperationNode.value.children) {
      currentOperationNode.value.children = []
    }
    // 确保父节点不再是叶子节点，否则无法展开显示子节点
    if (currentOperationNode.value.isLeaf) {
      currentOperationNode.value.isLeaf = false
    }
    const newKey = `node-${Date.now()}`
    // 如果是第三级（叶子），标记 isLeaf
    currentOperationNode.value.children.push({
      key: newKey,
      label: categoryForm.value.name,
      isLeaf: true,
    })
    // 展开父节点
    if (!expandedKeys.value.includes(currentOperationNode.value.key as string)) {
      expandedKeys.value.push(currentOperationNode.value.key as string)
    }
    message.success('子分类添加成功')
  }
  else if (categoryOperation.value === 'edit' && currentOperationNode.value) {
    // 编辑节点
    currentOperationNode.value.label = categoryForm.value.name
    message.success('分类修改成功')
  }

  showCategoryModal.value = false
}

// Tree Rendering
function renderPrefix({ option }: { option: TreeOption }) {
  // 根据层级或类型显示不同图标
  if (option.children && option.children.length > 0) {
    return h(SvgIcon, { icon: 'carbon:folder', class: 'text-gray-400 text-lg' })
  }
  // 如果明确标记为叶子节点，或者没有 children
  return h(SvgIcon, { icon: 'carbon:document', class: 'text-gray-400 text-lg' })
}

function renderSuffix({ option }: { option: TreeOption }) {
  // 悬浮时显示操作按钮
  return h(
    'div',
    {
      class: 'flex items-center gap-2 opacity-0 group-hover:opacity-100 transition-opacity',
      onClick: (e: Event) => e.stopPropagation(),
    },
    [
      h('div', {
        class: 'text-gray-400 hover:text-blue-500 cursor-pointer flex items-center',
        title: '编辑',
        onClick: (e: Event) => {
          e.stopPropagation()
          handleEditCategory(option)
        },
      }, [h(SvgIcon, { icon: 'carbon:edit', class: 'text-lg' })]),
      // 允许所有节点添加子节点，如果添加了子节点，它就变成文件夹
      h('div', {
        class: 'text-gray-400 hover:text-green-500 cursor-pointer flex items-center',
        title: '添加子分类',
        onClick: (e: Event) => {
          e.stopPropagation()
          handleAddChildCategory(option)
        },
      }, [h(SvgIcon, { icon: 'carbon:add', class: 'text-lg' })]),
      h('div', {
        class: 'text-gray-400 hover:text-red-500 cursor-pointer flex items-center',
        title: '删除',
        onClick: (e: Event) => {
          e.stopPropagation()
          handleDeleteCategory(option)
        },
      }, [h(SvgIcon, { icon: 'carbon:trash-can', class: 'text-lg' })]),
    ],
  )
}
</script>

<template>
  <div class="h-full flex flex-col border-r border-gray-100 bg-gray-50/30">
    <div class="flex items-center justify-between border-b border-gray-100 px-4 py-4">
      <span class="text-lg text-gray-700 font-bold">分类导航树</span>
      <NButton size="tiny" secondary type="primary" @click="handleAddRootCategory">
        <template #icon>
          <SvgIcon icon="ic:baseline-add" class="text-icon" />
        </template>
      </NButton>
    </div>

    <div class="flex-1 overflow-y-auto py-2">
      <NTree
        block-line :data="treeData" :selected-keys="selectedKeys" :expanded-keys="expandedKeys"
        :render-prefix="renderPrefix" :render-suffix="renderSuffix" selectable expand-on-click class="px-2"
        @update:selected-keys="(keys) => (selectedKeys = keys)"
        @update:expanded-keys="(keys) => (expandedKeys = keys)"
      />
    </div>

    <div class="border-t border-gray-100 bg-gray-50 p-3 text-xs text-gray-400">
      提示：请勿随意删除维护原有分类，三级分类为最终题目目录。
    </div>

    <!-- Add/Edit Category Modal -->
    <NModal
      v-model:show="showCategoryModal" preset="card"
      :title="categoryOperation === 'edit' ? '编辑分类' : `新增 ${categoryModalType} 级分类`" class="w-[500px]"
    >
      <NForm>
        <NFormItem label="分类显示名称">
          <NInput v-model:value="categoryForm.name" placeholder="请输入内容" />
        </NFormItem>
      </NForm>
      <template #footer>
        <div class="flex justify-end gap-3">
          <NButton @click="showCategoryModal = false">
            取消操作
          </NButton>
          <NButton type="primary" @click="submitCategory">
            确认提交
          </NButton>
        </div>
      </template>
    </NModal>
  </div>
</template>

<style scoped>
:deep(.n-tree-node-content__text) {
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 1;
  min-width: 0;
}

:deep(.n-tree-node--selected) {
  background-color: #eff6ff !important;
}

:deep(.n-tree-node--selected .n-tree-node-content__text) {
  color: #3b82f6;
}

/* Ensure icons in tree are visible on hover */
:deep(.n-tree-node-content:hover .group-hover\:opacity-100) {
  opacity: 1;
}

/* Custom group class for tree node content wrapper to handle hover state */
:deep(.n-tree-node-content) {
  @apply group;
}
</style>
