<template>
  <el-dialog
    v-model="dialogVisible"
    :title="isAdd ? '添加' : '编辑'"
    :width="700"
    center
    align-center
    :close-on-click-modal="false"
    @closed="closed"
  >
    <el-form :model="formData" ref="formRef" label-width="100px" :rules="formRules">
      <el-form-item label="角色名称" prop="roleName">
        <el-input v-model="formData.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="formData.roleKey" placeholder="请输入权限字符" />
      </el-form-item>
      <el-form-item label="角色顺序" prop="roleSort">
        <el-input-number v-model="formData.roleSort" controls-position="right" :min="0" />
      </el-form-item>
      <el-form-item label="状态" prop="status">
        <el-radio-group v-model="formData.status">
          <el-radio label="0">正常</el-radio>
          <el-radio label="1">停用</el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item label="菜单权限">
        <el-checkbox v-if="false" @change="handleCheckedTreeNodeAll">全选</el-checkbox>
        <el-tree
          class="tree-border"
          :data="menuOptions"
          show-checkbox
          ref="menuRef"
          node-key="id"
          :check-strictly="false"
          default-expand-all
          empty-text="加载中，请稍候"
          :props="{ label: 'label', children: 'children' }"
          @check="treeCheck"
          @check-change="treeCheckChange"
        >
          <template #default="{ node, data }">
            <el-space v-if="Object.keys(dataPrimisMap).includes(node.label)" :size="70" spacer="|">
              <span>{{ node.label }}</span>
              <div class="h-flex" @click.stop>
                <span style="font-weight: bold"> 数据权限： </span>
                <el-radio-group v-model="formData[dataPrimisMap[node.label]]" :disabled="!allCheckedKeys.includes(data.id)">
                  <el-radio label="0" size="large">全部</el-radio>
                  <el-radio label="1" size="large">本人</el-radio>
                </el-radio-group>
              </div>
            </el-space>
            <span v-else>{{ node.label }}</span>
          </template>
        </el-tree>
      </el-form-item>
      <el-form-item label="备注" prop="remark">
        <el-input v-model="formData.remark" type="textarea" placeholder="请输入内容"></el-input>
      </el-form-item>
    </el-form>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="handleCancel">取消</el-button>
        <el-button type="primary" class="ml30" v-throttle="handleSubmit">确定</el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script lang="ts" setup name="editTeamMember">
import { ref, defineExpose, nextTick } from "vue";
import { FormInstance, FormRules, ElMessage, ElTreeSelect } from "element-plus";
import { editRole, addRole } from "@/api/modules/system/role";
import { getCheckedKeysByRoleId, getAllTreeMenu } from "@/api/modules/system/menu";
import { Role, Menu } from "@/api/interface";
import { QuestionFilled } from "@element-plus/icons-vue";

//* 接收注入
const dialogVisible = ref(false);
const allCheckedKeys = ref<number[]>([]);
//* data
//* ref
const formRef = ref<FormInstance>();
const openPromise = ref<any>({});
interface FormData extends Partial<Role.ResRoleList> {
  [key: string]: any;
}
const isAdd = ref(false);
const menuOptions = ref<Menu.ResTreeMenu[]>([]);
const menuRef = ref<typeof ElTreeSelect>();

const formData = ref<FormData>(getFormDefaultValue());

const dataPrimisMap: Record<string, string> = {
  标注首页: "annoIndexDataAuth",
  数据标注: "annoListDataAuth"
};

// 校验规则
const formRules: FormRules = {
  roleName: [{ required: true, message: "角色名称不能为空", trigger: "blur" }],
  roleKey: [{ required: true, message: "权限字符不能为空", trigger: "blur" }],
  roleSort: [{ required: true, message: "角色顺序不能为空", trigger: "blur" }]
};

//* 方法

// 菜单权限树选择事件
function treeCheck(_: any, { checkedKeys, halfCheckedKeys }: any) {
  allCheckedKeys.value = [...halfCheckedKeys, ...checkedKeys];
}

// 菜单权限树复选框选择事件
function treeCheckChange(data: any, checked: boolean) {
  if (formData.value.roleId || !Object.keys(dataPrimisMap).includes(data.label)) {
    return;
  }
  formData.value[dataPrimisMap[data.label]] = checked ? "0" : undefined;
}

//获取默认值
function getFormDefaultValue() {
  return {
    annoIndexDataAuth: undefined,
    annoListDataAuth: undefined,
    roleId: undefined,
    roleName: undefined,
    roleKey: undefined,
    roleSort: undefined,
    status: "0",
    remark: "",
    f1: undefined,
    f2: undefined
  };
}

/** 根据角色ID查询菜单树结构 */
function loadCheckedKeys(roleId: number) {
  return getCheckedKeysByRoleId(roleId).then(res => {
    allCheckedKeys.value = res.data.checkedKeys || [];
    res.data.checkedKeys.forEach(v => {
      menuRef.value?.setChecked(v, true, false);
    });
  });
}

/** 加载所有菜单 */
function loadAllTreeMenu() {
  return getAllTreeMenu().then(res => {
    menuOptions.value = res.data;
  });
}

loadAllTreeMenu();

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

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

function closed() {
  formData.value = getFormDefaultValue();
  dialogVisible.value = false;
  // formRef.value?.resetFields(); // 没生效
  nextTick(formRef.value?.clearValidate);
  menuRef.value?.setCheckedKeys([]);
  allCheckedKeys.value = [];
}
// 取消
function handleCancel() {
  dialogVisible.value = false;
}
//提交
function handleSubmit() {
  formRef.value?.validate(async valid => {
    if (!valid) return;
    const params = {
      ...formData.value,
      menuIds: allCheckedKeys.value
    };
    if (isAdd.value) {
      await addRole(params);
      ElMessage.success("新增成功");
    } else {
      await editRole(params);
      ElMessage.success("编辑成功");
    }
    openPromise.value.resolve();
    dialogVisible.value = false;
  });
}

function open(params?: FormData) {
  isAdd.value = !params;
  if (params?.roleId) {
    loadCheckedKeys(params.roleId);
    const defaultValue: FormData = {};
    for (const key of Object.keys(formData.value)) {
      defaultValue[key] = params[key];
    }
    formData.value = defaultValue;
  }
  dialogVisible.value = true;
  return new Promise(resolve => {
    openPromise.value.resolve = resolve;
  });
}
defineExpose({
  open
});
</script>

<style lang="scss" scoped>
.tree-border {
  width: 100%;
  min-height: 300px;
  max-height: calc(100vh - 900px);
  margin-top: 5px;
  overflow-y: auto;
  background: #ffffff none;
  border: 1px solid #e5e6e7;
  border-radius: 4px;
}
</style>
