/*
 * @Author: your name
 * @Date: 2022-01-14 14:03:42
 * @LastEditTime: 2022-11-30 15:48:33
 * @LastEditors: code4eat awesomedema@gmail.com
 * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 * @FilePath: /KC-MiddlePlatform/src/pages/platform/setting/hospManage/modals/menu.tsx
 */

import React, { Key, useEffect, useState } from 'react';
import KCTable from '@/components/kcTable';
import { Popconfirm } from 'antd';
import { Input, Transfer, Tree } from 'antd';
import { getAllMenus, getAllMenusDataType, getHospAllMenus } from '@/service/menu';
import { ProColumns } from '@ant-design/pro-table';
import type { MenuItemDataType } from '@/service/menu';

import { DownOutlined, FileOutlined, RightOutlined } from '@ant-design/icons';
import './style.less';
import { MenuTypes } from '@/constant';
import { getValsFromTree } from '@/utils';

import type { TransferDirection, TransferItem } from 'antd/es/transfer';
import type { DataNode } from 'antd/es/tree';

const { Search } = Input;

export interface MenuEditerType {
  value?: React.Key[] | React.Key[];
  onChange?: (selectedRowKeys: React.Key[], selectedRows?: any[]) => {};
  noAction?: boolean;
  hospId?: number | string;
}

const MenuEditer: React.FC<MenuEditerType> = ({ value = [], onChange, noAction = false, hospId }) => {
  const getData = async () => {
    if (hospId) {
      const resp = await getHospAllMenus(hospId);
      if (resp) {
        const data = resp.allMenuVO;

        const convertData = (data: Array<any>) => {
          data.forEach((item) => {
            item.children = item.child;
            if (item.child) {
              convertData(item.child);
            }
          });
        };
        convertData(data);
        setDataSource(data);
      }
    } else {
      const resp = await getAllMenus();
      const data = resp.list ? resp.list : [];
      setDataSource(data);
    }
  };

  const [dataSource, setDataSource] = useState<any[]>([]);

  const [targetKeys, setTargetKeys] = useState<string[]>([]);

  const [_selectedKeys, set__selectedKeys] = useState<string[]>([]);

  const [sourceSelectedKeys, set_sourceSelectedKeys] = useState<string[]>([]);

  const onTransFerChange = (keys: string[]) => {
    let _keys = Array.from(new Set(keys));
    setTargetKeys(_keys);
    onChange && onChange(_keys);
  };

  interface TreeTransferProps {
    dataSource: MenuItemDataType[];
    targetKeys: string[];
    onChange: (targetKeys: string[], direction: TransferDirection, moveKeys: string[]) => void;
  }

  const isChecked = (selectedKeys: (string | number)[], eventKeys: (string | number)[]) => {
    // console.log({selectedKeys,eventKeys});

    const isIncludesFunc = (arr1: (string | number)[], arr2: (string | number)[]) => {
      if (arr2.length == 0) {
        return true;
      }
      return arr2.every((item) => arr1.includes(item));
    };

    return isIncludesFunc(selectedKeys, eventKeys);
  };

  const generateTree = (treeNodes: MenuItemDataType[] = [], checkedKeys: string[] = []): any[] => {
    return treeNodes.map(({ children, menuId, name, ...props }) => ({
      key: menuId,
      title: name,
      disabled: checkedKeys.includes(menuId as string),
      children: generateTree(children, checkedKeys),
      ...props,
    }));
  };

  const onSelectChangeHandle = (_sourceSelectedKeys: Key[], targetSelectedKeys: Key[]) => {
    set_sourceSelectedKeys(_sourceSelectedKeys as string[]);
    // set_selectedKeysVal(sourceSelectedKeys as string[]);
    // setTargetKeys(targetSelectedKeys as string[]);
  };

  const TreeTransfer = ({ dataSource, targetKeys, ...restProps }: TreeTransferProps) => {
    const transferDataSource: MenuItemDataType[] = [];

    function flatten(list: MenuItemDataType[] = []) {
      list.forEach((item) => {
        transferDataSource.push(item as MenuItemDataType);
        flatten(item.children);
      });
    }

    flatten(dataSource);

    return (
      <Transfer
        {...restProps}
        listStyle={{ width: 100, height: 500 }}
        targetKeys={targetKeys}
        rowKey={(record) => record.menuId}
        dataSource={transferDataSource}
        className="tree-transfer"
        // onSelectChange={onSelectChangeHandle}
        // selectedKeys={_selectedKeys}
        render={(item) => item.name!}
        showSelectAll={true}
      >
        {({ direction, onItemSelect, selectedKeys, onItemSelectAll }) => {
          if (direction === 'left') {
            const checkedKeys = [...selectedKeys, ...targetKeys];
            return (
              <Tree
                blockNode
                checkable
                checkStrictly={false}
                defaultExpandAll
                height={460}
                checkedKeys={checkedKeys}
                treeData={generateTree(dataSource, targetKeys)}
                onCheck={(keys, { node, halfCheckedKeys, ...rest }) => {
                  // console.log({keys,node,rest});
                  // 差集
                  let difference = (keys as Key[]).filter((v) => !targetKeys.includes(v as string));
                  const map = (list: any, cb: any) => {
                    return list.reduce((res: any, v: any) => {
                      res.push(cb(v));
                      if (Array.isArray(v.child)) res = res.concat(map(v.child, cb));
                      return res;
                    }, []);
                  };

                  if (!node.checked) {
                    //选中
                    onItemSelectAll(difference as string[], true);
                  } else {
                    //取消勾选
                    const cancelKeys = map(node.children, (v: any) => v.key);
                    onItemSelectAll([node.key, ...cancelKeys, ...(halfCheckedKeys as Key[])] as string[], false);
                  }
                }}
                onSelect={(keys, { node: { key } }) => {}}
              />
            );
          }
        }}
      </Transfer>
    );
  };

  useEffect(() => {
    setTargetKeys(value as string[]);
  }, [value]);

  useEffect(() => {
    getData();
  }, []);

  return (
    <div className="MenuEditer">
      <TreeTransfer dataSource={dataSource} targetKeys={targetKeys} onChange={onTransFerChange} />
    </div>
  );
};

export default MenuEditer;
