<!-- =============================================================================
// 企微IT智能服务台 — 快速回复组件（v5.3 终版 · 三层渐进导航）
// =============================================================================
// 导航结构：L1(7分类网格) → L2(chip子分类) → L3(条目列表) → Enter填入
// 键盘操作：Alt+1~7(L1) → 数字(L2/L3) → Enter填入 → ←/Backspace返回 → /搜索
// ============================================================================= -->

<template>
  <div class="qr-panel">
    <!-- ================================================================ -->
    <!-- 搜索栏（置顶） -->
    <!-- ================================================================ -->
    <div class="qr-search">
      <el-input
        ref="searchRef"
        v-model="searchQuery"
        placeholder="搜索快速回复 / Alt+目录数字"
        size="small"
        clearable
        :prefix-icon="SearchIcon"
        class="qr-search-input"
        @keydown.stop
      />
    </div>

    <!-- ================================================================ -->
    <!-- 面包屑导航 -->
    <!-- ================================================================ -->
    <div class="qr-breadcrumb">
      <span v-if="navState.l1Index >= 0" class="bc-back" @click="goBack">
        ← 返回
      </span>
      <template v-if="navState.l1Index >= 0">
        <span
          class="bc-item"
          :class="{ 'bc-active': navState.l2Index < 0 }"
          @click="resetToL1"
        >{{ catName(navState.l1Index) }}</span>
        <template v-if="navState.l2Index >= 0">
          <span class="bc-sep">›</span>
          <span class="bc-item bc-active">{{ subName(navState.l1Index, navState.l2Index) }}</span>
        </template>
      </template>
      <span class="bc-placeholder" v-else>选择一个分类开始浏览</span>
    </div>

    <!-- ================================================================ -->
    <!-- L1 一级分类：7列网格，按钮上下排列，强制一行 -->
    <!-- ================================================================ -->
    <div v-show="showL1" class="qr-l1-grid">
      <button
        v-for="(cat, i) in qrData"
        :key="i"
        class="qr-l1-btn"
        :class="{ active: navState.l1Index === i }"
        @click="selectL1(i)"
      >
        <span class="l1-num">{{ i + 1 }}</span>
        <span class="l1-name">{{ cat.name }}</span>
      </button>
    </div>

    <!-- ================================================================ -->
    <!-- L2 二级子分类：chip 横向流式 -->
    <!-- ================================================================ -->
    <div v-show="showL2" class="qr-l2-row">
      <button
        v-for="(sub, i) in currentSubs"
        :key="i"
        class="qr-l2-chip"
        :class="{ selected: navState.l2Index === i }"
        @click="selectL2(i)"
      >
        <span class="l2-num">{{ i + 1 }}</span>
        <span>{{ sub.name }}</span>
      </button>
    </div>

    <!-- ================================================================ -->
    <!-- L3 回复列表 -->
    <!-- ================================================================ -->
    <div v-show="showL3" class="qr-l3-scroll">
      <div v-if="filteredItems.length === 0" class="qr-empty">
        {{ searchQuery ? '无匹配结果' : '暂无回复模板' }}
      </div>
      <div v-else class="qr-l3-list">
        <div
          v-for="(item, i) in filteredItems"
          :key="i"
          class="qr-l3-item"
          :class="{ selected: navState.selectedIndex === i }"
          :ref="(el) => { if (el) itemRefs[i] = el as HTMLElement }"
          @click="selectL3(i)"
          @mouseenter="navState.selectedIndex = i"
        >
          <span class="qr-l3-num">{{ i + 1 }}</span>
          <div class="qr-l3-body">
            <div class="qr-l3-title">{{ item.title }}</div>
            <div class="qr-l3-content">{{ item.content }}</div>
          </div>
        </div>
      </div>
    </div>

    <!-- ================================================================ -->
    <!-- 选中预览条 -->
    <!-- ================================================================ -->
    <div v-if="selectedPreview" class="qr-selected-bar" @click="fillSelected">
      <span class="qr-selected-label">已选：</span>
      <span class="qr-selected-text">{{ selectedPreview }}</span>
      <span class="qr-selected-enter">Enter ↵ 填入</span>
    </div>

    <!-- ================================================================ -->
    <!-- 底部键盘指南 -->
    <!-- ================================================================ -->
    <div class="qr-keyboard-guide">
      <span><kbd>Alt+1-7</kbd> 一级</span>
      <span class="qr-guide-sep">|</span>
      <span><kbd>数字</kbd> 选子项</span>
      <span class="qr-guide-sep">|</span>
      <span><kbd>Enter</kbd> 填入</span>
      <span class="qr-guide-sep">|</span>
      <span><kbd>←</kbd> 返回</span>
      <span class="qr-guide-sep">|</span>
      <span><kbd>/</kbd> 搜索</span>
    </div>
  </div>
</template>

<!-- ==================================================================== -->
<!-- Script -->
<!-- ==================================================================== -->
<script setup lang="ts">
import { ref, computed, watch, nextTick, onMounted } from 'vue'
import { Search as SearchIcon } from '@element-plus/icons-vue'
import { useConversationStore } from '@/stores/conversation'
import { useKeyboardShortcuts } from '@/composables/useKeyboardShortcuts'
import { qrData, type QrCategory, type QrItem } from '@/data/qrData'

// ========================================================================
// Interface
// ========================================================================

interface Emits {
  (e: 'use-template', content: string): void
}

const emit = defineEmits<Emits>()

// ========================================================================
// State
// ========================================================================

const conversationStore = useConversationStore()
const searchRef = ref<InstanceType<typeof import('element-plus')['ElInput']> | null>(null)
const itemRefs = ref<Record<number, HTMLElement>>({})

/** 搜索关键词 */
const searchQuery = ref('')

/**
 * 导航状态机
 * l1Index: -1 = 初始/L1选择中; >=0 = 已选L1分类
 * l2Index: -1 = L2选择中; >=0 = 已选L2子分类，展示L3
 * selectedIndex: L3列表中的选中索引
 */
interface NavState {
  l1Index: number
  l2Index: number
  selectedIndex: number
}
const navState = ref<NavState>({
  l1Index: -1,
  l2Index: -1,
  selectedIndex: 0,
})

// ========================================================================
// Computed
// ========================================================================

/** 是否显示 L1 网格 */
const showL1 = computed(() => navState.value.l1Index < 0)

/** 是否显示 L2 chip 行 */
const showL2 = computed(() => navState.value.l1Index >= 0 && navState.value.l2Index < 0)

/** 是否显示 L3 列表 */
const showL3 = computed(() => navState.value.l1Index >= 0 && navState.value.l2Index >= 0)

/** 当前 L1 分类 */
const currentCategory = computed<QrCategory | null>(() => {
  if (navState.value.l1Index < 0) return null
  return qrData[navState.value.l1Index] ?? null
})

/** 当前 L2 子分类列表 */
const currentSubs = computed(() => {
  const cat = currentCategory.value
  return cat ? cat.subs : []
})

/** 当前 L3 条目列表 */
const currentItems = computed(() => {
  const cat = currentCategory.value
  if (!cat || navState.value.l2Index < 0) return []
  const sub = cat.subs[navState.value.l2Index]
  return sub ? sub.items : []
})

/** 搜索过滤后的 L3 条目 */
const filteredItems = computed<QrItem[]>(() => {
  const items = currentItems.value
  if (!searchQuery.value.trim()) return items
  const q = searchQuery.value.trim().toLowerCase()
  return items.filter(
    (item) =>
      item.title.toLowerCase().includes(q) ||
      item.content.toLowerCase().includes(q)
  )
})

/** 当前选中的条目文案预览 */
const selectedPreview = computed(() => {
  if (!showL3.value) return null
  const items = filteredItems.value
  if (items.length === 0) return null
  const idx = navState.value.selectedIndex
  if (idx < 0 || idx >= items.length) return null
  return items[idx].title
})

// ========================================================================
// Helpers
// ========================================================================

function catName(index: number): string {
  return qrData[index]?.name ?? ''
}

function subName(l1: number, l2: number): string {
  return qrData[l1]?.subs[l2]?.name ?? ''
}

// ========================================================================
// Navigation Methods
// ========================================================================

/** 选择 L1 分类 → 进入 L2 */
function selectL1(index: number): void {
  if (index < 0 || index >= qrData.length) return
  navState.value = { l1Index: index, l2Index: -1, selectedIndex: 0 }
  searchQuery.value = ''
}

/** 选择 L2 子分类 → 进入 L3 */
function selectL2(index: number): void {
  const cat = currentCategory.value
  if (!cat || index < 0 || index >= cat.subs.length) return
  navState.value.l2Index = index
  navState.value.selectedIndex = 0
  searchQuery.value = ''
  nextTick(() => scrollToSelected())
}

/** 点击 L3 条目 → 直接填入 */
function selectL3(index: number): void {
  const items = filteredItems.value
  if (index < 0 || index >= items.length) return
  fillContent(items[index].content)
}

/** 将选中条目填入输入框 */
function fillSelected(): void {
  const items = filteredItems.value
  const idx = navState.value.selectedIndex
  if (idx < 0 || idx >= items.length) return
  fillContent(items[idx].content)
}

/** 填入内容（含变量替换） */
function fillContent(content: string): void {
  const conv = conversationStore.currentConversation
  const variables: Record<string, string> = {}
  if (conv) {
    variables.employee_name = conv.employee_name || ''
    variables.department = conv.department || ''
    variables.position = conv.position || ''
  }

  let result = content
  for (const [key, value] of Object.entries(variables)) {
    result = result.replaceAll(`{${key}}`, value)
  }

  emit('use-template', result)
}

/** 返回上一级 */
function goBack(): void {
  if (navState.value.l2Index >= 0) {
    // L3 → L2
    navState.value.l2Index = -1
    navState.value.selectedIndex = 0
  } else if (navState.value.l1Index >= 0) {
    // L2 → L1
    navState.value.l1Index = -1
    navState.value.selectedIndex = 0
  }
}

/** 回到 L1（点击面包屑中的 L1） */
function resetToL1(): void {
  if (navState.value.l2Index >= 0) {
    navState.value.l2Index = -1
    navState.value.selectedIndex = 0
  }
}

/** 滚动选中项到视图 */
function scrollToSelected(): void {
  nextTick(() => {
    const el = itemRefs.value[navState.value.selectedIndex]
    if (el) {
      el.scrollIntoView({ block: 'nearest', behavior: 'smooth' })
    }
  })
}

// ========================================================================
// Keyboard Navigation (数字键选择)
// ========================================================================

function handleDigitKey(digit: number): void {
  if (showL1.value) {
    // L1: 数字键选择分类
    if (digit >= 1 && digit <= qrData.length) {
      selectL1(digit - 1)
    }
  } else if (showL2.value) {
    // L2: 数字键选择子分类
    const subs = currentSubs.value
    if (digit >= 1 && digit <= subs.length) {
      selectL2(digit - 1)
    }
  } else if (showL3.value) {
    // L3: 数字键选择条目
    const items = filteredItems.value
    if (digit >= 1 && digit <= items.length) {
      selectL3(digit - 1)
    }
  }
}

function navigateUpDown(direction: 'up' | 'down'): void {
  if (showL3.value) {
    const len = filteredItems.value.length
    if (len === 0) return
    if (direction === 'up') {
      navState.value.selectedIndex =
        navState.value.selectedIndex > 0 ? navState.value.selectedIndex - 1 : len - 1
    } else {
      navState.value.selectedIndex =
        navState.value.selectedIndex < len - 1 ? navState.value.selectedIndex + 1 : 0
    }
    scrollToSelected()
  }
}

function confirmSelection(): void {
  if (showL3.value) {
    fillSelected()
  }
}

function focusSearch(): void {
  searchRef.value?.focus()
}

// ========================================================================
// Keyboard Shortcuts Registration
// ========================================================================

// 注册 Alt+1~7 分类切换
function handleCategoryShortcut(index: number): void {
  if (index >= 0 && index < qrData.length) {
    selectL1(index)
  }
}

// 注册全局键盘快捷键
useKeyboardShortcuts({
  onQuickReplyCategory: handleCategoryShortcut,
  onQuickReplyDigit: handleDigitKey,
  onQuickReplyBack: goBack,
  onQuickReplyNavigate: navigateUpDown,
  onQuickReplyConfirm: confirmSelection,
  onFocusSearch: focusSearch,
})

// ========================================================================
// Watchers — 搜索词变化后重置选中
// ========================================================================

watch(searchQuery, () => {
  navState.value.selectedIndex = 0
})

// ========================================================================
// Lifecycle — 初始进入默认展示 L1
// ========================================================================

onMounted(() => {
  navState.value = { l1Index: -1, l2Index: -1, selectedIndex: 0 }
})
</script>

<!-- ==================================================================== -->
<!-- Styles -->
<!-- ==================================================================== -->
<style scoped>
.qr-panel {
  height: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* ---- 搜索栏 ---- */
.qr-search {
  padding: 6px 10px;
  flex-shrink: 0;
  border-bottom: 1px solid var(--border-color);
}
.qr-search-input {
  width: 100%;
}
.qr-search-input :deep(.el-input__wrapper) {
  background-color: var(--bg-tertiary);
  border-radius: var(--radius-md);
  box-shadow: none !important;
  border: 1px solid var(--border-light);
  font-size: 12px;
}
.qr-search-input :deep(.el-input__wrapper:hover) {
  border-color: var(--accent);
}
.qr-search-input :deep(.el-input__wrapper.is-focus) {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent) !important;
}
.qr-search-input :deep(.el-input__prefix-inner) {
  color: var(--text-tertiary);
}

/* ---- 面包屑 ---- */
.qr-breadcrumb {
  padding: 5px 10px;
  flex-shrink: 0;
  font-size: 11px;
  color: var(--text-secondary);
  display: flex;
  align-items: center;
  gap: 4px;
  flex-wrap: wrap;
  border-bottom: 1px solid var(--border-light);
  background: var(--bg-tertiary);
  min-height: 26px;
}
.bc-back {
  cursor: pointer;
  color: var(--accent);
  font-weight: 500;
  padding: 1px 6px;
  border-radius: 3px;
  transition: 0.2s;
}
.bc-back:hover {
  background: var(--accent-soft);
}
.bc-sep {
  color: var(--text-placeholder);
}
.bc-item {
  color: var(--text-secondary);
  transition: 0.2s;
  cursor: default;
}
.bc-item.bc-active {
  font-weight: 600;
  color: var(--text-primary);
}
.bc-item:not(.bc-active) {
  cursor: pointer;
}
.bc-item:not(.bc-active):hover {
  color: var(--accent);
}
.bc-placeholder {
  color: var(--text-tertiary);
  font-style: italic;
}

/* ---- L1 一级分类：7列网格，强制一行，按钮内上下排列 ---- */
.qr-l1-grid {
  padding: 4px 6px 6px;
  flex-shrink: 0;
  border-bottom: 1px solid var(--border-light);
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 4px;
}
.qr-l1-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  padding: 5px 2px;
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: 0.15s;
  font-size: 10px;
  color: var(--text-secondary);
  background: transparent;
  border: 1px solid var(--border-light);
  min-width: 0;
  overflow: hidden;
}
.qr-l1-btn:hover {
  background: var(--bg-hover);
  color: var(--text-primary);
}
.qr-l1-btn.active {
  background: var(--accent-soft);
  color: var(--accent);
  border-color: var(--accent);
  font-weight: 600;
}
.l1-num {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  border-radius: 4px;
  background: var(--bg-tertiary);
  color: var(--text-tertiary);
  font-size: 10px;
  font-weight: 700;
  flex-shrink: 0;
  border: 1px solid var(--border-light);
}
.qr-l1-btn.active .l1-num {
  background: var(--accent);
  color: var(--bg-secondary);
  border-color: var(--accent);
}
.l1-name {
  font-size: 10px;
  line-height: 1.2;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}

/* ---- L2 二级子分类 chip ---- */
.qr-l2-row {
  padding: 5px 8px;
  flex-shrink: 0;
  border-bottom: 1px solid var(--border-light);
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}
.qr-l2-chip {
  display: flex;
  align-items: center;
  gap: 3px;
  padding: 3px 8px;
  border-radius: 12px;
  cursor: pointer;
  transition: 0.15s;
  font-size: 11px;
  color: var(--text-secondary);
  background: var(--bg-tertiary);
  border: 1px solid var(--border-light);
  white-space: nowrap;
}
.qr-l2-chip:hover {
  background: var(--bg-hover);
  color: var(--text-primary);
  border-color: var(--border-light);
}
.qr-l2-chip.selected {
  background: var(--accent-soft);
  color: var(--accent);
  border-color: var(--accent);
  font-weight: 600;
}
.l2-num {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--bg-hover);
  color: var(--text-tertiary);
  font-size: 10px;
  font-weight: 600;
}
.qr-l2-chip.selected .l2-num {
  background: var(--accent);
  color: var(--bg-secondary);
}

/* ---- L3 列表 ---- */
.qr-l3-scroll {
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
  min-height: 0;
}
.qr-empty {
  text-align: center;
  padding: 24px 12px;
  color: var(--text-tertiary);
  font-size: 12px;
}
.qr-l3-list {
  padding: 2px 0;
}
.qr-l3-item {
  display: flex;
  gap: 6px;
  padding: 7px 10px;
  cursor: pointer;
  transition: background 0.15s;
  border-left: 3px solid transparent;
}
.qr-l3-item:hover {
  background: var(--bg-hover);
}
.qr-l3-item.selected {
  background: var(--accent-soft);
  border-left-color: var(--accent);
}
.qr-l3-num {
  flex-shrink: 0;
  width: 16px;
  text-align: right;
  font-size: 10px;
  color: var(--text-tertiary);
  margin-top: 1px;
}
.qr-l3-body {
  flex: 1;
  min-width: 0;
  overflow: hidden;
}
.qr-l3-title {
  font-size: 12px;
  font-weight: 500;
  color: var(--text-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.qr-l3-content {
  font-size: 11px;
  color: var(--text-secondary);
  margin-top: 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  line-height: 1.4;
}

/* ---- 选中预览条 ---- */
.qr-selected-bar {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 5px 10px;
  border-top: 1px solid var(--border-light);
  background: var(--bg-accent-soft);
  font-size: 11px;
  cursor: pointer;
  flex-shrink: 0;
  transition: background 0.15s;
}
.qr-selected-bar:hover {
  background: var(--bg-hover);
}
.qr-selected-label {
  color: var(--text-tertiary);
  flex-shrink: 0;
}
.qr-selected-text {
  flex: 1;
  color: var(--accent);
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.qr-selected-enter {
  color: var(--text-placeholder);
  font-size: 10px;
  flex-shrink: 0;
}

/* ---- 键盘指南 ---- */
.qr-keyboard-guide {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 4px 8px;
  border-top: 1px solid var(--border-light);
  background: var(--bg-secondary);
  flex-shrink: 0;
  font-size: 10px;
  color: var(--text-tertiary);
  flex-wrap: wrap;
}
.qr-keyboard-guide kbd {
  display: inline-block;
  padding: 0 3px;
  font-size: 9px;
  font-family: inherit;
  background: var(--bg-tertiary);
  border: 1px solid var(--border-color);
  border-radius: 2px;
  color: var(--text-secondary);
  line-height: 1.4;
}
.qr-guide-sep {
  color: var(--text-placeholder);
}
</style>
