<template>
	<a-checkbox v-model:checked="checked" :indeterminate="indeterminate" :style="parentStyle">
		{{ props.menu.menuName }}
	</a-checkbox>

	<a-checkbox-group
		v-if="menuPermission"
		v-model:value="permissionsValue"
		:fieldNames="{ label: 'menuName', value: 'id' }"
		:options="menuPermission"
		:style="groupStyle"
	/>

	<menu-tree-item
		v-for="child of props.menu.children"
		:key="child.id"
		:menu="child"
		:permissions="props.permissions"
		@update:permissions="updatePermission"
	/>
</template>

<script lang="ts" setup>
import { SystemMenu } from '../../../../entity/system/system-menu'
import { computed } from 'vue'
import { AccountRolePermission } from '../../../../entity/account/account-role'

/**
 * 父级传过来的数据
 */
const props = defineProps<{ menu: SystemMenu; permissions: { [key: string]: AccountRolePermission } }>()

/**
 * 更改父容器组件
 */
const emit = defineEmits<{ (e: 'update:permissions', menuCode: string, permissions: string): void }>()

/**
 * 将子元素传递回来的值继续网上抛
 * @param menuCode
 * @param permission
 */
function updatePermission(menuCode: string, permission: string) {
	emit('update:permissions', menuCode, permission)
}

/**
 * 权限
 */
const menuPermission = computed(() => {
	if (!props.menu.permissions || props.menu.permissions.search(/^\s+$/) !== -1) {
		return []
	} else {
		return props.menu.permissions?.split(',') || []
	}
})

/**
 * 复选框是否选中
 */
const checked = computed({
	get: () => {
		return isMenuChecked(props.menu)
	},
	set: (checked: boolean) => {
		updateChildrenPermissions(props.menu, checked)
	}
})

/**
 * 检查menu是否选中
 * @param menu
 */
function isMenuChecked(menu: SystemMenu): boolean {
	let childAllChecked = menu.children.every(child => isMenuChecked(child))
	// 子元素是否全部选中
	const currentPermissions = menu.permissions ?? ''
	const permissionValue = props.permissions[menu.menuCode]?.permissionValue
	let currentCheck = permissionValue == currentPermissions

	return childAllChecked && currentCheck
}

/**
 * 更新菜单权限
 * @param menu
 * @param checked
 */
function updateChildrenPermissions(menu: SystemMenu, checked: boolean) {
	if (menu.children) {
		for (let child of menu.children) {
			updateChildrenPermissions(child, checked)
		}
	}
	updatePermission(menu.menuCode, checked ? menu.permissions ?? '' : '')
}

/**
 * 部分选中
 */
const indeterminate = computed(() => {
	return isMenuIndeterminate(props.menu)

	// let permissionValue = props.permissions[props.menu.menuCode]?.permissionValue
	// return !!permissionValue && permissionValue != props.menu.permissions
})

function isMenuIndeterminate(menu: SystemMenu): boolean {
	let childChecked = menu.children.map(child => isMenuIndeterminate(child))
	let someChecked = childChecked.some(checked => checked)
	let everyChecked = childChecked.every(checked => checked)
	if (menu.children.length > 0 && someChecked && !everyChecked) {
		return true
	}
	// 子元素是否全部选中
	const currentPermissions = menu.permissions ?? ''
	let permissionValue = props.permissions[menu.menuCode]?.permissionValue ?? ''
	let currentCheck = permissionValue == currentPermissions

	return !!permissionValue.length && !currentCheck
}

/**
 * 复选框组，权限值部分
 */
const permissionsValue = computed({
	get: () => {
		return props.permissions[props.menu.menuCode]?.permissionValue?.split(',') || []
	},
	set: (checkedValue: Array<string>) => {
		emit('update:permissions', props.menu.menuCode, checkedValue.join(','))
	}
})

//---------------------
// css 样式
// 菜单等级
const level = props.menu.menuLevel - 1
const marginLeft = level * 40
// 左侧边距
const parentStyle = {
	marginLeft: marginLeft + 'px',
	marginTop: 5 + 'px'
}
const groupStyle = {
	marginLeft: marginLeft + 30 + 'px'
}
</script>
<script lang="ts">
export default {
	name: 'MenuTreeItem'
}
</script>

<style scoped>
* {
	user-select: none;
}
</style>
