<template>
	<div class="pages-sidebar-layout permission-page">
		<div class="left-box">
			<div class="header">
				<div class="search-wrapper">
					<a-input v-model:value="menuFilterText" placeholder="搜索权限名称或编码..." allow-clear
						@change="handleMenuSearch">
						<template #prefix>
							<SearchOutlined style="color: rgba(0, 0, 0, 0.45)" />
						</template>
					</a-input>
				</div>
				<div class="actions">
					<a-space size="small">
						<a-tooltip title="展开全部">
							<a-button type="text" size="small" @click="handleExpandAll">
								<template #icon><UnorderedListOutlined /></template>
							</a-button>
						</a-tooltip>
						<a-tooltip title="折叠全部">
							<a-button type="text" size="small" @click="handleCollapseAll">
								<template #icon><OrderedListOutlined /></template>
							</a-button>
						</a-tooltip>
						<a-tooltip title="添加根权限">
							<a-button type="text" size="small" @click="handleAdd(null)">
								<template #icon><PlusOutlined /></template>
							</a-button>
						</a-tooltip>
					</a-space>
				</div>
			</div>
			<div class="body">
				<a-spin :spinning="loading" :delay="200">
					<a-tree
						ref="treeRef"
						v-model:selectedKeys="selectedMenuKeys"
						v-model:checkedKeys="checkedMenuKeys"
						v-model:expandedKeys="expandedKeys"
						:tree-data="filteredMenuTree"
						:field-names="{ title: 'title', key: 'id', children: 'children' }"
						show-line
						checkable
						:check-strictly="false"
						:expand-on-click-node="false"
						block-node
						@select="onMenuSelect"
						@check="onMenuCheck">
						<template #icon="{ dataRef }">
							<FolderOutlined v-if="dataRef.type === 'menu' && dataRef.children?.length" />
							<FolderOpenOutlined v-else-if="dataRef.type === 'menu'" />
							<ApiOutlined v-else-if="dataRef.type === 'api'" />
							<ControlOutlined v-else />
						</template>
						<template #title="{ dataRef }">
							<span class="tree-node-content">
								<span class="tree-node-title">{{ dataRef.title }}</span>
								<a-tag v-if="dataRef.name" class="tree-node-code" size="small">{{ dataRef.name }}</a-tag>
								<a-tag v-if="dataRef.type !== 'menu'" :color="getTypeColor(dataRef.type)" size="small">
									{{ getTypeLabel(dataRef.type) }}
								</a-tag>
								<span v-if="!dataRef.status" class="tree-node-disabled">
									<StopOutlined />
								</span>
							</span>
						</template>
					</a-tree>
				</a-spin>
			</div>
		</div>
		<div class="right-box">
			<div class="header">
				<div class="title-wrapper">
					<span class="title">{{ selectedMenu?.title || '请选择权限节点' }}</span>
					<a-tag v-if="selectedMenu" :color="getTypeColor(selectedMenu.type)" size="small">
						{{ getTypeLabel(selectedMenu.type) }}
					</a-tag>
				</div>
				<a-space>
					<a-button v-if="checkedMenuKeys.length > 0" danger size="small" @click="handleDeleteBatch">
						<template #icon><DeleteOutlined /></template>
						批量删除 ({{ checkedMenuKeys.length }})
					</a-button>
					<a-button type="link" size="small" @click="handleRefresh">
						<template #icon><ReloadOutlined /></template>
						刷新
					</a-button>
				</a-space>
			</div>
			<div class="body">
				<a-spin :spinning="detailLoading" :delay="200">
					<save-form v-if="selectedMenu" :menu="menuTree" :menu-id="selectedMenu.id" :parent-id="parentId"
						@success="handleSaveSuccess" />
					<a-empty v-else description="请选择左侧权限节点后操作" :image-size="100" />
				</a-spin>
			</div>
		</div>
	</div>
</template>

<script setup>
import { ref, onMounted, nextTick } from 'vue'
import { message, Modal } from 'ant-design-vue'
import {
	SearchOutlined,
	ReloadOutlined,
	PlusOutlined,
	FolderOutlined,
	FolderOpenOutlined,
	ApiOutlined,
	ControlOutlined,
	UnorderedListOutlined,
	OrderedListOutlined,
	DeleteOutlined,
	StopOutlined
} from '@ant-design/icons-vue'
import saveForm from './components/SaveForm.vue'
import authApi from '@/api/auth'

defineOptions({
	name: 'authPermission'
})

// 菜单树数据
const menuTree = ref([])
const filteredMenuTree = ref([])
const selectedMenuKeys = ref([])
const checkedMenuKeys = ref([])
const expandedKeys = ref([])
const menuFilterText = ref('')

// 当前选中的菜单
const selectedMenu = ref(null)
const parentId = ref(null)

// 加载状态
const loading = ref(false)
const detailLoading = ref(false)

// 树引用
const treeRef = ref()

// 加载权限树
const loadMenuTree = async () => {
	try {
		loading.value = true
		const res = await authApi.permissions.tree.get()
		if (res.code === 200) {
			menuTree.value = res.data || []
			filteredMenuTree.value = res.data || []
			// 默认展开第一层
			expandAllKeys(menuTree.value, 1)
		} else {
			message.error(res.message || '加载权限树失败')
		}
	} catch (error) {
		console.error('加载权限树失败:', error)
		message.error('加载权限树失败')
	} finally {
		loading.value = false
	}
}

// 刷新
const handleRefresh = () => {
	loadMenuTree()
	if (selectedMenu.value) {
		// 重新获取当前选中的权限详情
		const menuNode = findMenuNode(menuTree.value, selectedMenu.value.id)
		if (menuNode) {
			selectedMenu.value = menuNode
		}
	}
}

// 搜索权限
const handleMenuSearch = (e) => {
	const keyword = (e.target?.value || '').trim()
	menuFilterText.value = keyword
	if (!keyword) {
		filteredMenuTree.value = menuTree.value
		return
	}

	// 递归过滤权限树（支持搜索名称和编码）
	const filterTree = (nodes) => {
		return nodes.reduce((acc, node) => {
			const titleMatch = node.title && node.title.toLowerCase().includes(keyword.toLowerCase())
			const nameMatch = node.name && node.name.toLowerCase().includes(keyword.toLowerCase())
			const isMatch = titleMatch || nameMatch
			const filteredChildren = node.children ? filterTree(node.children) : []

			if (isMatch || filteredChildren.length > 0) {
				acc.push({
					...node,
					children: filteredChildren.length > 0 ? filteredChildren : undefined
				})
			}
			return acc
		}, [])
	}

	filteredMenuTree.value = filterTree(menuTree.value)
	// 搜索时展开所有匹配节点
	expandAllKeys(filteredMenuTree.value)
}

// 查找权限节点
const findMenuNode = (tree, id) => {
	for (const node of tree) {
		if (node.id === id) {
			return node
		}
		if (node.children && node.children.length > 0) {
			const found = findMenuNode(node.children, id)
			if (found) return found
		}
	}
	return null
}

// 查找父节点ID
const findParentId = (tree, id) => {
	for (const node of tree) {
		if (node.children && node.children.length > 0) {
			const child = node.children.find(child => child.id === id)
			if (child) {
				return node.id
			}
			const found = findParentId(node.children, id)
			if (found !== null) return found
		}
	}
	return null
}

// 限制选择事件
const onMenuSelect = (selectedKeys, { selected }) => {
	if (selected) {
		const menuId = selectedKeys[0]
		const menuNode = findMenuNode(menuTree.value, menuId)
		selectedMenu.value = menuNode
		parentId.value = findParentId(menuTree.value, menuId)
	} else {
		selectedMenu.value = null
		parentId.value = null
	}
}

// 限制勾选事件
const onMenuCheck = (checkedKeys, info) => {
	console.log('checkedKeys:', checkedKeys, 'info:', info)
}

// 获取所有节点ID（用于展开/折叠）
const getAllKeys = (nodes) => {
	const keys = []
	const traverse = (items) => {
		items.forEach(item => {
			keys.push(item.id)
			if (item.children?.length) {
				traverse(item.children)
			}
		})
	}
	traverse(nodes)
	return keys
}

// 展开全部
const handleExpandAll = () => {
	expandedKeys.value = getAllKeys(filteredMenuTree.value)
}

// 折叠全部
const handleCollapseAll = () => {
	expandedKeys.value = []
}

// 自动展开指定层级的节点
const expandAllKeys = (nodes, maxLevel = 3) => {
	const keys = []
	const traverse = (items, level = 1) => {
		items.forEach(item => {
			if (level < maxLevel && item.children?.length) {
				keys.push(item.id)
				traverse(item.children, level + 1)
			}
		})
	}
	traverse(nodes)
	expandedKeys.value = keys
}

// 获取权限类型标签
const getTypeLabel = (type) => {
	const typeMap = {
		menu: '菜单',
		api: '接口',
		button: '按钮',
		url: '链接'
	}
	return typeMap[type] || type
}

// 获取权限类型颜色
const getTypeColor = (type) => {
	const colorMap = {
		menu: 'blue',
		api: 'green',
		button: 'orange',
		url: 'purple'
	}
	return colorMap[type] || 'default'
}

// 批量删除权限
const handleDeleteBatch = async () => {
	if (checkedMenuKeys.value.length === 0) {
		message.warning('请选择需要删除的权限')
		return
	}

	Modal.confirm({
		title: '确认删除',
		content: `确定删除已选择的 ${checkedMenuKeys.value.length} 个权限吗？`,
		okText: '删除',
		okType: 'danger',
		cancelText: '取消',
		onOk: async () => {
			try {
				const res = await authApi.permissions.batchDelete.post({ ids: checkedMenuKeys.value })
				if (res.code === 200) {
					message.success('删除成功')

					// 如果当前选中的权限被删除了，清空选择
					if (selectedMenu.value && checkedMenuKeys.value.includes(selectedMenu.value.id)) {
						selectedMenu.value = null
						selectedMenuKeys.value = []
					}

					checkedMenuKeys.value = []
					await loadMenuTree()
				} else {
					message.error(res.message || '删除失败')
				}
			} catch (error) {
				console.error('删除权限失败:', error)
				message.error('删除失败')
			}
		}
	})
}

// 保存成功回调
const handleSaveSuccess = async () => {
	await loadMenuTree()
	// 重新设置当前选中的权限
	if (selectedMenu.value) {
		const menuNode = findMenuNode(menuTree.value, selectedMenu.value.id)
		selectedMenu.value = menuNode
	}
	message.success('保存成功')
}

// 初始化
onMounted(() => {
	loadMenuTree()
})

defineExpose({
	loadMenuTree,
	handleExpandAll,
	handleCollapseAll
})
</script>

<style scoped lang="scss">
.permission-page {
	.left-box {
		.header {
			display: flex;
			justify-content: space-between;
			align-items: center;
			gap: 8px;

			.search-wrapper {
				flex: 1;
				min-width: 0;
			}

			.actions {
				flex-shrink: 0;
			}
		}

		.body {
			padding: 8px;

			:deep(.ant-tree) {
				background: transparent;

				.ant-tree-node-content-wrapper {
					padding: 4px 0;
					transition: background-color 0.2s;

					&:hover {
						background-color: #f5f5f5;
					}
				}

				.ant-tree-switcher {
					color: rgba(0, 0, 0, 0.45);
				}

				.ant-tree-iconEle {
					margin-right: 6px;
				}
			}

			.tree-node-content {
				display: inline-flex;
				align-items: center;
				gap: 6px;
				flex-wrap: wrap;

				.tree-node-title {
					font-size: 14px;
					color: #262626;
				}

				.tree-node-code {
					font-family: 'Consolas', 'Monaco', monospace;
					font-size: 11px;
					background: #f0f0f0;
					border: none;
					padding: 1px 6px;
					border-radius: 2px;
					color: #595959;
				}

				.tree-node-disabled {
					color: #ff4d4f;
					margin-left: 4px;
				}
			}

			:deep(.ant-tree-treenode-selected) {
				> .ant-tree-node-content-wrapper {
					background-color: #e6f7ff;
				}
			}
		}
	}

	.right-box {
		.header {
			display: flex;
			justify-content: space-between;
			align-items: center;
			padding: 12px 16px;

			.title-wrapper {
				display: flex;
				align-items: center;
				gap: 8px;

				.title {
					font-size: 16px;
					font-weight: 500;
					color: #262626;
				}
			}
		}

		.body {
			padding: 16px;
			overflow-y: auto;
			background: #fff;
		}
	}
}
</style>
