<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="isAllExpanded ? '折叠全部' : '展开全部'">
							<a-button type="text" size="small" @click="handleToggleExpand">
								<template #icon>
									<UnorderedListOutlined v-if="!isAllExpanded" />
									<OrderedListOutlined v-else />
								</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"
						@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-dropdown>
						<a-button type="link" size="small">
							<template #icon><MoreOutlined /></template>
							更多
						</a-button>
						<template #overlay>
							<a-menu>
								<a-menu-item @click="handleImport"> <ImportOutlined />导入权限 </a-menu-item>
								<a-menu-item @click="handleExport"> <ExportOutlined />导出权限 </a-menu-item>
								<a-menu-item @click="handleDownloadTemplate"> <DownloadOutlined />下载模板 </a-menu-item>
							</a-menu>
						</template>
					</a-dropdown>
					<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>

	<!-- 导入权限弹窗 -->
	<sc-import v-model:open="dialog.import" title="导入权限" :api="authApi.permission.import.post" :template-api="authApi.permission.downloadTemplate.get" filename="权限" @success="handleImportSuccess" />

	<!-- 导出权限弹窗 -->
	<sc-export v-model:open="dialog.export" title="导出权限" :api="handleExportApi" :default-filename="`权限列表_${Date.now()}`" :show-options="false" tip="导出当前选中或所有权限数据" @success="handleExportSuccess" />
</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, ImportOutlined, ExportOutlined, DownloadOutlined, MoreOutlined } from '@ant-design/icons-vue'
import { computed } from 'vue'
import saveForm from './components/SaveForm.vue'
import scImport from '@/components/scImport/index.vue'
import scExport from '@/components/scExport/index.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 dialog = ref({
	import: false,
	export: false,
})

// 树引用
const treeRef = ref()

// 是否全部展开
const isAllExpanded = computed(() => {
	const allKeys = getAllKeys(filteredMenuTree.value)
	return allKeys.length > 0 && expandedKeys.value.length === allKeys.length
})

// 切换展开/折叠
const handleToggleExpand = () => {
	if (isAllExpanded.value) {
		handleCollapseAll()
	} else {
		handleExpandAll()
	}
}

// 加载权限树
const loadMenuTree = async () => {
	try {
		loading.value = true
		const res = await authApi.permission.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.permission.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('保存成功')
}

// 导出权限
const handleExport = () => {
	dialog.value.export = true
}

// 导出API封装
const handleExportApi = async () => {
	return await authApi.permission.export.post({
		ids: checkedMenuKeys.value.length > 0 ? checkedMenuKeys.value : undefined,
	})
}

// 导出成功回调
const handleExportSuccess = () => {
	checkedMenuKeys.value = []
}

// 导入权限
const handleImport = () => {
	dialog.value.import = true
}

// 导入成功回调
const handleImportSuccess = () => {
	loadMenuTree()
}

// 下载模板
const handleDownloadTemplate = async () => {
	try {
		const blob = await authApi.permission.downloadTemplate.get()
		const url = window.URL.createObjectURL(blob)
		const link = document.createElement('a')
		link.href = url
		link.download = '权限导入模板.xlsx'
		document.body.appendChild(link)
		link.click()
		document.body.removeChild(link)
		window.URL.revokeObjectURL(url)
		message.success('下载成功')
	} catch (error) {
		console.error('下载模板失败:', error)
		message.error('下载失败')
	}
}

// 初始化
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: 2px 4px;
					transition: background-color 0.2s;
					display: flex;
					align-items: center;
					min-height: 28px;

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

				.ant-tree-switcher {
					color: rgba(0, 0, 0, 0.45);
					display: flex;
					align-items: center;
					min-width: 20px;
				}

				.ant-tree-iconEle {
					margin-right: 4px;
					flex-shrink: 0;
					display: flex;
					align-items: center;
				}

				.ant-tree-title {
					display: flex;
					align-items: center;
					flex: 1;
					min-width: 0;
				}
			}

			.tree-node-content {
				display: flex;
				align-items: center;
				gap: 4px;
				max-width: 100%;

				.tree-node-title {
					font-size: 13px;
					color: #262626;
					flex-shrink: 0;
					line-height: 1.4;
				}

				.tree-node-code {
					font-family: 'Consolas', 'Monaco', monospace;
					font-size: 11px;
					background: #f0f0f0;
					border: none;
					padding: 0 4px;
					border-radius: 2px;
					color: #595959;
					flex-shrink: 0;
					margin-right: 2px;
				}

				.tree-node-disabled {
					color: #ff4d4f;
					font-size: 12px;
					flex-shrink: 0;
				}
			}

			: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>
