<template>
  <vab-dialog v-model="dialogFormVisible" append-to-body :title="title" width="500px" @close="close">
    <el-form ref="formRef" label-width="100px" :model="form" :rules="rules">
      <el-form-item label="角色名称" prop="roleName">
        <el-input v-model="form.roleName" placeholder="请输入角色名称" />
      </el-form-item>
      <el-form-item prop="roleKey">
        <template #label>
          <span>
            <el-tooltip content="控制器中定义的权限字符，如：@PreAuthorize(`@ss.hasRole('admin')`)" placement="top">
              <el-icon><question-filled /></el-icon>
            </el-tooltip>
            权限字符
          </span>
        </template>
        <el-input v-model="form.roleKey" placeholder="请输入权限字符" />
      </el-form-item>
      <el-form-item label="角色顺序" prop="roleSort">
        <el-input-number v-model="form.roleSort" controls-position="right" :min="0" />
      </el-form-item>
      <el-form-item label="状态">
        <el-radio-group v-model="form.status">
          <el-radio v-for="dict in sys_normal_disable" :key="dict.value" :value="dict.value">{{ dict.label }}</el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item label="菜单权限">
        <el-checkbox v-model="menuExpand" @change="handleCheckedTreeExpand($event)">展开/折叠</el-checkbox>
        <el-checkbox v-model="menuNodeAll" @change="handleCheckedTreeNodeAll($event)">全选/全不选</el-checkbox>
        <el-checkbox v-model="form.menuCheckStrictly" @change="handleCheckedTreeConnect($event)">父子联动</el-checkbox>
        <el-tree
          ref="menuRef"
          :check-strictly="!form.menuCheckStrictly"
          class="tree-border"
          :data="menuOptions"
          empty-text="加载中，请稍候"
          node-key="id"
          :props="{ label: 'label', children: 'children' }"
          show-checkbox
        />
      </el-form-item>
      <el-form-item label="备注">
        <el-input v-model="form.remark" placeholder="请输入内容" type="textarea" />
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button type="primary" @click="save">确 定</el-button>
      <el-button @click="cancel">取 消</el-button>
    </template>
  </vab-dialog>
</template>

<script lang="ts" setup>
import type { FormInstance } from 'element-plus'
import { treeselect as menuTreeselect, roleMenuTreeselect } from '/@/api/menuManagement'
import { doAdd, doEdit, getRole } from '/@/api/roleManagement'

defineOptions({
  name: 'RoleManagementEdit',
})

const { proxy } = getCurrentInstance() as any
const { sys_normal_disable } = proxy.useDict('sys_normal_disable')

const emit = defineEmits(['fetch-data'])

const menuRef = ref<any>(null)
const menuExpand = ref(false)
const menuNodeAll = ref(false)
const deptExpand = ref(true)
const deptNodeAll = ref(false)

const formRef = ref<FormInstance>()
const form = ref<any>({
  roleId: undefined,
  roleName: undefined,
  roleKey: undefined,
  roleSort: 0,
  status: '0',
  menuIds: [],
  deptIds: [],
  menuCheckStrictly: true,
  deptCheckStrictly: true,
  remark: undefined,
})
const rules = reactive<any>({
  roleName: [{ required: true, message: '角色名称不能为空', trigger: 'blur' }],
  roleKey: [{ required: true, message: '权限字符不能为空', trigger: 'blur' }],
  roleSort: [{ required: true, message: '角色顺序不能为空', trigger: 'blur' }],
})
const title = ref<string>('')
const dialogFormVisible = ref<boolean>(false)
const menuOptions = ref<any>([])

const showEdit = (row?: any) => {
  reset()
  if (row && row.roleId) {
    title.value = '编辑'
    const roleMenu = getRoleMenuTreeselect(row.roleId)
    getRole(row.roleId).then((response) => {
      form.value = response.data
      form.value.roleSort = Number(form.value.roleSort)
      dialogFormVisible.value = true
      nextTick(() => {
        roleMenu.then((res: any) => {
          let checkedKeys = res.checkedKeys
          checkedKeys.forEach((v: any) => {
            nextTick(() => {
              menuRef.value.setChecked(v, true, false)
            })
          })
        })
      })
    })
  } else {
    getMenuTreeselect()
    title.value = '添加'
    dialogFormVisible.value = true
  }
}

/** 根据角色ID查询菜单树结构 */
function getRoleMenuTreeselect(roleId: any) {
  return roleMenuTreeselect(roleId).then((response: any) => {
    menuOptions.value = response.menus
    return response
  })
}

/** 查询菜单树结构 */
function getMenuTreeselect() {
  menuTreeselect().then((response) => {
    menuOptions.value = response.data
  })
}

/** 树权限（展开/折叠）*/
function handleCheckedTreeExpand(value: any) {
  let treeList = menuOptions.value
  for (const treeItem of treeList) {
    menuRef.value.store.nodesMap[treeItem.id].expanded = value
  }
}

/** 树权限（全选/全不选） */
function handleCheckedTreeNodeAll(value: any) {
  menuRef.value.setCheckedNodes(value ? menuOptions.value : [])
}

/** 树权限（父子联动） */
function handleCheckedTreeConnect(value: any) {
  form.value.menuCheckStrictly = value ? true : false
}

/** 所有菜单节点数据 */
function getMenuAllCheckedKeys() {
  // 目前被选中的菜单节点
  let checkedKeys = menuRef.value.getCheckedKeys()
  // 半选中的菜单节点
  let halfCheckedKeys = menuRef.value.getHalfCheckedKeys()
  checkedKeys.unshift(...halfCheckedKeys)
  return checkedKeys
}

/** 重置新增的表单以及其他数据  */
function reset() {
  if (menuRef.value != undefined) {
    menuRef.value.setCheckedKeys([])
  }
  menuExpand.value = false
  menuNodeAll.value = false
  deptExpand.value = true
  deptNodeAll.value = false
  form.value = {
    roleId: undefined,
    roleName: undefined,
    roleKey: undefined,
    roleSort: 0,
    status: '0',
    menuIds: [],
    deptIds: [],
    menuCheckStrictly: true,
    deptCheckStrictly: true,
    remark: undefined,
  }
  proxy.resetForm('formRef')
}

const close = () => {
  formRef.value?.clearValidate()
  formRef.value?.resetFields()
  emit('fetch-data')
}

const cancel = () => {
  close()
  dialogFormVisible.value = false
}

const save = () => {
  formRef.value?.validate(async (valid: any) => {
    if (valid) {
      if (form.value.roleId) {
        form.value.menuIds = getMenuAllCheckedKeys()
        await doEdit(form.value)
        await $baseMessage('修改成功', 'success', 'hey')
      } else {
        form.value.menuIds = getMenuAllCheckedKeys()
        await doAdd(form.value)
        await $baseMessage('添加成功', 'success', 'hey')
      }
      cancel()
    }
  })
}

onBeforeMount(() => {})

defineExpose({
  showEdit,
})
</script>

<style lang="scss" scoped>
.vab-tree-border {
  width: 100%;
  height: 250px;
  padding: var(--el-padding);
  overflow-y: auto;
  border: 1px solid var(--el-border-color);
  border-radius: var(--el-border-radius-base);
}
</style>
