<template>
  <aside class="df-sidebar" :class="{ 'df-sidebar--collapsed': collapsed }">
    <!-- Logo(7b:brand 区只保留品牌标识,收缩按钮已移到底部操作区) -->
    <div class="sidebar-brand">
      <div class="brand-mark">
        <svg width="20" height="20" viewBox="0 0 24 24" fill="none">
          <path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z" fill="url(#brand-grad)" />
          <defs><linearGradient id="brand-grad" x1="3" y1="2" x2="21" y2="22">
            <stop stop-color="#7b6ff0"/><stop offset="1" stop-color="#5eaff0"/>
          </linearGradient></defs>
        </svg>
      </div>
      <span v-if="!collapsed" class="brand-text">DevFlow</span>
      <span v-if="!collapsed" class="brand-version">v0.1</span>
    </div>

    <!-- Navigation -->
    <nav class="sidebar-nav">
      <div class="nav-group">
        <span v-if="!collapsed" class="nav-group-label">{{ $t('nav.workspace') }}</span>
        <router-link
          v-for="item in primaryNav" :key="item.path"
          :to="item.path"
          class="nav-link"
          active-class="nav-link--active"
          :title="collapsed ? $t(item.label) : undefined"
        >
          <span class="nav-link-icon" v-html="item.svg"></span>
          <span v-if="!collapsed" class="nav-link-text">{{ $t(item.label) }}</span>
          <span v-if="!collapsed && item.badge" class="nav-link-badge">{{ item.badge }}</span>
        </router-link>
      </div>

      <div class="nav-divider"></div>

      <div class="nav-group">
        <span v-if="!collapsed" class="nav-group-label">{{ $t('nav.traceability') }}</span>
        <router-link
          v-for="item in secondaryNav" :key="item.path"
          :to="item.path"
          class="nav-link"
          active-class="nav-link--active"
          :title="collapsed ? $t(item.label) : undefined"
        >
          <span class="nav-link-icon" v-html="item.svg"></span>
          <span v-if="!collapsed" class="nav-link-text">{{ $t(item.label) }}</span>
          <span v-if="!collapsed && item.path === '/knowledge' && candidateCount > 0" class="nav-link-badge">{{ candidateCount }}</span>
        </router-link>
      </div>
    </nav>

    <!-- Footer -->
    <div class="sidebar-footer">
      <!-- AI 面板切换按钮 -->
      <button class="nav-link ai-toggle-btn" :class="{ 'ai-toggle-btn--active': aiStore.state.panelOpen }" @click="aiStore.togglePanel()" :title="collapsed ? $t('nav.aiPanel') : undefined">
        <span class="nav-link-icon ai-spark-icon">
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3l1.9 5.1L19 10l-5.1 1.9L12 17l-1.9-5.1L5 10l5.1-1.9z"/><path d="M19 3v3M21 4.5h-3M5 17v3M6.5 18.5h-3"/></svg>
        </span>
        <span v-if="!collapsed" class="nav-link-text">{{ $t('nav.aiPanel') }}</span>
        <span v-if="!collapsed" class="ai-toggle-shortcut">⌘I</span>
      </button>
      <router-link to="/settings" class="nav-link" active-class="nav-link--active" :title="collapsed ? $t('nav.settings') : undefined">
        <span class="nav-link-icon">
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 010 2.83 2 2 0 01-2.83 0l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 01-4 0v-.09A1.65 1.65 0 009 19.4a1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 01-2.83-2.83l.06-.06A1.65 1.65 0 004.68 15a1.65 1.65 0 00-1.51-1H3a2 2 0 010-4h.09A1.65 1.65 0 004.6 9a1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 012.83-2.83l.06.06A1.65 1.65 0 009 4.68a1.65 1.65 0 001-1.51V3a2 2 0 014 0v.09a1.65 1.65 0 001 1.51 1.65 1.65 0 001.82-.33l.06-.06a2 2 0 012.83 2.83l-.06.06A1.65 1.65 0 0019.4 9a1.65 1.65 0 001.51 1H21a2 2 0 010 4h-.09a1.65 1.65 0 00-1.51 1z"/></svg>
        </span>
        <span v-if="!collapsed" class="nav-link-text">{{ $t('nav.settings') }}</span>
      </router-link>
      <!-- 7b:收缩/展开切换按钮(最底部,快捷键 Ctrl+B 同效) -->
      <button class="nav-link collapse-toggle-btn" @click="toggleCollapsed" :title="collapsed ? $t('nav.expand') : $t('nav.collapse')">
        <span class="nav-link-icon">
          <svg v-if="!collapsed" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 18 9 12 15 6"/></svg>
          <svg v-else width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"/></svg>
        </span>
        <span v-if="!collapsed" class="nav-link-text">{{ $t('nav.collapse') }}</span>
        <span v-if="!collapsed" class="ai-toggle-shortcut">Ctrl+B</span>
      </button>
    </div>
  </aside>
</template>

<script setup lang="ts">
import { computed, ref, onMounted, onBeforeUnmount } from 'vue'
import { useAiStore } from '@/stores/ai'
import { useKnowledgeStore } from '@/stores/knowledge'
import { useAppSettingsStore } from '@/stores/appSettings'

const aiStore = useAiStore()
const knowledgeStore = useKnowledgeStore()
const appSettings = useAppSettingsStore()

// ── 侧边栏收缩状态(持久化到 appSettings,小窗口自动收缩) ──
// 展开 192px(文字+图标) / 收缩 56px(仅图标,hover tooltip 显示文字)
// 优先级:用户手动设置 > 小窗口自动收缩(≤768px)
const COLLAPSE_THRESHOLD = 768
const userCollapsed = ref(false)  // 用户手动设置的收缩状态
const isNarrowWindow = ref(false) // 小窗口自动收缩标记

const collapsed = computed(() => userCollapsed.value || isNarrowWindow.value)

// 持久化用户手动收缩状态
function toggleCollapsed() {
  userCollapsed.value = !userCollapsed.value
  void appSettings.set('df-sidebar-collapsed', userCollapsed.value)
}

// 监听窗口宽度:小窗口自动收缩(但不改变用户偏好)
function checkWindowWidth() {
  isNarrowWindow.value = window.innerWidth < COLLAPSE_THRESHOLD
}

// 7b:Ctrl+B / Cmd+B 切换侧边栏收缩(与 AI 面板 Ctrl+I 同款全局快捷键风格)
// 仅响应 ctrl 或 meta 任一修饰键(Cmd+I 同款),忽略纯 'b'(避免拦截正常输入)
function handleCollapseKeydown(e: KeyboardEvent) {
  if ((e.ctrlKey || e.metaKey) && (e.key === 'b' || e.key === 'B')) {
    e.preventDefault()
    toggleCollapsed()
  }
}

onMounted(async () => {
  // 恢复用户偏好(默认展开)
  userCollapsed.value = appSettings.get('df-sidebar-collapsed', false)
  // 检查当前窗口宽度
  checkWindowWidth()
  window.addEventListener('resize', checkWindowWidth)
  // Ctrl+B 切换快捷键
  window.addEventListener('keydown', handleCollapseKeydown)
})

onBeforeUnmount(() => {
  window.removeEventListener('resize', checkWindowWidth)
  window.removeEventListener('keydown', handleCollapseKeydown)
})

// 知识库候选数量(侧栏 badge)— 解包 computed 取值保持响应式
const candidateCount = computed(() => knowledgeStore.candidateCount)

const primaryNav = [
  { path: '/dashboard', label: 'nav.overview', badge: null,
    svg: '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><rect x="14" y="14" width="7" height="7" rx="1"/></svg>' },
  { path: '/ideas', label: 'nav.ideas', badge: null,
    svg: '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M9 18h6M10 22h4M12 2a7 7 0 014 12.74V17a1 1 0 01-1 1h-6a1 1 0 01-1-1v-2.26A7 7 0 0112 2z"/></svg>' },
  { path: '/projects', label: 'nav.projects', badge: null,
    svg: '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M22 19a2 2 0 01-2 2H4a2 2 0 01-2-2V5a2 2 0 012-2h5l2 3h9a2 2 0 012 2z"/></svg>' },
  { path: '/tasks', label: 'nav.tasks', badge: null,
    svg: '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"/></svg>' },
]

const secondaryNav = [
  { path: '/knowledge', label: 'nav.knowledge',
    svg: '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5A2.5 2.5 0 016.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 014 19.5v-15A2.5 2.5 0 016.5 2z"/></svg>' },
  { path: '/audit', label: 'nav.audit',
    svg: '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M9 11l3 3L22 4"/><path d="M21 12v7a2 2 0 01-2 2H5a2 2 0 01-2-2V5a2 2 0 012-2h11"/></svg>' },
]
</script>

<style scoped>
.df-sidebar {
  width: 192px;
  min-width: 192px;
  background: var(--df-sidebar-bg);
  border-right: 0.5px solid var(--df-border);
  display: flex;
  flex-direction: column;
  position: relative;
  user-select: none;
  transition: width 0.2s var(--df-ease), min-width 0.2s var(--df-ease);
}

/* 收缩态 */
.df-sidebar--collapsed {
  width: 56px;
  min-width: 56px;
}

/* — Logo — */
.sidebar-brand {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 14px 16px 12px;
  border-bottom: 0.5px solid var(--df-border);
}
.df-sidebar--collapsed .sidebar-brand {
  padding: 12px 10px 10px;
  justify-content: center;
}
.brand-mark {
  width: 28px; height: 28px;
  display: flex; align-items: center; justify-content: center;
  background: var(--df-accent-bg);
  border: 0.5px solid var(--df-border);
  flex-shrink: 0;
}
.df-sidebar--collapsed .brand-mark { width: 32px; height: 32px; }
.brand-text {
  font-size: 15px;
  font-weight: 500;
  letter-spacing: -0.3px;
  color: var(--df-text);
}
.brand-version {
  font-family: var(--df-font-mono);
  font-size: 10px;
  color: var(--df-text-dim);
  background: rgba(255,255,255,0.04);
  padding: 1px 6px;
  border-radius: var(--df-radius-xs);
}

/* 7b:收缩/展开切换按钮(底部操作区,复用 nav-link 样式 + button 重置)
   与 .ai-toggle-btn 同款 button-over-nav-link 模式:cursor/border/background/font 重置 */
.collapse-toggle-btn {
  cursor: pointer;
  border: none;
  background: transparent;
  width: 100%;
  font: inherit;
  text-align: left;
  appearance: none;
  -webkit-appearance: none;
  color: var(--df-text-secondary);
}
.collapse-toggle-btn:hover {
  background: var(--df-sidebar-hover);
  color: var(--df-text);
}

/* — Nav — */
.sidebar-nav { flex: 1; overflow-y: auto; padding: 8px 8px; }
.df-sidebar--collapsed .sidebar-nav { padding: 8px 6px; }

.nav-group { margin-bottom: 2px; }
.nav-group-label {
  display: block;
  padding: 8px 10px 4px;
  font-size: 9px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 1.2px;
  color: var(--df-text-dim);
}

.nav-divider {
  height: 0.5px;
  background: var(--df-border);
  margin: 6px 12px;
}
.df-sidebar--collapsed .nav-divider { margin: 4px 8px; }

.nav-link {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 10px;
  margin: 1px 0;
  border-radius: var(--df-radius-sm);
  color: var(--df-text-secondary);
  text-decoration: none;
  font-size: 12px;
  font-weight: 450;
  transition: all 0.18s var(--df-ease);
  position: relative;
}
.df-sidebar--collapsed .nav-link {
  justify-content: center;
  padding: 8px 0;
}

.nav-link:hover {
  background: var(--df-sidebar-hover);
  color: var(--df-text);
}
.nav-link--active {
  background: var(--df-sidebar-active);
  color: var(--df-accent);
  font-weight: 500;
}
.nav-link--active::before {
  content: '';
  position: absolute;
  left: -10px;
  top: 50%;
  transform: translateY(-50%);
  width: 3px;
  height: 16px;
  background: var(--df-accent);
  border-radius: 0 3px 3px 0;
}
/* 收缩态隐藏左边高亮线(居中布局无空间) */
.df-sidebar--collapsed .nav-link--active::before { display: none; }

.nav-link-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  opacity: 0.7;
  flex-shrink: 0;
}
.nav-link--active .nav-link-icon { opacity: 1; }

.nav-link-text { flex: 1; }

.nav-link-badge {
  font-family: var(--df-font-mono);
  font-size: 10px;
  font-weight: 500;
  padding: 1px 6px;
  border-radius: var(--df-radius);
  min-width: 18px;
  text-align: center;
  background: var(--df-accent);
  color: #fff;
  line-height: 1.4;
}

/* — AI Toggle Button — */
.ai-toggle-btn {
  cursor: pointer;
  border: none;
  background: transparent;
  width: 100%;
  font: inherit;
  text-align: left;
  appearance: none;
  -webkit-appearance: none;
}
.ai-toggle-btn--active {
  color: var(--df-accent);
  background: var(--df-sidebar-active);
}
/* AI 入口用星花图标 + 轻发光,与其他 nav-link 区分 */
.ai-spark-icon {
  opacity: 0.85;
}
.ai-toggle-btn:hover .ai-spark-icon,
.ai-toggle-btn--active .ai-spark-icon {
  opacity: 1;
  filter: drop-shadow(0 0 3px var(--df-accent));
}
.ai-toggle-shortcut {
  font-family: var(--df-font-mono);
  font-size: 9px;
  color: var(--df-text-dim);
  background: rgba(255,255,255,0.04);
  padding: 1px 5px;
  border-radius: var(--df-radius-sm);
}

/* — Footer — */
.sidebar-footer {
  padding: 6px 8px;
  border-top: 0.5px solid var(--df-border);
}

/* "系统就绪"装饰占位已移除(无真实就绪状态,见核查结论) */

/* ═══ Responsive ═══ */
/* 小窗口自动收缩由 JS resize listener 驱动(isNarrowWindow),无需 media query。
   原 768px media query 已删除,收缩逻辑统一走 collapsed class 控制。 */
</style>
