<template>
	<el-dialog 
		:close-on-click-modal="false" 
		title="分配工作台菜单" 
		width="800px" 
		draggable 
		v-model="visible"
	>
		<div v-loading="loading">
			<div class="mb-4">
				<el-alert 
					title="请选择该角色可以访问的工作台菜单项" 
					type="info" 
					:closable="false"
					show-icon
				/>
			</div>
			
			<div v-if="workbenchData.length > 0" class="workbench-menu-list">
				<div 
					v-for="item in workbenchData" 
					:key="item.id" 
					class="menu-item"
				>
					<div class="menu-header">
						<div class="menu-info">
							<el-checkbox 
								:model-value="isModuleAllSelected(item)"
								:indeterminate="isModuleIndeterminate(item)"
								@change="toggleModuleSelection(item)"
								class="menu-checkbox"
							/>
							<div class="menu-title">{{ item.title }}</div>
							<div class="menu-name">{{ item.name }}</div>
						</div>
					</div>
					
					<div v-if="item.content && item.content.data" class="menu-content">
						<div class="content-grid">
							<div 
								v-for="(dataItem, index) in item.content.data" 
								:key="dataItem.id || index"
								class="content-item"
								:class="{ 'selected': selectedMenuIds.includes(dataItem.id) }"
								@click="toggleMenuItem(dataItem.id)"
							>
								<el-checkbox 
									:model-value="selectedMenuIds.includes(dataItem.id)"
									@change="toggleMenuItem(dataItem.id)"
									class="item-checkbox"
									@click.stop
								/>
								<div class="item-icon">
									<el-icon v-if="dataItem.icon" :size="20">
										<component :is="dataItem.icon" />
									</el-icon>
									<div v-else class="default-icon">
										<el-icon :size="20"><Menu /></el-icon>
									</div>
								</div>
								<div class="item-name">{{ dataItem.name }}</div>
								<div v-if="dataItem.badge" class="item-badge">{{ dataItem.badge }}</div>
							</div>
						</div>
					</div>
				</div>
			</div>
			
			<div v-else class="empty-state">
				<el-empty description="暂无工作台菜单数据" />
			</div>
		</div>
		
		<template #footer>
			<span class="dialog-footer">
				<el-button @click="visible = false">{{ $t('common.cancelButtonText') }}</el-button>
				<el-button @click="onSubmit" type="primary" :disabled="loading">{{ $t('common.confirmButtonText') }}</el-button>
			</span>
		</template>
	</el-dialog>
</template>

<script lang="ts" name="workbenchMenuDialog" setup>
import { useMessage } from '/@/hooks/message';
import { getWorkbenchDecorate, updateRoleWorkbenchMenus, getObj } from '/@/api/app/approle';
import { useI18n } from 'vue-i18n';
import { Menu } from '@element-plus/icons-vue';

// 定义子组件向父组件传值/事件
const emit = defineEmits(['refresh']);

const { t } = useI18n();

// 定义变量内容
const visible = ref(false);
const loading = ref(false);
const currentRoleId = ref('');

// 工作台数据
const workbenchData = ref<any[]>([]);
const selectedMenuIds = ref<string[]>([]);

// 打开弹窗
const openDialog = async (roleId: string) => {
	visible.value = true;
	currentRoleId.value = roleId;
	selectedMenuIds.value = [];
	
	try {
		loading.value = true;
		
		// 获取工作台装饰数据
		await getWorkbenchData();
		
		// 获取角色当前的菜单配置
		if (roleId) {
			await getRoleMenuData(roleId);
		}
	} catch (err: any) {
		useMessage().error(err.msg || '获取数据失败');
	} finally {
		loading.value = false;
	}
};

// 获取工作台装饰数据
const getWorkbenchData = async () => {
	try {
		const response = await getWorkbenchDecorate();
		const { data } = response;
		
		if (data && data.pageData) {
			const pageData = JSON.parse(data.pageData);
			workbenchData.value = pageData
		}
	} catch (err: any) {
		console.error('获取工作台数据失败:', err);
		throw err;
	}
};

// 获取角色当前的菜单数据
const getRoleMenuData = async (roleId: string) => {
	try {
		const { data } = await getObj(roleId);
		
		if (data && data.menuId) {
			selectedMenuIds.value = data.menuId.split(',').filter((id: string) => id.trim());
		}
	} catch (err: any) {
		console.error('获取角色菜单数据失败:', err);
		// 不抛出错误，允许继续操作
	}
};

// 切换菜单项选择状态
const toggleMenuItem = (menuId: string) => {
	const index = selectedMenuIds.value.indexOf(menuId);
	if (index > -1) {
		selectedMenuIds.value.splice(index, 1);
	} else {
		selectedMenuIds.value.push(menuId);
	}
};

// 检查模块是否全选
const isModuleAllSelected = (module: any) => {
	if (!module.content || !module.content.data || module.content.data.length === 0) {
		return false;
	}
	return module.content.data.every((item: any) => selectedMenuIds.value.includes(item.id));
};

// 检查模块是否部分选中
const isModuleIndeterminate = (module: any) => {
	if (!module.content || !module.content.data || module.content.data.length === 0) {
		return false;
	}
	const selectedCount = module.content.data.filter((item: any) => selectedMenuIds.value.includes(item.id)).length;
	return selectedCount > 0 && selectedCount < module.content.data.length;
};

// 切换模块选择状态（全选/取消全选）
const toggleModuleSelection = (module: any) => {
	if (!module.content || !module.content.data) {
		return;
	}
	
	const isAllSelected = isModuleAllSelected(module);
	
	if (isAllSelected) {
		// 取消选择该模块下的所有项
		module.content.data.forEach((item: any) => {
			const index = selectedMenuIds.value.indexOf(item.id);
			if (index > -1) {
				selectedMenuIds.value.splice(index, 1);
			}
		});
	} else {
		// 选择该模块下的所有项
		module.content.data.forEach((item: any) => {
			if (!selectedMenuIds.value.includes(item.id)) {
				selectedMenuIds.value.push(item.id);
			}
		});
	}
};

// 提交
const onSubmit = async () => {
	try {
		loading.value = true;
		const menuId = selectedMenuIds.value.join(',');
		
		await updateRoleWorkbenchMenus(currentRoleId.value, menuId);
		
		useMessage().success('工作台菜单分配成功');
		visible.value = false;
		emit('refresh');
	} catch (err: any) {
		useMessage().error(err.msg || '分配失败');
	} finally {
		loading.value = false;
	}
};

// 暴露变量
defineExpose({
	openDialog,
});
</script>

<style lang="scss" scoped>
.workbench-menu-list {
	max-height: 500px;
	overflow-y: auto;
}

.menu-item {
	border: 1px solid #e4e7ed;
	border-radius: 8px;
	margin-bottom: 16px;
	padding: 16px;
	transition: all 0.3s ease;
}

.menu-header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	margin-bottom: 12px;
}

.menu-info {
	display: flex;
	align-items: center;
	gap: 12px;
}

.menu-checkbox {
	pointer-events: auto;
}

.menu-title {
	font-size: 16px;
	font-weight: 600;
	color: #303133;
}

.menu-name {
	font-size: 12px;
	color: #909399;
	background-color: #f5f7fa;
	padding: 2px 8px;
	border-radius: 4px;
}

.menu-content {
	border-top: 1px solid #f0f0f0;
	padding-top: 12px;
}

.content-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
	gap: 12px;
}

.content-item {
	display: flex;
	flex-direction: column;
	align-items: center;
	padding: 12px 8px;
	border-radius: 6px;
	background-color: #fafafa;
	position: relative;
	cursor: pointer;
	transition: all 0.3s ease;
	border: 1px solid transparent;
	
	&:hover {
		border-color: #409eff;
		box-shadow: 0 2px 8px rgba(64, 158, 255, 0.1);
	}
	
	&.selected {
		border-color: #409eff;
		background-color: #f0f9ff;
		box-shadow: 0 2px 8px rgba(64, 158, 255, 0.2);
	}
}

.item-checkbox {
	position: absolute;
	top: 4px;
	left: 4px;
	z-index: 1;
}

.item-icon {
	margin-bottom: 4px;
	margin-top: 16px;
	color: #409eff;
}

.default-icon {
	color: #909399;
}

.item-name {
	font-size: 12px;
	color: #606266;
	text-align: center;
	line-height: 1.2;
	margin-top: 4px;
}

.item-badge {
	position: absolute;
	top: -4px;
	right: -4px;
	background-color: #f56c6c;
	color: white;
	font-size: 10px;
	padding: 1px 4px;
	border-radius: 8px;
	min-width: 16px;
	text-align: center;
}

.empty-state {
	text-align: center;
	padding: 40px 0;
}

.dialog-footer {
	display: flex;
	justify-content: flex-end;
	gap: 12px;
}
</style> 