import React, { useMemo } from 'react';
import classNames from 'classnames';
import Dropdown from 'antd/es/dropdown';
import 'antd/es/dropdown/style/index';
import Menu from 'antd/es/menu';
import 'antd/es/menu/style/index';
import { checkType } from '@jy-fe/utils';
import { XuiOperationNodeType, XuiOperationListType } from './xui-operation-list.d';

interface DiscoprNodeFunction {
  (nodes: XuiOperationNodeType[], data?: { [key: string]: any }): {
    front: XuiOperationNodeType[];
    later: XuiOperationNodeType[];
  };
}

const discoprNode: DiscoprNodeFunction = (nodes, data = {}) => {
  const currentNodes = nodes.filter(({ access, show }) => {
    if (checkType(show) === 'Object') {
      const result: boolean[] = [];
      const showObj = show as { [key: string]: any };
      Object.keys(showObj).forEach(key => {
        const value = showObj[key];
        if (data[key] !== undefined && data[key] !== null) {
          if (checkType(value) === 'Array') {
            if (checkType(data[key]) === 'Array') {
              let isIncludes = false;
              data[key].forEach(d => {
                if ((value as React.ReactText[]).includes(d)) {
                  isIncludes = true;
                }
              });
              if (isIncludes) {
                result.push(true);
              } else {
                result.push(false);
              }
            } else if ((value as React.ReactText[]).includes(data[key])) {
              result.push(true);
            } else {
              result.push(false);
            }
          } else if (data[key] !== value) {
            result.push(false);
          } else {
            result.push(true);
          }
        } else {
          result.push(true);
        }
      });
      return access !== false && result.filter(res => !res).length === 0;
    }
    if (checkType(show) === 'Function') {
      return access !== false && (show as () => boolean)?.();
    }
    return access !== false;
  });
  let front: XuiOperationNodeType[] = [];
  let later: XuiOperationNodeType[] = [];
  if (currentNodes.length > 3) {
    front = currentNodes.slice(0, 2);
    later = currentNodes.slice(2);
  } else {
    front = currentNodes;
  }
  return {
    front,
    later,
  };
};

const OperationList: XuiOperationListType = ({ getNodes, data }) => {
  const className = 'xui-ant__operation-list';

  const renderOperation = useMemo(() => {
    const renderNodes: JSX.Element[] = [];
    const { front, later } = discoprNode(getNodes(data), data);
    front.forEach(({ key, content, clickEvent }, index) => {
      renderNodes.push(
        <a
          key={key}
          className={classNames({
            [`${className}--a`]: index !== front.length - 1,
          })}
          onClick={clickEvent}
        >
          {content}
        </a>,
      );
    });
    if (later.length > 0) {
      const renderLaterContent: JSX.Element[] = [];
      later.forEach(({ key, content, clickEvent }) => {
        renderLaterContent.push(
          <Menu.Item key={key} onClick={clickEvent}>
            {content}
          </Menu.Item>,
        );
      });
      renderNodes.push(
        <Dropdown
          key='more'
          overlay={<Menu className={`${className}--dropMenu`}>{renderLaterContent}</Menu>}
        >
          <a className={`${className}--dropdown`}>
            更多<span className='iconfont'>&#xe6a5;</span>
          </a>
        </Dropdown>,
      );
    }
    return renderNodes;
  }, [getNodes, data]);

  return <div className={className}>{renderOperation}</div>;
};

OperationList.getWidth = (getNodes, data, config) => {
  const defaultConfig = {
    fontSize: 14,
    padding: 12,
  };
  const curConfig = { ...defaultConfig, ...config };

  let width = curConfig.padding * 2 + 1; // 左右边距 + 右边框
  const { front, later } = discoprNode(getNodes(data), data);
  if (front.length > 0) {
    front.forEach(({ minWidth = 0, content }, index) => {
      const curWidth = content.length * curConfig.fontSize + 1; // 1个字为14px，safari下整体多1px
      width += curWidth > minWidth ? curWidth : minWidth;
      if (index < front.length - 1) {
        width += 12; // 两个操作按钮间距为12px
      }
    });
  } else {
    width = 0;
  }
  if (later.length > 0) {
    width += curConfig.padding + curConfig.fontSize * 3 + 1; // 间隔+3个字+边框
  }
  return width;
};

export default OperationList;
