<template>
	<page-container :title="$t(String($route.meta.title))" :sub-title="$t('pages.acl.role.subTitle')">
		<template #ops>
			<a-row>
				<a-col :span="16">
					<a-input-search
						v-model:value="key"
						:placeholder="$t('pages.acl.role.search.placeholder')"
						enter-button
						@search="loadRoles(1, 10, key)"
					/>
				</a-col>
				<a-col :span="8">
					<a-button type="primary" style="margin-left: 10px" @click="addOrEditRole()">
						<template #icon>
							<icon-font type="icon-plus" />
						</template>
						{{ $t('pages.acl.role.add') }}
					</a-button>
				</a-col>
			</a-row>
		</template>
		<div style="min-height: calc(100vh - 305px)">
			<a-table
				:columns="columns"
				:data-source="rolePage?.records"
				bordered
				:pagination="pagination"
				:loading="loading"
				row-key="key"
				@expand="tryLoadPermissions"
			>
				<template #expandedRowRender="{ record }">
					<permission-info-panel
						type="role"
						:ref-key="record.key"
						:name="record.name"
						:permissions="record.permissions"
					></permission-info-panel>
				</template>
				<template #bodyCell="{ column, record }">
					<template v-if="column.dataIndex === 'operation'">
						<a-button type="link" @click="addOrEditRole(record)">
							<template #icon>
								<icon-font type="icon-edit" />
							</template>
							{{ $t('pages.acl.role.edit') }}
						</a-button>
						<a-popconfirm
							:title="$t('pages.acl.role.confirm.delete.title', { name: record.name })"
							@confirm="deleteRole(record.key)"
						>
							<a-button type="link" danger style="margin-left: 10px">
								<template #icon>
									<icon-font type="icon-delete" />
								</template>
								{{ $t('pages.acl.role.delete') }}
							</a-button>
						</a-popconfirm>
					</template>
				</template>
			</a-table>
		</div>
		<form-drawer
			ref="roleForm"
			v-model="role"
			:title="roleFormTitle"
			:form-items="items"
			:disabled-fields="disabledFields"
			@ok="doAOrEditRole"
		></form-drawer>
	</page-container>
</template>
<script lang="ts" setup>
	import { api } from '@/api'
	import type { IPage } from '@/api/api'
	import PermissionInfoPanel from '../components/permission-info-panel.vue'
	import { notification } from 'ant-design-vue'
	import { useI18n } from 'vue-i18n'
	import FormDrawer from '@/components/form-render/form-drawer.vue'
	import { formItems } from './roleForm'
	import { FormDataType } from '@/components/form-render/form-render-types'

	const { t } = useI18n()
	const key = ref('')
	const loading = ref(false)
	const rolePage = ref<IPage<acl.Role>>()
	const loadRoles = (page?: number, size?: number, searchKey?: string) => {
		loading.value = true
		api.aclApi.role.roles(
			{
				page: page || rolePage.value?.current,
				size: size || rolePage.value?.size,
				key: searchKey || key.value,
			},
			(data) => {
				loading.value = false
				rolePage.value = data
			},
		)
	}
	const columns = [
		{
			title: t('pages.acl.role.table.columns.name'),
			dataIndex: 'name',
		},
		{
			title: t('pages.acl.role.table.columns.description'),
			dataIndex: 'description',
		},
		{
			title: t('pages.acl.role.table.columns.operation'),
			dataIndex: 'operation',
		},
	]
	const pagination = computed(() => {
		return {
			current: rolePage.value?.current,
			pageSize: rolePage.value?.size,
			total: rolePage.value?.total,
			onChange: (page: number, pageSize: number) => {
				loadRoles(page, pageSize, key.value)
			},
		}
	})

	loadRoles()

	const roleForm = ref<typeof FormDrawer>()
	const role = ref<Partial<acl.Role>>({})

	const roleFormTitle = computed(() => {
		return t(role.value.id ? 'pages.acl.role.edit' : 'pages.acl.role.add')
	})

	const disabledFields = computed(() => {
		return role.value.id ? ['key'] : []
	})

	const items = computed(() => {
		return formItems
	})

	const addOrEditRole = (r?: Record<string, unknown>) => {
		role.value = { ...r }
		roleForm.value?.show()
	}

	const doAOrEditRole = (role: FormDataType) => {
		api.aclApi.role.saveOrUpdateRole(role as unknown as acl.Role, () => {
			roleForm.value?.close()
			notification.success({
				message: t('pages.acl.role.notification.success'),
				description: t('pages.acl.role.notification.addOrEdit.description'),
				onClose: () => {
					loadRoles(1)
				},
			})
		})
	}

	const deleteRole = (key: string) => {
		api.aclApi.role.deleteRole(key, () => {
			notification.success({
				message: t('pages.acl.role.notification.success'),
				description: t('pages.acl.role.notification.delete.description'),
				onClose: () => {
					loadRoles(1)
				},
			})
		})
	}

	const tryLoadPermissions = (expanded: boolean, record: acl.Role & { permissions?: acl.Permission[] }) => {
		if (expanded && !record.permissions) {
			api.aclApi.role.permissions(record.key as unknown as string, (data) => {
				record.permissions = data
			})
		}
	}
</script>
