import React from "react";
import { Button, Card, Tree, message } from "antd";
import useBool from "@/utils/hooks/useBool";
import { arr2Tree } from "@/utils/array";
import { getSysMenu } from "@/service/sysmenu";
import {
  getSysRoleResource,
  postSysRoleResource,
} from "@/service/sysroleresource";

export default (props) => {
  const { role } = props;

  const [loading, startLoading, cancelLoading] = useBool();
  const [list, setList] = React.useState([]);
  const [expandedKeys, setExpandedKeys] = React.useState([]);
  const [treeData, setTreeData] = React.useState([]);
  const treeDictRef = React.useRef();
  const [checkedKeys, setCheckedKeys] = React.useState({
    checked: [],
    halfChecked: [],
  });
  const keys = checkedKeys.checked.concat(checkedKeys.halfChecked);

  const title = role ? `${role.name} - 授权菜单` : "未选角色 - 授权菜单";

  const getListData = () => {
    return new Promise((resolve, reject) => {
      getSysMenu({ pageSize: 999 })
        .then((res = []) => {
          setList(res?.records);
          resolve(res?.records);
        })
        .catch(reject);
    });
  };

  const onCheck = (keys, { halfCheckedKeys }) => {
    setCheckedKeys({ checked: keys, halfChecked: halfCheckedKeys });
  };

  const onSubmit = () => {
    // 如果一个都不选，代表清空授权
    const data = [];
    const roleId = role.roleId;
    for (let resourceId of keys) {
      data.push({ roleId, resourceId, resourceType: 'menu' });
    }
    startLoading();
    postSysRoleResource(roleId, data)
      .then((res) => {
        cancelLoading();
      })
      .catch(() => {
        cancelLoading();
      });
  };

  React.useEffect(() => {
    const p = !list.length ? getListData : () => Promise.resolve(list);
    if (!role || !role.roleId) {
      p();
    } else {
      startLoading();
      p()
        .then((allData) => {
          getSysRoleResource({ roleId: role.roleId, resourceType: 'menu', pageSize: 9999 })
            .then((res = []) => {
              cancelLoading();

              const { records = [] } = res;

              // 数据分为2部分, 一部分叶子节点, 一部分非叶子节点
              const checked = [],
                halfChecked = [];

                for (let item of records) {
                  // 获取子节点, 没有的话则为叶子节点, 否则为非叶子节点
                  const children = allData.filter(
                    (x) => x.parentId === item.resourceId
                  );
                  if (!children.length) {
                    // 没有子节点, 则为叶子节点, 算入选中节点
                    checked.push(item.resourceId);
                  } else {
                    // 获取选中子节点
                    const checkedChildren = records.filter(
                      (x) => x.parentId === item.resourceId
                    );
                    if (checkedChildren.length === children.length) {
                      // 非叶子节点如果 子节点全部包含, 那么算入选中节点
                      checked.push(item.resourceId);
                    } else {
                      halfChecked.push(item.resourceId);
                    }
                  }
                }

              setCheckedKeys({ checked, halfChecked });
            })
            .catch(() => {
              cancelLoading();
            });
        })
        .catch(() => {
          cancelLoading();
        });
    }
  }, [role]);

  React.useEffect(() => {
    // 展开节点
    setExpandedKeys(
      list.filter((x) => x.parentId === "-1").map((x) => x.resourceId)
    );
    // 先转为需要的格式
    const arr = list.map((x) => ({
      title: x.name,
      key: x.menuId,
      parentId: x.parentId,
    }));
    // 再转为 tree
    const [tree, dict] = arr2Tree(arr);
    setTreeData(tree);
    treeDictRef.current = dict;
  }, [list]);

  return (
    <Card
      loading={loading}
      title={title}
      extra={
        <Button
          type="primary"
          disabled={!role || !role.roleId}
          ghost
          onClick={onSubmit}
        >
          保存
        </Button>
      }
    >
      <Tree
        checkable
        autoExpandParent
        expandedKeys={expandedKeys}
        checkStrictly={false}
        selectable={false}
        checkedKeys={checkedKeys}
        onCheck={onCheck}
        onExpand={setExpandedKeys}
        treeData={treeData}
      />
    </Card>
  );
};
