import React from 'react';
import { Button, Card, Tree, message } from 'antd';
import useBool from '@/utils/hooks/useBool';
import { arr2Tree, uniq } from '@/utils/array';
import { getResourceList, authRoleResource } from '@/services/role';

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) => {
      getResourceList({ type: 'menu' }).then((res = []) => {
        setList(res);
        resolve(res)
      }).catch(reject);
    });
  }

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

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

  React.useEffect(() => {
    const p = !list.length ? getListData : () => Promise.resolve(list);
    if (!role || !role.id) {
      p();
    } else {
      startLoading();
      p().then((allData) => {
        getResourceList({ type: 'menu', roleId: role.id }).then((res = []) => {
          cancelLoading();
          
          // 数据分为2部分, 一部分叶子节点, 一部分非叶子节点
          const checked = [], halfChecked = [];
          for (let item of res) {
            // 获取子节点, 没有的话则为叶子节点, 否则为非叶子节点
            const children = allData.filter(x => x.parentId === item.id);
            if (!children.length) {
              // 没有子节点, 则为叶子节点, 算入选中节点
              checked.push(item.id);
            } else {
              // 获取选中子节点
              const checkedChildren = res.filter(x => x.parentId === item.id);
              if (checkedChildren.length === children.length) {
                // 非叶子节点如果 子节点全部包含, 那么算入选中节点
                checked.push(item.id);
              } else {
                halfChecked.push(item.id);
              }
            }
          }

          setCheckedKeys({ checked, halfChecked });
        }).catch(() => {
          cancelLoading();
        })
      }).catch(() => {
        cancelLoading();
      })
    }
  }, [role]);
  
  React.useEffect(() => {
    // 展开节点
    setExpandedKeys((list).filter(x => x.parentId === -1).map(x => x.id));
    // 先转为需要的格式
    const arr = list.map(x => ({ title: x.name, key: x.id, 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.id} ghost onClick={onSubmit}>保存</Button>}
    >
      <Tree
        checkable
        autoExpandParent
        expandedKeys={expandedKeys}
        checkStrictly={false}
        selectable={false}
        checkedKeys={checkedKeys}
        onCheck={onCheck}
        onExpand={setExpandedKeys}
        treeData={treeData}
      />
    </Card>
  )
}

function getKeysWithParent(node, dict) {
  if (node.parentId === -1) return [node.key];
  const parentKeys = getKeysWithParent(dict[node.parentId], dict);
  return parentKeys ? [node.key].concat(parentKeys) : [node.key];
}
