import classNames from 'classnames';
import React, { Dispatch, SetStateAction, useContext, useRef, useMemo } from 'react';
import { CaretDownOutlined } from '@ant-design/icons';
import useMedia from 'react-use/lib/useMedia';
import { useRect } from '@reach/rect';
import { SizeType } from '../../../config-provider/SizeContext';

import ConfigProvider, { ConfigContext } from '../../../config-provider';
import Button from '../../../button';
import Dropdown from '../../../dropdown';
import Menu from '../../../menu';
import defaultLocale from '../../../locale/en_US';
import { ApolloTableRowSelection } from '../../interfaces';

export interface BatchActionsProps<T> {
  children: React.ReactNode;
  tableAlertRenderResult:
    | false
    | {
        promotedBulkActions?: {
          content: string;
          disabled?: boolean;
          hidden?: boolean;
          onClick: React.MouseEventHandler<HTMLElement>;
        }[];
        bulkActions?: {
          content: string;
          disabled?: boolean;
          hidden?: boolean;
          onClick: (e: React.MouseEvent<HTMLElement, MouseEvent>) => void;
        }[];
      };
  size: SizeType;
  rowSelection: ApolloTableRowSelection<T>;
  propsRowSelection: ApolloTableRowSelection<T> | undefined;
  // 是否有多页（不止一页）
  hasAnyPage: boolean;
  isSelectedAll: boolean;
  setIsSelectedAll: Dispatch<SetStateAction<boolean>>;
  dataSource: T[] | undefined;
  onCleanSelected: () => void;
  setSelectedRowsAndKey: (keys: React.ReactText[], rows: T[]) => void;
  getRowKey: any;
  cardLeft: number;
}

export const BatchActions = <T extends {}>({
  children,
  tableAlertRenderResult,
  size,
  rowSelection,
  propsRowSelection,
  hasAnyPage,
  isSelectedAll,
  setIsSelectedAll,
  dataSource,
  onCleanSelected,
  setSelectedRowsAndKey,
  getRowKey,
  cardLeft,
}: BatchActionsProps<T>) => {
  const { getPrefixCls } = useContext(ConfigProvider.ConfigContext);
  const isNavigationCollapsed = useMedia('(max-width: 768px)');

  const prefixCls = getPrefixCls('apollo-table-selection');

  const { locale: { ApolloTable: locale } = { ApolloTable: defaultLocale.ApolloTable } } =
    React.useContext(ConfigContext);

  const ref = useRef<HTMLTableRowElement>(null);
  const rect = useRect(ref);

  const promotedBulkActions = useMemo(() => {
    if (tableAlertRenderResult && tableAlertRenderResult.promotedBulkActions) {
      return (
        tableAlertRenderResult && tableAlertRenderResult.promotedBulkActions.filter(i => !i.hidden)
      );
    }
    return undefined;
  }, [tableAlertRenderResult]);

  const bulkActions = useMemo(() => {
    if (tableAlertRenderResult && tableAlertRenderResult.bulkActions) {
      return tableAlertRenderResult && tableAlertRenderResult.bulkActions.filter(i => !i.hidden);
    }
    return undefined;
  }, [tableAlertRenderResult]);

  return (
    <>
      <tr ref={ref} className={`${prefixCls}-hide-tr`}>
        {children}
      </tr>
      <tr className={`${prefixCls}-bar`} style={{ left: cardLeft - (rect?.left || 0) + 16 }}>
        <th>
          <div
            className={classNames(`${prefixCls}-bar-item-number`, {
              [`${prefixCls}-bar-item-number-small`]: size === 'small',
            })}
          >
            {(children as any)?.[0].props.children}
            <span style={{ padding: '0 10px' }}>
              {`${locale?.selected} ${
                isSelectedAll
                  ? `${(dataSource || []).length}+`
                  : (rowSelection as any).selectedRowKeys?.length
              } ${locale?.item}`}
            </span>
          </div>

          {(promotedBulkActions?.length || 0) + (bulkActions?.length || 0) > 0 && (
            <div className={`${prefixCls}-bar-item-wrapper`}>
              {promotedBulkActions &&
                (promotedBulkActions.length < 2 ? true : !isNavigationCollapsed) &&
                promotedBulkActions.map((item, index) => (
                  <div
                    // eslint-disable-next-line react/no-array-index-key
                    key={index}
                    className={`${prefixCls}-bar-item`}
                  >
                    <Button
                      className={`${prefixCls}-bar-item-btn`}
                      size={size === 'small' ? 'small' : 'middle'}
                      onClick={item.onClick}
                    >
                      {item.content}
                    </Button>
                  </div>
                ))}

              {(!!bulkActions?.length ||
                (isNavigationCollapsed &&
                  promotedBulkActions &&
                  promotedBulkActions.length > 1)) && (
                <div className={`${prefixCls}-bar-item`}>
                  <Dropdown
                    overlay={
                      <Menu style={{ maxHeight: 300, overflowY: 'auto' }}>
                        {(isNavigationCollapsed &&
                        promotedBulkActions &&
                        promotedBulkActions.length > 1
                          ? promotedBulkActions
                          : []
                        )
                          .concat(bulkActions || [])
                          .map((item, index) => (
                            <Menu.Item
                              // eslint-disable-next-line react/no-array-index-key
                              key={index}
                              onClick={({ domEvent }) => item.onClick(domEvent)}
                            >
                              {item.content}
                            </Menu.Item>
                          ))}
                      </Menu>
                    }
                    trigger={['click']}
                  >
                    <Button
                      className={`${prefixCls}-bar-item-btn`}
                      size={size === 'small' ? 'small' : 'middle'}
                    >
                      {locale?.moreActions}
                      <CaretDownOutlined />
                    </Button>
                  </Dropdown>
                </div>
              )}
            </div>
          )}
        </th>

        {rowSelection && rowSelection.allowSelectAll && hasAnyPage && (
          <th>
            {!isSelectedAll && (
              <Button
                type="link"
                onClick={() => {
                  setIsSelectedAll(true);
                  setSelectedRowsAndKey(
                    (dataSource || []).map(item => getRowKey(item)),
                    dataSource || [],
                  );
                  if (propsRowSelection && propsRowSelection.onChange) {
                    propsRowSelection.onChange(
                      (dataSource || []).map(item => getRowKey(item)),
                      dataSource || [],
                    );
                  }
                }}
              >
                {`${locale?.selectAll} ${(dataSource || []).length}+ ${locale?.item}`}
              </Button>
            )}
            {isSelectedAll && (
              <div className={`${prefixCls}-bar-select-all`}>
                {`${locale?.selectedAll} ${(dataSource || []).length}+ ${locale?.itemEnd}`}
              </div>
            )}
            {isSelectedAll && (
              <Button type="link" onClick={onCleanSelected}>
                {locale?.undo}
              </Button>
            )}
          </th>
        )}
      </tr>
    </>
  );
};
