<template>
	<a-modal v-model:open="visible" :title="$t('common.searchMenu')" :footer="null" :width="600" :destroyOnClose="true" @cancel="handleClose">
		<div class="menu-search">
			<a-input v-model:value="searchKeyword" :placeholder="$t('common.searchPlaceholder')" size="large" allow-clear @input="handleSearch" @keydown="handleKeydown" ref="searchInputRef">
				<template #prefix>
					<SearchOutlined />
				</template>
			</a-input>

			<div v-if="searchResults.length > 0" class="search-results">
				<div v-for="(item, index) in searchResults" :key="item.path" class="result-item" :class="{ active: selectedIndex === index }" @click="handleSelect(item)" @mouseenter="selectedIndex = index">
					<div class="result-icon">
						<component :is="item.icon || 'MenuOutlined'" />
					</div>
					<div class="result-content">
						<div class="result-title">{{ item.title }}</div>
						<div v-if="item.breadcrumbs" class="result-path">
							{{ item.breadcrumbs }}
						</div>
					</div>
				</div>
			</div>

			<div v-else-if="searchKeyword" class="no-results">
				<a-empty :description="$t('common.noResults')" />
			</div>

			<div v-else class="search-tips">
				<div class="tip-title">{{ $t('common.searchTips') }}</div>
				<div class="tip-list">
					<div class="tip-item">
						<kbd>↑</kbd>
						<kbd>↓</kbd>
						<span>{{ $t('common.navigateResults') }}</span>
					</div>
					<div class="tip-item">
						<kbd>Enter</kbd>
						<span>{{ $t('common.selectResult') }}</span>
					</div>
					<div class="tip-item">
						<kbd>Esc</kbd>
						<span>{{ $t('common.closeSearch') }}</span>
					</div>
				</div>
			</div>
		</div>
	</a-modal>
</template>

<script setup>
import { ref, computed, watch, nextTick } from 'vue'
import { useRouter } from 'vue-router'
import { SearchOutlined, MenuOutlined } from '@ant-design/icons-vue'
import { useUserStore } from '@/stores/modules/user'
import { useI18n } from 'vue-i18n'

// 定义组件名称
defineOptions({
	name: 'MenuSearch',
})

const { t } = useI18n()
const router = useRouter()
const userStore = useUserStore()

const visible = defineModel('visible', { type: Boolean, default: false })
const searchKeyword = ref('')
const searchResults = ref([])
const selectedIndex = ref(0)
const searchInputRef = ref(null)

// 将扁平化的菜单数据转换为可搜索格式
function flattenMenus(menus, breadcrumbs = []) {
	const result = []

	menus.forEach((menu) => {
		if (menu.hidden) return

		const currentBreadcrumbs = [...breadcrumbs, menu.title]

		// 如果有路径且不是外部链接，添加到搜索结果
		if (menu.path && !menu.path.startsWith('http')) {
			result.push({
				title: menu.title,
				path: menu.path,
				icon: menu.icon,
				breadcrumbs: currentBreadcrumbs.join(' / '),
			})
		}

		// 递归处理子菜单
		if (menu.children && menu.children.length > 0) {
			const children = flattenMenus(menu.children, currentBreadcrumbs)
			result.push(...children)
		}
	})

	return result
}

// 获取所有菜单项
const allMenus = computed(() => {
	const menus = userStore.menu || []
	return flattenMenus(menus)
})

// 执行搜索
function handleSearch() {
	if (!searchKeyword.value.trim()) {
		searchResults.value = []
		selectedIndex.value = 0
		return
	}

	const keyword = searchKeyword.value.toLowerCase().trim()
	searchResults.value = allMenus.value.filter((menu) => {
		return menu.title.toLowerCase().includes(keyword) || menu.breadcrumbs.toLowerCase().includes(keyword)
	})

	selectedIndex.value = 0
}

// 键盘导航
function handleKeydown(e) {
	if (!searchResults.value.length) return

	switch (e.key) {
		case 'ArrowUp':
			e.preventDefault()
			selectedIndex.value = selectedIndex.value > 0 ? selectedIndex.value - 1 : searchResults.value.length - 1
			break
		case 'ArrowDown':
			e.preventDefault()
			selectedIndex.value = selectedIndex.value < searchResults.value.length - 1 ? selectedIndex.value + 1 : 0
			break
		case 'Enter':
			e.preventDefault()
			if (searchResults.value[selectedIndex.value]) {
				handleSelect(searchResults.value[selectedIndex.value])
			}
			break
		case 'Escape':
			e.preventDefault()
			handleClose()
			break
	}
}

// 选择菜单项
function handleSelect(item) {
	visible.value = false
	router.push(item.path)
}

// 关闭搜索弹窗
function handleClose() {
	visible.value = false
	searchKeyword.value = ''
	searchResults.value = []
	selectedIndex.value = 0
}

// 监听弹窗显示，自动聚焦输入框
watch(visible, (newVal) => {
	if (newVal) {
		nextTick(() => {
			searchInputRef.value?.focus()
		})
	} else {
		handleClose()
	}
})
</script>

<style scoped lang="scss">
.menu-search {
	.search-results {
		max-height: 400px;
		overflow-y: auto;
		margin-top: 16px;
		border: 1px solid #f0f0f0;
		border-radius: 4px;

		.result-item {
			display: flex;
			align-items: center;
			padding: 12px 16px;
			cursor: pointer;
			transition: background-color 0.2s;
			border-bottom: 1px solid #f0f0f0;

			&:last-child {
				border-bottom: none;
			}

			&:hover,
			&.active {
				background-color: #e6f7ff;
			}

			.result-icon {
				margin-right: 12px;
				font-size: 16px;
				color: #1890ff;
			}

			.result-content {
				flex: 1;
				min-width: 0;

				.result-title {
					font-size: 14px;
					color: #333;
					margin-bottom: 4px;
					font-weight: 500;
				}

				.result-path {
					font-size: 12px;
					color: #999;
					overflow: hidden;
					text-overflow: ellipsis;
					white-space: nowrap;
				}
			}
		}
	}

	.no-results {
		margin-top: 40px;
	}

	.search-tips {
		margin-top: 20px;

		.tip-title {
			font-size: 14px;
			color: #666;
			margin-bottom: 16px;
			text-align: center;
		}

		.tip-list {
			display: flex;
			flex-direction: row;
			gap: 12px;

			.tip-item {
				display: flex;
				align-items: center;
				gap: 12px;
				padding: 8px 16px;
				background-color: #f5f5f5;
				border-radius: 4px;

				kbd {
					display: inline-block;
					padding: 2px 8px;
					font-size: 12px;
					font-family: inherit;
					line-height: 1;
					color: #333;
					background-color: #fff;
					border: 1px solid #d9d9d9;
					border-radius: 2px;
					box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
				}

				span {
					font-size: 13px;
					color: #666;
				}
			}
		}
	}
}
</style>
