<template>
	<page-container :title="$t(String($route.meta.title))" :sub-title="$t('pages.acl.permission.subTitle')">
		<template #ops>
			<a-space>
				<a-button type="primary" @click="syncOpen = true">
					<template #icon>
						<icon-font type="icon-sync"></icon-font>
					</template>
					{{ $t('pages.acl.permission.sync') }}
				</a-button>
				<a-button type="primary" @click="addOrEditPermission()">
					<template #icon>
						<icon-font type="icon-plus" />
					</template>
					{{ $t('pages.acl.permission.add') }}
				</a-button>
			</a-space>
		</template>
		<div style="min-height: calc(100vh - 218px)">
			<vxe-table
				ref="xTree"
				border
				show-overflow
				size="medium"
				:loading="loading"
				:column-config="{ resizable: true }"
				:expand-config="{
					expandAll: true,
				}"
				:tree-config="{
					iconOpen: 'vxe-icon-square-minus',
					iconClose: 'vxe-icon-square-plus',
					transform: true,
					rowField: 'key',
					parentField: 'parentKey',
					expandAll: true,
					line: true,
				}"
				:data="permissions"
			>
				<vxe-column field="key" :title="$t('pages.acl.permission.table.columns.key')" tree-node></vxe-column>
				<vxe-column field="name" :title="$t('pages.acl.permission.table.columns.name')"></vxe-column>
				<vxe-column field="keyPath" :title="$t('pages.acl.permission.table.columns.keyPath')"></vxe-column>
				<vxe-column field="description" :title="$t('pages.acl.permission.table.columns.description')"></vxe-column>
				<vxe-column field="typeInfo.description" :title="$t('pages.acl.permission.table.columns.type')"></vxe-column>
				<vxe-column field="ops" :title="$t('pages.acl.permission.table.columns.operation')" width="350">
					<template #default="{ row }">
						<a-button type="link" @click="addOrEditPermission({ parentKey: row.key })">
							<template #icon>
								<icon-font type="icon-children" />
							</template>
							{{ $t('pages.acl.permission.addChild') }}
						</a-button>
						<a-button type="link" style="margin-left: 10px" @click="addOrEditPermission(row)">
							<template #icon>
								<icon-font type="icon-edit" />
							</template>
							{{ $t('pages.acl.permission.edit') }}
						</a-button>
						<a-popconfirm
							:title="$t('pages.acl.permission.confirm.delete.title', { name: row.name })"
							@confirm="deletePermission(row.keyPath)"
						>
							<a-button type="link" danger style="margin-left: 10px">
								<template #icon>
									<icon-font type="icon-delete" />
								</template>
								{{ $t('pages.acl.permission.delete') }}
							</a-button>
						</a-popconfirm>
					</template>
				</vxe-column>
			</vxe-table>
		</div>
		<form-drawer
			ref="permissionForm"
			v-model="permission"
			:title="permissionFormTitle"
			:form-items="items"
			:disabled-fields="disabledFields"
			:hidden-fields="hiddenFields"
			@ok="doAOrEditPermission"
		></form-drawer>
		<a-drawer
			v-model:open="syncOpen"
			:title="$t('pages.acl.permission.drawer.sync.title')"
			placement="right"
			:width="500"
			:footer-style="{ textAlign: 'right' }"
		>
			<a-tree
				default-expand-all
				:selectable="false"
				:tree-data="menuTrees"
				:field-names="{
					title: 'name',
				}"
			>
				<template #title="item">
					<icon-font :type="item.icon">{{ item }}</icon-font>
					{{ item.name }}
				</template>
			</a-tree>
			<template #footer>
				<a-button style="margin-right: 8px" type="primary" @click="syncAll">
					<template #icon>
						<icon-font type="icon-send"></icon-font>
					</template>
					{{ $t('pages.acl.permission.drawer.sync.submit') }}
				</a-button>
			</template>
		</a-drawer>
	</page-container>
</template>
<script lang="ts">
	export interface P {
		key: string
		name: string
		keyPath?: string
		icon: string
		parentKey?: string
		children: P[]
	}
</script>
<script lang="ts" setup>
	import type { VxeTableInstance } from 'vxe-table'
	import api from '@/api'
	import type { Codebook } from '@/api/api'
	import { notification } from 'ant-design-vue'
	import FormDrawer from '@/components/form-render/form-drawer.vue'
	import { formItems } from './permissionForm'
	import { FormValueType } from '@/components/form-render/form-render-types'
	import { menuTree } from '@/layout/components/menu'
	import XEUtils from 'xe-utils'
	import { useI18n } from 'vue-i18n'
	const { t } = useI18n()
	const loading = ref(true)
	const permissions = ref<Array<acl.Permission>>([])
	const xTree = ref<VxeTableInstance>()
	const loadPermissions = (force = false) => {
		loading.value = true
		api.aclApi.permission.permissions({ force: force }, (data) => {
			loading.value = false
			permissions.value = data
			nextTick(() => {
				xTree.value?.reloadData(data)
			})
		})
	}
	loadPermissions(true)

	const types = ref<Array<Codebook>>([])
	api.aclApi.permission.types((data) => {
		types.value = data
	})

	const permissionForm = ref<typeof FormDrawer>()
	const permission = ref<Partial<acl.Permission>>({})
	const permissionFormTitle = computed(() => {
		return t(permission.value.id ? 'pages.acl.permission.edit' : 'pages.acl.permission.add')
	})
	const disabledFields = computed(() => {
		const key = permission.value && permission.value.id ? 'key' : ''
		const parentKey = permission.value && permission.value.parentKey ? 'parentKey' : ''
		return [key, parentKey]
	})
	const hiddenFields = computed(() => {
		return permission.value && permission.value.parentKey ? [] : ['parentKey']
	})
	const items = computed(() => {
		return formItems(types.value)
	})
	const addOrEditPermission = (p?: Record<string, unknown>) => {
		permission.value = { ...{ type: 'MENU' }, ...p }
		permissionForm.value?.show()
	}
	const doAOrEditPermission = (_permission: Record<string, FormValueType>) => {
		const f = permission.value.id ? api.aclApi.permission.update : api.aclApi.permission.add
		f(_permission as unknown as acl.Permission, () => {
			permissionForm.value?.close()
			notification.success({
				message: t('pages.acl.permission.notification.success'),
				description: t('pages.acl.permission.notification.addOrEdit.description'),
				onClose: () => {
					loadPermissions(true)
				},
			})
		})
	}

	const deletePermission = (keyPath: string) => {
		api.aclApi.permission.deletePermission(keyPath, () => {
			notification.success({
				message: t('pages.acl.permission.notification.success'),
				description: t('pages.acl.permission.notification.delete.description'),
				onClose: () => {
					loadPermissions(true)
				},
			})
		})
	}

	const menuTrees = computed(() => {
		return menuTree()
	})
	const permissionInfos = computed(() => {
		return XEUtils.toTreeArray(XEUtils.clone(menuTrees.value, true), { clear: true }).map((item) => {
			return { ...item, ...{ description: item.name, type: 'MENU' } }
		})
	})
	const syncOpen = ref(false)
	const syncAll = () => {
		api.aclApi.permission.batchInitPermissions(permissionInfos.value as unknown as acl.Permission[], () => {
			syncOpen.value = false
			notification.success({
				message: t('pages.acl.permission.notification.success'),
				description: t('pages.acl.permission.notification.sync.description'),
				onClose: () => {
					loadPermissions(true)
				},
			})
		})
	}
</script>
