<template>
  <div class="sidebar">
    <div class="sidebar-header">
      <div class="logo">
        <el-icon :size="28"><Setting /></el-icon>
        <h1>ConfTemplate</h1>
      </div>
      <p class="subtitle">云原生配置文件生成器</p>
    </div>

    <div class="search-box">
      <el-input
        v-model="searchQuery"
        placeholder="搜索中间件..."
        prefix-icon="Search"
        clearable
        size="default"
      />
    </div>

    <div class="nav-list">
      <template v-for="cat in filteredCategories" :key="cat.name">
        <div
          class="nav-category"
          :class="{ collapsed: !isExpanded(cat.name) }"
          @click="toggle(cat.name)"
        >
          <div class="nav-category-left">
            <el-icon><component :is="cat.icon" /></el-icon>
            <span>{{ cat.name }}</span>
            <span class="nav-category-count">{{ cat.items.length }}</span>
          </div>
          <el-icon class="nav-category-arrow" :class="{ open: isExpanded(cat.name) }">
            <ArrowRight />
          </el-icon>
        </div>
        <transition name="slide">
          <div v-show="isExpanded(cat.name)" class="nav-category-items">
            <div
              v-for="itemId in cat.items"
              :key="itemId"
              class="nav-item"
              :class="{ active: modelValue === itemId }"
              @click="$emit('update:modelValue', itemId); $emit('select')"
            >
              <el-icon><component :is="schemas[itemId].icon" /></el-icon>
              <div class="nav-item-info">
                <span class="nav-item-name">{{ schemas[itemId].name }}</span>
                <span class="nav-item-desc">{{ schemas[itemId].description }}</span>
              </div>
              <el-tag size="small" type="info">{{ schemas[itemId].format }}</el-tag>
            </div>
          </div>
        </transition>
      </template>

      <div v-if="filteredCategories.length === 0" class="no-results">
        <el-empty description="未找到匹配的中间件" :image-size="60" />
      </div>
    </div>

    <div class="sidebar-footer">
      <el-text size="small" type="info">v1.0.0 · 纯前端生成 · 59 个组件</el-text>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, watch } from 'vue'
import { ArrowRight } from '@element-plus/icons-vue'
import { schemas, categories } from '../schemas'

const props = defineProps({
  modelValue: String,
})

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

const searchQuery = ref('')

// Track which categories are expanded
const expandedSet = ref(new Set())

// Initialize: expand all categories, or auto-expand the one containing active item
function initExpanded() {
  const activeCat = categories.find(cat => cat.items.includes(props.modelValue))
  if (activeCat) {
    expandedSet.value = new Set([activeCat.name])
  } else {
    expandedSet.value = new Set(categories.map(c => c.name))
  }
}
initExpanded()

// When active item changes, auto-expand its category
watch(() => props.modelValue, (val) => {
  const cat = categories.find(c => c.items.includes(val))
  if (cat && !expandedSet.value.has(cat.name)) {
    expandedSet.value.add(cat.name)
  }
})

function isExpanded(name) {
  return expandedSet.value.has(name)
}

function toggle(name) {
  const s = new Set(expandedSet.value)
  if (s.has(name)) {
    s.delete(name)
  } else {
    s.add(name)
  }
  expandedSet.value = s
}

const filteredCategories = computed(() => {
  const q = searchQuery.value.toLowerCase().trim()
  if (!q) return categories

  return categories
    .map((cat) => ({
      ...cat,
      items: cat.items.filter((id) => {
        const s = schemas[id]
        return (
          s.name.toLowerCase().includes(q) ||
          s.description.toLowerCase().includes(q) ||
          s.category.toLowerCase().includes(q) ||
          id.toLowerCase().includes(q)
        )
      }),
    }))
    .filter((cat) => cat.items.length > 0)
})

// When searching, auto-expand all matching categories
watch(searchQuery, (q) => {
  if (q.trim()) {
    expandedSet.value = new Set(filteredCategories.value.map(c => c.name))
  }
})
</script>

<style scoped>
.sidebar {
  width: 280px;
  min-width: 280px;
  height: 100vh;
  background: #1a1a2e;
  color: #e0e0e0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.sidebar-header {
  padding: 20px 16px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.logo {
  display: flex;
  align-items: center;
  gap: 10px;
  color: #fff;
}

.logo h1 {
  font-size: 18px;
  font-weight: 700;
  margin: 0;
  background: linear-gradient(135deg, #667eea, #764ba2);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

.subtitle {
  font-size: 12px;
  color: #888;
  margin: 6px 0 0;
}

.search-box {
  padding: 12px 16px;
}

.search-box :deep(.el-input__wrapper) {
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.08);
  box-shadow: none;
  border-radius: 8px;
}

.search-box :deep(.el-input__inner) {
  color: #e0e0e0;
}

.search-box :deep(.el-input__inner::placeholder) {
  color: #666;
}

.nav-list {
  flex: 1;
  overflow-y: auto;
  padding: 4px 8px;
}

.nav-list::-webkit-scrollbar {
  width: 4px;
}

.nav-list::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.1);
  border-radius: 2px;
}

/* Category header — clickable */
.nav-category {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 8px 4px;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: #666;
  cursor: pointer;
  user-select: none;
  transition: color 0.2s;
  border-radius: 6px;
}

.nav-category:hover {
  color: #999;
}

.nav-category-left {
  display: flex;
  align-items: center;
  gap: 8px;
}

.nav-category-count {
  font-size: 10px;
  background: rgba(102, 126, 234, 0.2);
  color: #667eea;
  padding: 1px 6px;
  border-radius: 10px;
  font-weight: 700;
}

.nav-category-arrow {
  font-size: 12px;
  transition: transform 0.25s ease;
  color: #555;
}

.nav-category-arrow.open {
  transform: rotate(90deg);
}

/* Slide transition */
.nav-category-items {
  overflow: hidden;
}

.slide-enter-active,
.slide-leave-active {
  transition: all 0.25s ease;
}

.slide-enter-from,
.slide-leave-to {
  opacity: 0;
  max-height: 0;
}

.slide-enter-to,
.slide-leave-from {
  opacity: 1;
  max-height: 1000px;
}

/* Nav item */
.nav-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  margin: 2px 0;
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.2s;
  position: relative;
}

.nav-item:hover {
  background: rgba(255, 255, 255, 0.06);
}

.nav-item.active {
  background: rgba(102, 126, 234, 0.15);
  color: #667eea;
}

.nav-item.active::before {
  content: '';
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 3px;
  height: 60%;
  background: #667eea;
  border-radius: 0 2px 2px 0;
}

.nav-item-info {
  flex: 1;
  min-width: 0;
}

.nav-item-name {
  display: block;
  font-size: 13px;
  font-weight: 500;
  color: #e0e0e0;
}

.nav-item.active .nav-item-name {
  color: #667eea;
}

.nav-item-desc {
  display: block;
  font-size: 11px;
  color: #666;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.no-results {
  padding: 40px 0;
}

.sidebar-footer {
  padding: 12px 16px;
  text-align: center;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
}
</style>
