<script setup lang="ts">
import type { CategoryNode } from './CategoryTreeNode.vue'
import type { ContextMenuItem } from './ContextMenu.vue'

export interface ToolItem {
  key: string
  label: string
  icon: string
}

const props = withDefaults(defineProps<{
  tools?: ToolItem[]
  categories: CategoryNode[]
  activeToolKey?: string
  activeCategoryId?: string
  mode?: 'rail' | 'drawer'
  drawerOpen?: boolean
  width?: string
  side?: 'left' | 'right'
  loggedIn?: boolean
}>(), {
  mode: 'rail',
  drawerOpen: false,
  width: '300px',
  side: 'left',
  tools: () => [
    { key: 'home', label: '主页', icon: 'lucide:home' },
    { key: 'collect', label: '收藏', icon: 'lucide:star' },
    // { key: 'search', label: '搜索', icon: 'lucide:search' },
    // { key: 'tags', label: '标签', icon: 'lucide:tag' },
    // { key: 'highlights', label: '高亮', icon: 'lucide:highlighter' },
    // { key: 'archive', label: '归档', icon: 'lucide:archive' },
  ],
})

const emit = defineEmits<{
  selectTool: [key: string]
  selectCategory: [id: string]
  addCategory: [parentId: string | null]
  renameCategory: [id: string]
  deleteCategory: [id: string]
  moveCategory: [id: string]
  changeCover: [id: string]
  'update:drawerOpen': [v: boolean]
  dropCard: [categoryId: string | null, categoryName: string]
}>()

const expandedIds = ref<Set<string>>(new Set())

function expandAll(nodes: CategoryNode[]) {
  for (const node of nodes) {
    if (node.children?.length) {
      expandedIds.value.add(node.id)
      expandAll(node.children)
    }
  }
}

watch(() => props.categories, (nodes) => {
  if (nodes.length > 0) expandAll(nodes)
}, { immediate: true })

function toggleExpand(id: string) {
  const next = new Set(expandedIds.value)
  if (next.has(id)) next.delete(id)
  else next.add(id)
  expandedIds.value = next
}

function onSelectTool(key: string) {
  emit('selectTool', key)
}

function onSelectCategory(id: string) {
  emit('selectCategory', id)
}

const ctxVisible = ref(false)
const ctxX = ref(0)
const ctxY = ref(0)
const ctxNode = ref<CategoryNode | null>(null)

const ctxItems = computed<ContextMenuItem[]>(() => [
  { key: 'add-child', label: '新建子分类', icon: 'lucide:folder-plus' },
  { key: 'rename', label: '重命名', icon: 'lucide:pencil' },
  { key: 'change-cover', label: '更换封面', icon: 'lucide:image' },
  { key: 'move', label: '移动到…', icon: 'lucide:move' },
  { key: 'divider-1', label: '', divider: true },
  { key: 'delete', label: '删除', icon: 'lucide:trash-2', danger: true },
])

function onTreeContextMenu(node: CategoryNode, event: MouseEvent) {
  if (!props.loggedIn) return
  if (node.id === '__uncategorized__') return
  ctxNode.value = node
  ctxX.value = event.clientX
  ctxY.value = event.clientY
  ctxVisible.value = true
}

function onCtxSelect(key: string) {
  const node = ctxNode.value
  if (!node) return
  switch (key) {
    case 'add-child':
      emit('addCategory', node.id)
      break
    case 'rename':
      emit('renameCategory', node.id)
      break
    case 'change-cover':
      emit('changeCover', node.id)
      break
    case 'move':
      emit('moveCategory', node.id)
      break
    case 'delete':
      emit('deleteCategory', node.id)
      break
  }
}

function onCtxClose() {
  ctxVisible.value = false
  ctxNode.value = null
}

function onAddRoot() {
  emit('addCategory', null)
}
</script>

<template>
  <template v-if="mode === 'rail'">
    <aside class="left-sidebar">
      <!-- ── Toolbar ── -->
      <nav class="toolbar">
        <button
          v-for="tool in tools"
          :key="tool.key"
          type="button"
          class="tool-item"
          :class="{ active: activeToolKey === tool.key }"
          :title="tool.label"
          @click="onSelectTool(tool.key)"
        >
          <Icon :name="tool.icon" class="tool-icon" />
          <span class="tool-label">{{ tool.label }}</span>
        </button>
      </nav>

      <div class="divider" />

      <!-- ── Category section header ── -->
      <div class="cat-header">
        <span class="cat-title">
          分类
        </span>
        <button
          v-if="loggedIn"
          type="button"
          class="cat-add"
          title="新建分类"
          @click="onAddRoot"
        >
          <Icon name="lucide:plus" />
        </button>
      </div>

      <!-- ── Tree ── -->
      <div class="tree-scroll">
        <div v-if="categories.length === 0" class="empty-tip">
          <Icon name="lucide:folder-open" class="empty-icon" />
          <span>还没有分类</span>
          <button v-if="loggedIn" type="button" class="empty-btn" @click="onAddRoot">
            新建第一个
          </button>
        </div>
        <IndexCategoryTreeNode
          v-for="node in categories"
          :key="node.id"
          :node="node"
          :active-id="activeCategoryId"
          :expanded-ids="expandedIds"
          @select="onSelectCategory"
          @contextmenu="onTreeContextMenu"
          @toggle-expand="toggleExpand"
          @drop-card="(catId, catName) => emit('dropCard', catId, catName)"
        />
      </div>

      <IndexContextMenu
        v-if="loggedIn"
        :visible="ctxVisible"
        :x="ctxX"
        :y="ctxY"
        :items="ctxItems"
        @select="onCtxSelect"
        @close="onCtxClose"
      />
    </aside>
  </template>

  <BoDrawer
    v-else
    :open="drawerOpen"
    :side="side"
    :width="width"
    :z-index="200"
    @update:open="(v: boolean) => emit('update:drawerOpen', v)"
  >
    <aside class="left-sidebar">
      <!-- ── Toolbar ── -->
      <nav class="toolbar">
        <button
          v-for="tool in tools"
          :key="tool.key"
          type="button"
          class="tool-item"
          :class="{ active: activeToolKey === tool.key }"
          :title="tool.label"
          @click="onSelectTool(tool.key)"
        >
          <Icon :name="tool.icon" class="tool-icon" />
          <span class="tool-label">{{ tool.label }}</span>
        </button>
      </nav>

      <div class="divider" />

      <!-- ── Category section header ── -->
      <div class="cat-header">
        <span class="cat-title">
          分类
        </span>
        <button
          v-if="loggedIn"
          type="button"
          class="cat-add"
          title="新建分类"
          @click="onAddRoot"
        >
          <Icon name="lucide:plus" />
        </button>
      </div>

      <!-- ── Tree ── -->
      <div class="tree-scroll">
        <div v-if="categories.length === 0" class="empty-tip">
          <Icon name="lucide:folder-open" class="empty-icon" />
          <span>还没有分类</span>
          <button v-if="loggedIn" type="button" class="empty-btn" @click="onAddRoot">
            新建第一个
          </button>
        </div>
        <IndexCategoryTreeNode
          v-for="node in categories"
          :key="node.id"
          :node="node"
          :active-id="activeCategoryId"
          :expanded-ids="expandedIds"
          @select="onSelectCategory"
          @contextmenu="onTreeContextMenu"
          @toggle-expand="toggleExpand"
          @drop-card="(catId, catName) => emit('dropCard', catId, catName)"
        />
      </div>

      <IndexContextMenu
        v-if="loggedIn"
        :visible="ctxVisible"
        :x="ctxX"
        :y="ctxY"
        :items="ctxItems"
        @select="onCtxSelect"
        @close="onCtxClose"
      />
    </aside>
  </BoDrawer>
</template>

<style scoped>
.left-sidebar {
  display: flex;
  flex-direction: column;
  height: 100%;
  background: rgba(250, 249, 245, 0.6);
  border-right: 1px solid var(--color-hairline);
  backdrop-filter: blur(8px);
}

/* ── Toolbar ── */

.toolbar {
  display: flex;
  flex-direction: column;
  padding: 12px 10px 8px;
  gap: 2px;
}

.tool-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 9px 12px;
  border-radius: 8px;
  background: none;
  border: none;
  cursor: pointer;
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 500;
  color: var(--color-body);
  text-align: left;
  width: 100%;
  transition: background 0.12s ease, color 0.12s ease;
}

.tool-item:hover {
  background: var(--color-surface-soft);
  color: var(--color-ink);
}

.tool-item.active {
  background: var(--color-surface-card);
  color: var(--color-ink);
}

.tool-item.active .tool-icon {
  color: var(--color-primary);
}

.tool-icon {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  color: var(--color-muted);
  transition: color 0.12s ease;
}

.tool-item:hover .tool-icon {
  color: var(--color-ink);
}

.tool-label {
  flex: 1;
}

/* ── Divider ── */

.divider {
  height: 1px;
  background: var(--color-hairline);
  margin: 4px 16px 8px;
}

/* ── Category header ── */

.cat-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 6px 16px 8px;
}

.cat-title {
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--color-muted);
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.cat-total {
  font-size: 10px;
  font-weight: 500;
  color: var(--color-on-primary, #fff);
  background: var(--color-primary);
  min-width: 20px;
  height: 18px;
  padding: 0 5px;
  border-radius: 9999px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  letter-spacing: 0;
}

.cat-add {
  width: 22px;
  height: 22px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: 1px dashed var(--color-hairline);
  border-radius: 6px;
  cursor: pointer;
  color: var(--color-muted);
  transition: all 0.15s ease;
}

.cat-add :deep(svg) {
  width: 13px;
  height: 13px;
}

.cat-add:hover {
  background: var(--color-primary);
  color: var(--color-on-primary);
  border-color: var(--color-primary);
  border-style: solid;
  transform: rotate(90deg);
}

/* ── Tree scroll ── */

.tree-scroll {
  flex: 1;
  overflow-y: auto;
  padding: 4px 6px 16px 10px;
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.tree-scroll::-webkit-scrollbar {
  width: 6px;
}

.tree-scroll::-webkit-scrollbar-thumb {
  background: rgba(108, 106, 100, 0.18);
  border-radius: 4px;
}

.tree-scroll::-webkit-scrollbar-thumb:hover {
  background: rgba(108, 106, 100, 0.35);
}

/* ── Empty state ── */

.empty-tip {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 40px 16px;
  color: var(--color-muted-soft);
  font-size: 12px;
  text-align: center;
}

.empty-icon {
  width: 28px;
  height: 28px;
  color: var(--color-muted-soft);
  opacity: 0.5;
}

.empty-btn {
  background: none;
  border: 1px solid var(--color-hairline);
  border-radius: 9999px;
  padding: 6px 14px;
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 500;
  color: var(--color-primary);
  cursor: pointer;
  transition: all 0.15s ease;
}

.empty-btn:hover {
  background: var(--color-primary);
  color: var(--color-on-primary);
  border-color: var(--color-primary);
}
</style>
