<template>
  <BasicModal
    wrapClassName="autherizeDialog"
    v-bind="$attrs"
    @register="registerRoleAuthModal"
    :title="t('功能授权')"
    destroy-on-close
    @ok="handleSubmit"
    width="90%"
  >
    <a-row class="h-full">
      <a-col :span="6">
        <NodeHead nodeName="系统功能" class="title" />
        <div class="treebox">
          <BasicTree
            :treeData="treeData"
            checkable
            ref="treeRef"
            @check="handleTreeSelect"
            :fieldNames="{ title: 'title', key: 'id' }"
          >
            <template #title="{ title, systemName, parentId }">
              <div v-if="parentId == 0">{{ title }} 【{{ systemName }}】</div>
              <div v-else>{{ title }}</div>
            </template>
          </BasicTree>
        </div>
      </a-col>
      <a-col :span="6">
        <NodeHead nodeName="按钮权限" class="title" />
        <div class="treebox">
          <BasicTree
            :treeData="buttonSelectData"
            checkable
            ref="ButtonRef"
            @check="handleButtonSelect"
            :fieldNames="{ title: 'title', key: 'id' }"
          />
        </div>
      </a-col>
      <a-col :span="6">
        <NodeHead nodeName="字段权限" class="title" />
        <div class="treebox">
          <BasicTree
            :treeData="columnSelectData"
            checkable
            ref="ColumnRef"
            @check="handleColumnSelect"
            :fieldNames="{ title: 'title', key: 'id' }"
          />
        </div>
      </a-col>
      <a-col :span="6">
        <NodeHead nodeName="表单权限" class="title" />
        <div class="treebox">
          <BasicTree
            :treeData="fieldSelectData"
            checkable
            ref="FieldRef"
            @check="handleFieldSelect"
            :fieldNames="{ title: 'title', key: 'id' }"
          />
        </div>
      </a-col>
    </a-row>
    <template #insertFooter>
      <SelectRole @change="handleOtherAuth" :isInline="true">
        <a-button type="primary" class="mr-2">复制其他角色功能权限</a-button>
      </SelectRole>
    </template>
  </BasicModal>
</template>
<script lang="ts">
  import { defineComponent, ref, unref, nextTick } from 'vue';
  import { getMenuSimpleTree } from '/@/api/system/menu';
  import { BasicModal, useModalInner } from '/@/components/Modal';
  import { TreeItem, BasicTree, TreeActionType } from '/@/components/Tree';
  import { getRoleAuth, RoleSetAuth } from '/@/api/system/role';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { SelectRole } from '/@/components/SelectOrganizational/index';
  import { getMenuButtonList, getMenuColumnList, getMenuFieldList } from '/@/api/system/menuButton';
  import { cloneDeep } from 'lodash-es';
  import { useI18n } from '/@/hooks/web/useI18n';
  import { NodeHead } from '/@/components/ModalPanel/index';

  export default defineComponent({
    name: 'SelectUserModal',
    components: { BasicModal, BasicTree, SelectRole, NodeHead },
    emits: ['success', 'register'],
    setup(_, { emit }) {
      const { notification } = useMessage();
      const { t } = useI18n();
      const treeRef = ref<Nullable<TreeActionType>>(null);
      const ButtonRef = ref<Nullable<TreeActionType>>(null);
      const ColumnRef = ref<Nullable<TreeActionType>>(null);
      const FieldRef = ref<Nullable<TreeActionType>>(null);
      const treeData = ref<TreeItem[]>([]);
      const buttonData = ref<TreeItem[]>([]);
      const columnData = ref<TreeItem[]>([]);
      const fieldData = ref<TreeItem[]>([]);

      const buttonSelectData = ref<TreeItem[]>([]);
      const columnSelectData = ref<TreeItem[]>([]);
      const fieldSelectData = ref<TreeItem[]>([]);
      const btnKeys = ref<string[]>([]);
      const colKeys = ref<string[]>([]);
      const menuKeys = ref<string[]>([]);
      const fieldKeys = ref<string[]>([]);

      const btnFilterKeys = ref<string[]>([]);
      const colFilterKeys = ref<string[]>([]);
      const fieldFilterKeys = ref<string[]>([]);

      const rowId = ref('');

      function getTree(tree) {
        if (!tree) {
          return null;
        }
        return tree;
      }

      const [registerRoleAuthModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
        setModalProps({ confirmLoading: false });
        rowId.value = data.id;
        treeData.value = await getMenuSimpleTree();

        buttonData.value = await getMenuButtonList();
        columnData.value = await getMenuColumnList();
        fieldData.value = await getMenuFieldList();
        getAuthInfo(rowId.value);
      });

      async function getAuthInfo(id) {
        const authList = await getRoleAuth(id);
        menuKeys.value = authList.menuIds || [];
        btnKeys.value = authList.buttonIds || [];
        colKeys.value = authList.columnIds || [];
        fieldKeys.value = authList.formIds || [];
        let menuCheckedKey = [];
        let btnCheckedKey = [];
        let colCheckedKey = [];
        let fieldCheckedKey = [];
        menuKeys.value.forEach((o) => {
          getParentKeys(menuCheckedKey, treeData.value, o);
        });
        menuKeys.value = menuCheckedKey;
        getTree(unref(treeRef)).setCheckedKeys(authList.menuIds);
        initTree(menuCheckedKey);

        btnKeys.value.forEach((o) => {
          getParentKeys(btnCheckedKey, buttonSelectData.value, o);
        });
        btnKeys.value = btnCheckedKey;
        colKeys.value.forEach((o) => {
          getParentKeys(colCheckedKey, columnSelectData.value, o);
        });
        colKeys.value = colCheckedKey;

        fieldKeys.value.forEach((o) => {
          getParentKeys(fieldCheckedKey, fieldSelectData.value, o);
        });
        fieldKeys.value = fieldCheckedKey;

        nextTick(() => {
          getTree(unref(ButtonRef))?.setCheckedKeys(authList.buttonIds);
          getTree(unref(ColumnRef))?.setCheckedKeys(authList.columnIds);
          getTree(unref(FieldRef))?.setCheckedKeys(authList.formIds);
          getTree(unref(ButtonRef)).expandAll(true);
          getTree(unref(ColumnRef)).expandAll(true);
          getTree(unref(FieldRef)).expandAll(true);
        });

        getTree(unref(treeRef)).expandAll(true);
      }

      function handleOtherAuth(list) {
        if (list.length) {
          getAuthInfo(list[0]);
        }
      }

      async function handleSubmit() {
        try {
          setModalProps({ confirmLoading: true });

          //由于树组件的原因，提交之前先过滤一遍，没有选中的不提交
          // btnKeys.value = getTree(unref(ButtonRef)).getCheckedKeys();
          // colKeys.value = getTree(unref(ColumnRef)).getCheckedKeys();
          // fieldKeys.value = getTree(unref(FieldRef)).getCheckedKeys();

          // btnKeys.value = btnKeys.value.filter((o) => {
          //   return btnFilterKeys.value.includes(o);
          // });
          // colKeys.value = colKeys.value.filter((o) => {
          //   return colFilterKeys.value.includes(o);
          // });
          // fieldKeys.value = fieldKeys.value.filter((o) => {
          //   return fieldFilterKeys.value.includes(o);
          // });

          await RoleSetAuth({
            id: rowId.value,
            menuIds: menuKeys.value,
            buttonIds: btnKeys.value,
            columnIds: colKeys.value,
            formIds: fieldKeys.value,
          });
          notification.success({
            message: t('提示'),
            description: t('功能授权更新成功'),
          }); //提示消息
          closeModal();
          emit('success');
        } catch (error) {
          setModalProps({ confirmLoading: false });
        }
      }
      function handleButtonSelect(keys, e) {
        btnKeys.value = [...e.halfCheckedKeys, ...keys];
      }
      function handleColumnSelect(keys, e) {
        colKeys.value = [...e.halfCheckedKeys, ...keys];
      }
      function handleFieldSelect(keys, e) {
        fieldKeys.value = [...e.halfCheckedKeys, ...keys];
      }
      function handleTreeSelect(keys, e) {
        //keys  所有全选中的key
        //e.halfCheckedKeys  所有半选中的

        //如果没有半选  就证明全部全选  直接使用keys
        //如果有半选需要  使用keys + e.halfCheckedKeys

        const menuSelect: string[] = [...e.halfCheckedKeys, ...keys];

        initTree(menuSelect);

        menuKeys.value = menuSelect;
      }
      function initTree(menuSelect) {
        buttonSelectData.value = [];
        columnSelectData.value = [];
        fieldSelectData.value = [];

        btnFilterKeys.value = [];
        colFilterKeys.value = [];
        fieldFilterKeys.value = [];

        findMenuTree(buttonSelectData.value, treeData.value, menuSelect, 'button');
        findMenuTree(columnSelectData.value, treeData.value, menuSelect, 'column');
        findMenuTree(fieldSelectData.value, treeData.value, menuSelect, 'field');

        getTree(unref(ButtonRef))?.setExpandedKeys(menuSelect);
        getTree(unref(ColumnRef))?.setExpandedKeys(menuSelect);
        getTree(unref(FieldRef))?.setExpandedKeys(menuSelect);
      }
      function getParentKeys(checkedKey, arr, keys) {
        for (let i = 0; i < arr.length; i++) {
          let o = arr[i];
          if (o.id == keys) {
            if (!checkedKey.includes(o.id)) checkedKey.push(o.id);
            if (o.parentId > 0) {
              if (!checkedKey.includes(o.parentId)) checkedKey.push(o.parentId);
              getParentKeys(checkedKey, treeData.value, o.parentId);
            }
          }
          if (o.children?.length > 0) {
            getParentKeys(checkedKey, o.children, keys);
          }
        }
      }
      function findMenuTree(menuSelectTree, treeData, keys, type) {
        for (let i = 0; i < treeData.length; i++) {
          let o = cloneDeep(treeData[i]);
          if (keys.includes(o.id)) {
            o.children = [];
            menuSelectTree.push(o);
            if (treeData[i].children?.length > 0) {
              findMenuTree(o.children, treeData[i].children, keys, type);
            } else {
              let list =
                type == 'button'
                  ? buttonData.value
                  : type == 'column'
                  ? columnData.value
                  : fieldData.value;
              o.children = getAuthData(list, o.id, type);
            }
          }
        }
      }
      function getAuthData(list, id, type) {
        let arr: TreeItem[] = [];

        arr = list.filter((o) => {
          return o.menuId == id;
        });

        arr.forEach((o) => {
          o.parentId = o.menuId;
          if (type == 'button') {
            btnFilterKeys.value.push(o.id);
          } else if (type == 'column') {
            colFilterKeys.value.push(o.id);
          } else {
            if (o.children && o.children.length > 0) {
              o.children?.forEach((k) => {
                fieldFilterKeys.value.push(k.id);
              });
            }
            fieldFilterKeys.value.push(o.id);
          }
        });
        return arr;
      }
      // function findMenuTree(menuTree, menuSelectTree, keys) {
      //   let selected: any = {};
      //   menuTree.forEach((key) => {
      //     //找到node对象

      //     if (keys.includes(key.id)) {
      //       console.log(key, 'kkkkkkkkkk');

      //       selected = cloneDeep(key);
      //       if (key.children?.length > 0) {
      //         selected.children = [];
      //         findMenuTree(key.children, selected.children, keys);
      //       }
      //     }
      //   });
      //   // let obj = menuSelectTree.find((o) => {
      //   //   return o.id == selected.id;
      //   // });
      //   // if (!obj) {
      //   //   menuSelectTree.push(selected);
      //   // } else {
      //   //   obj.children = obj.children.concat(selected.children);
      //   // }
      //   checkChild(menuSelectTree, selected);
      // }
      // function checkChild(menuTree, selected) {
      //   menuTree.forEach((o) => {
      //     if (o.id == selected.parentId) {
      //       o.children = o.children.concat(selected.children);
      //       checkChild(o.children, selected);
      //     } else {
      //       menuTree.push(selected);
      //     }
      //   });
      // }
      //将按钮塞入到菜单树
      // function menuInsertButton(menuTree, buttonList) {
      //   menuTree.forEach((menu) => {
      //     const thisMenuButton = buttonList.filter((btn) => btn.menuId === menu.id);
      //     if (menu.children && menu.children.length > 0) {
      //       menuInsertButton(menu.children, buttonList);
      //     }

      //     // console.log('thisMenuButton', thisMenuButton);

      //     menu.children = menu.children?.concat(thisMenuButton);
      //   });
      // }

      return {
        registerRoleAuthModal,
        handleSubmit,
        handleTreeSelect,
        handleButtonSelect,
        handleColumnSelect,
        handleFieldSelect,
        menuKeys,
        treeData,
        treeRef,
        ButtonRef,
        FieldRef,
        ColumnRef,
        buttonSelectData,
        columnSelectData,
        fieldSelectData,
        handleOtherAuth,
        t,
      };
    },
  });
</script>
<style lang="less">
  .autherizeDialog {
    .ant-modal {
      top: 20px;
      height: calc(100% - 40px) !important;

      .ant-modal-content {
        height: 100%;

        .ant-modal-body {
          height: calc(100% - 102px) !important;

          .scrollbar__view {
            height: 100%;

            & > div {
              height: 100%;
              max-height: none !important;

              .ant-col {
                height: 100%;

                .treebox {
                  height: calc(100% - 50px);
                  overflow: auto;
                  padding-right: 15px;
                  margin-bottom: 10px;
                  border-right: solid 1px #ddd;

                  .vben-tree {
                    height: auto;
                  }
                }
              }
            }
          }
        }
      }
    }
  }
</style>
<style lang="less" scoped>
  :deep(.ant-tree .ant-tree-switcher) {
    display: inline !important ;
  }

  :deep(.vben-tree__title) {
    padding-left: 0;
  }

  .title {
    height: 50px;
    padding-left: 20px;
    border-bottom: 1px solid #eee;
    border-right: 1px solid #ddd;
  }
</style>
