<template>
  <com-dialog
    :title="`${operateType}角色`"
    @quit="onQuit"
    :show="true"
    :showClose="edit"
    :enterText="!edit ? '确定' : undefined"
    :cornerClose="!edit"
    @submit="edit ? submit() : onQuit()"
    :width="600"
  >
    <el-form ref="form" label-width="90px" class="user-from">
      <el-form-item label="角色名称：" class="mandatory">
        <el-input
          maxlength="15"
          v-model="bindRole.roleName"
          :disabled="operateType == '查看'"
          placeholder="请输入"
        ></el-input>
      </el-form-item>
      <el-form-item label="所属架构：" v-if="roleLevel !== RoleLevel.admin">
        <el-input
          maxlength="15"
          :disabled="true"
          v-model="user.info.deptName"
          placeholder="请输入"
        ></el-input>
      </el-form-item>
      <el-row :gutter="20">
        <el-col :span="12">
          <div class="grid-content bg-purple">
            <div class="title">功能权限</div>
            <el-tree
              ref="tree"
              :data="menuTree"
              highlight-current
              show-checkbox
              node-key="id"
              :default-checked-keys="checkedMenuIds"
              @check="switchMenuCheck"
              @node-click="menuClick"
              :props="{ children: 'children', label: 'name', disabled: 'disabled' }"
            />
          </div>
        </el-col>
        <el-col :span="12">
          <div class="grid-content bg-purple">
            <div class="title">数据权限</div>
            <el-radio-group
              v-if="currentMenu"
              v-model="currentMenu.dataScope"
              :disabled="!edit"
            >
              <el-radio
                style="line-height: 28px"
                v-for="item in scopeOptions"
                :key="item.id"
                :label="item.id"
                size="large"
                >{{ item.value }}</el-radio
              >
            </el-radio-group>
          </div>
        </el-col>
      </el-row>
    </el-form>
  </com-dialog>
</template>

<script setup lang="ts">
import comDialog from "@/components/dialog/index.vue";
import { DetailProps } from ".";
import {
  Role,
  getRole,
  roleMenuTree,
  RoleMenuTreeItem,
  refreshRoleMenuTree,
  RoleMenuTree,
  DataScope,
} from "@/store/role";
import { user } from "@/store/user";
import { dataScopeOptions, roleMenuDataScope } from "@/constant/role";
import { RoleLevel, roleLevel } from "@/store/role";

import { computed, onMounted, ref } from "vue";
import { ElMessage } from "element-plus";
import { axios, updateRole } from "@/request";

const props = defineProps<
  DetailProps & { onQuit: () => void; onSuccess: (data: Role) => void }
>();

const operateType = computed(() =>
  props.edit ? (props.roleId ? "修改" : "新增") : "查看"
);
const bindRole = ref<Role>(({ perm: [] } as unknown) as Role);

const getDefMenuDataScope = (menuId: string): DataScope => {
  const dataScopeMap = roleMenuDataScope[roleLevel.value] as any;
  return menuId in dataScopeMap ? dataScopeMap[menuId] : dataScopeMap["other"];
};
const menuTree = computed(() => {
  const disabled = !props.edit;
  const getMenuTree = (
    menuTree: RoleMenuTree
  ): (RoleMenuTreeItem & { disabled?: boolean })[] => {
    return menuTree
      .filter((menu) => getDefMenuDataScope(menu.id) != DataScope.none)
      .map((item) => ({
        ...item,
        disabled,
        children: item.children ? getMenuTree(item.children) : [],
      }));
  };
  return getMenuTree(roleMenuTree.value);
});
const findMenuTreeItem = (
  id: string,
  items = menuTree.value
): RoleMenuTreeItem | null => {
  for (const item of items) {
    if (item.id === id) {
      return item.type === "button" ? item : null;
    } else if (item.children) {
      const cItem = findMenuTreeItem(id, item.children);
      if (cItem) {
        return cItem;
      }
    }
  }
  return null;
};

const checkedMenuIds = computed(() =>
  bindRole.value.perm
    .filter((item) => item.type === "button")
    .map((item) => item.permissionId)
);

const currentMenu = ref<RoleMenuTreeItem | null>(null);
const switchMenuCheck = (
  data: RoleMenuTreeItem,
  checkProps: { checkedKeys: string[] }
) => {
  bindRole.value.perm = checkProps.checkedKeys
    .map((id) => findMenuTreeItem(id))
    .filter((item) => !!item)
    .map((item) => ({
      ...item!,
      permissionId: item!.id,
      dataScope: getDefMenuDataScope(item!.id),
    }));
  currentMenu.value = bindRole.value.perm.find((item) => item.id === data.id)!;
};
const menuClick = (data: RoleMenuTreeItem) => {
  currentMenu.value = bindRole.value.perm.find((item) => item.permissionId === data.id)!;
};

const scopeOptions = computed(() => {
  if (currentMenu.value) {
    console.log(getDefMenuDataScope(currentMenu.value!.id));
    return dataScopeOptions.filter(
      (option) => option.id >= getDefMenuDataScope(currentMenu.value!.id)
    );
  }
});

const submit = async () => {
  if (!bindRole.value.roleName) {
    return ElMessage.error("请输入用户姓名");
  }
  const perm: { [key in string]: DataScope } = {};
  bindRole.value.perm.forEach((per) => {
    perm[per.id] = per.dataScope;
    perm[per.parentId] = DataScope.all;
  });

  await axios.post(updateRole, {
    id: bindRole.value.id || "",
    perm: perm,
    roleName: bindRole.value.roleName,
  });
  props.onSuccess(bindRole.value);
};

onMounted(async () => {
  await refreshRoleMenuTree();
  if (props.roleId) {
    bindRole.value = await getRole(props.roleId);
  } else {
  }
});
</script>

<style lang="scss" scoped>
.grid-content {
  border: 1px solid #e8e8e8;
  border-bottom: none;
  .title {
    background: #fafafa;
    padding: 12px 10px;
    border-bottom: 1px solid #ebeef5;
    line-height: 20px;
  }
  .el-radio-group {
    width: 100%;
    .el-radio {
      padding: 12px 10px;
      border-bottom: 1px solid #ebeef5;
      display: block;
      margin-right: 0;
      &:last-child {
        // border-bottom: none;
      }
    }
  }
}
</style>

<style lang="scss">
.user-table.el-table .cell {
  overflow: inherit;
}
.el-tree {
  max-height: 400px;
  overflow-y: auto;
  border-bottom: 1px solid #ebeef5;
  .el-tree-node__content {
    border-bottom: 1px solid #ebeef5;
    padding: 12px 10px;
  }
}
</style>
