import React from 'react';
import AntdTable from 'antd/es/table';
import Icons from '../icons';

import { ConfigConsumer } from '../config-provider';
// import MiniSelect from './MiniSelect';
import Select from '../select';
import 'antd/es/checkbox/style/index.less';
import './index.less';
import { customFilters } from './customFilters';
import { defaultEmptyTable } from './defaultEmptyTable';
import { getOperation } from './operations';
import { customFiltersLabel } from './customFiltersLabel';
import _ from 'lodash';

const {
  MinusSquareIcon,
  PlusSquareIcon,
  CaretLeftIcon,
  CaretRightIcon,
  DoubleLeftIcon,
  DoubleRightIcon,
} = Icons;

const defaultPaginationConfig = {
  defaultCurrent: 1,
  defaultPageSize: 10,
  showQuickJumper: true,
  showSizeChanger: true,
  showTotal: total => `共 ${total} 条记录`,
  locale: {
    items_per_page: '条/页',
    jump_to: '跳至',
    jump_to_confirm: '确定',
    page: '页',

    // Pagination.jsx
    prev_page: '上一页',
    next_page: '下一页',
    prev_5: '向前 5 页',
    next_5: '向后 5 页',
    prev_3: '向前 3 页',
    next_3: '向后 3 页',
  },
};

const defaultExpandableConfig = {
  expandIcon: ({ expanded, onExpand, record }) =>
    expanded ? (
      <span onClick={e => onExpand(record, e)}>
        <MinusSquareIcon />
      </span>
    ) : (
      <span onClick={e => onExpand(record, e)}>
        <PlusSquareIcon />
      </span>
    ),
};

class Table extends React.Component {
  constructor(props) {
    super();
    this.state = {
      optDropdownVisible: false,
      filteredColumnsKeys: [],
    };
  }

  componentDidMount() {
    const { columns } = this.props;
    if (columns.length > 0)
      this.setState({
        filteredColumnsKeys: this.getDefaultSelectedColumns(columns),
      });
  }

  componentDidUpdate(prevProps) {
    const { columns } = this.props;
    const { columns: prevColumns } = prevProps;
    const defaultColumnsKeys = this.getDefaultSelectedColumns(columns);
    const defaultPrevColumnsKeys = this.getDefaultSelectedColumns(prevColumns);
    const differentDefaultKeys = (arr1, arr2) => {
      for (let index = 0; index < arr1.length; index += 1) {
        if (arr1[index] !== arr2[index]) return true;
      }
      return false;
    };
    if (
      this.optOpen('columnSelector') &&
      differentDefaultKeys(defaultColumnsKeys, defaultPrevColumnsKeys)
    ) {
      this.setState({
        filteredColumnsKeys: defaultColumnsKeys,
      });
    }
  }
  getDefaultSelectedColumns = colList =>
    colList
      .filter(col => col.defaultSelected === true)
      .map(col => col.dataIndex);

  handleColFltDropdownChange = optDropdownVisible =>
    this.setState({ optDropdownVisible });

  handleColFltChange = checkedValue => {
    const { columns } = this.props;
    const filteredColumnsKeys = columns
      .filter(column => {
        if (checkedValue.find(v => v === column.dataIndex)) return column;
      })
      .map(col => col.dataIndex);
    this.setState({ filteredColumnsKeys });
  };

  withOperations = () => {
    const { operations } = this.props;
    return operations && operations.length > 0;
  };

  optOpen = optName => {
    const { operations } = this.props;
    return (
      this.withOperations() &&
      operations.find(operation => Object.keys(operation)[0] === optName)
    );
  };

  render() {
    return (
      <ConfigConsumer>
        {({ getPrefixCls, paginationIconsProps, direction }) => {
          const {
            prefixCls: customizePrefixCls,
            pagination,
            expandable,
            emptyTableText = '暂无数据',
            searchValue = '',
            handleReload,
            operations,
            optAbsolute,
            columns,
            dataSource,
            onTableFilterClear,
            loading,
            rowSelection,
            ...restProps
          } = this.props;
          const {
            selectedKeysMap = {},
            optDropdownVisible,
            filteredColumnsKeys,
            tempSelectedKeysMap = {},
          } = this.state;
          const prefixCls = getPrefixCls('table', customizePrefixCls);
          const spinPrefixCls = getPrefixCls('spin');
          let paginationProps = {};
          let expandableProps = {};
          const defaultSpinProps = { prefixCls: spinPrefixCls };
          let spinProps = { ...defaultSpinProps };
          if (pagination !== false) {
            const {
              prefixCls: paginationCustomizePrefixCls,
              selectPrefixCls: customizeSelectPrefixCls,
              ...restPaginationProps
            } = { ...pagination };
            const paginationPrefixCls = getPrefixCls(
              'pagination',
              paginationCustomizePrefixCls,
            );
            const selectPrefixCls = getPrefixCls(
              'select',
              customizeSelectPrefixCls,
            );
            paginationProps = {
              prefixCls: paginationPrefixCls,
              selectComponentClass: Select,
              selectPrefixCls,
              itemRender: (current, type, originalElement) => {
                if (type === 'prev') {
                  return (
                    <a className={`${paginationPrefixCls}-item-link`}>
                      <CaretLeftIcon />
                    </a>
                  );
                }
                if (type === 'next') {
                  return (
                    <a className={`${paginationPrefixCls}-item-link`}>
                      <CaretRightIcon />
                    </a>
                  );
                }
                if (type === 'jump-next') {
                  return (
                    <a className={`${paginationPrefixCls}-item-link`}>
                      <div className={`${paginationPrefixCls}-item-container`}>
                        <DoubleRightIcon
                          fill="currentColor"
                          className={`${paginationPrefixCls}-item-link-icon`}
                        />
                        <span
                          className={`${paginationPrefixCls}-item-ellipsis`}
                        >
                          •••
                        </span>
                      </div>
                    </a>
                  );
                }
                if (type === 'jump-prev') {
                  return (
                    <a className={`${paginationPrefixCls}-item-link`}>
                      <div className={`${paginationPrefixCls}-item-container`}>
                        <DoubleLeftIcon
                          fill="currentColor"
                          className={`${paginationPrefixCls}-item-link-icon`}
                        />
                        <span
                          className={`${paginationPrefixCls}-item-ellipsis`}
                        >
                          •••
                        </span>
                      </div>
                    </a>
                  );
                }
                return originalElement;
              },
              ...defaultPaginationConfig,
              ...restPaginationProps,
            };
          } else {
            paginationProps = false;
          }
          if (expandable) {
            expandableProps = { ...defaultExpandableConfig, ...expandable };
          }
          if (typeof loading === 'boolean') {
            spinProps = {
              spinning: loading,
              ...defaultSpinProps,
            };
          } else if (typeof loading === 'object') {
            spinProps = {
              spinning: true,
              ...defaultSpinProps,
              ...loading,
            };
          } else if (typeof loading === 'undefined') {
            spinProps = {
              spinning: false,
              ...defaultSpinProps,
            };
          }

          let rowSelectionProps = _.cloneDeep(rowSelection);
          if (rowSelection) {
            rowSelectionProps = {
              renderCell: (checked, record, index, originNode) => {
                const prefixCls = getPrefixCls(rowSelection.type || 'checkbox');
                return React.cloneElement(originNode, { prefixCls });
              },
              ...rowSelectionProps,
            };
          }

          const getColumns = () => {
            let resColumns = columns;
            if (this.optOpen('columnSelector') && filteredColumnsKeys)
              resColumns = columns.filter(col =>
                filteredColumnsKeys.find(key => key === col.dataIndex),
              );

            return resColumns.map(column => {
              const { filters, dataIndex, onTableFilterChange } = column;
              if (filters) {
                return {
                  ...customFilters({
                    column,
                    onChange: selectedKeys => {
                      const newSelectedKeysMap = _.cloneDeep(selectedKeysMap);
                      if (selectedKeys.length === 0)
                        delete newSelectedKeysMap[dataIndex];
                      else newSelectedKeysMap[dataIndex] = [...selectedKeys];
                      this.setState({ selectedKeysMap: newSelectedKeysMap });
                      if (onTableFilterChange)
                        onTableFilterChange(selectedKeys.map(key => key.value));
                    },
                    value:
                      (selectedKeysMap && selectedKeysMap[dataIndex]) || [],
                    prefixCls,
                    onSelect: selectedKeys => {
                      const newTempSelectedKeysMap = _.cloneDeep(
                        tempSelectedKeysMap || {},
                      );
                      newTempSelectedKeysMap[dataIndex] = [...selectedKeys];
                      this.setState({
                        tempSelectedKeysMap: newTempSelectedKeysMap,
                      });
                    },
                    tempSelectedKeys: tempSelectedKeysMap[dataIndex] || [],
                  }),
                  ...column,
                };
              }
              return column;
            });
          };

          const getDataSource = () => {
            if (this.optOpen('columnSelector')) {
              if (getColumns().length === 0) return [];
              return dataSource;
            }
            return dataSource;
          };

          const getAntTable = () => (
            <>
              {customFiltersLabel({
                columns,
                prefixCls,
                selectedKeysMap: selectedKeysMap,
                onClose: dataIndex => {
                  const newSelectedKeysMap = _.cloneDeep(selectedKeysMap);
                  delete newSelectedKeysMap[dataIndex];
                  this.setState({
                    selectedKeysMap: newSelectedKeysMap,
                    tempSelectedKeysMap: newSelectedKeysMap,
                  });
                  const col = columns.find(
                    column => column.dataIndex === dataIndex,
                  );
                  if (col.onTableFilterChange) col.onTableFilterChange([]);
                },
                onClear: () => {
                  this.setState({
                    selectedKeysMap: {},
                    tempSelectedKeysMap: {},
                  });
                  onTableFilterClear();
                },
              })}
              <AntdTable
                prefixCls={prefixCls}
                pagination={paginationProps}
                expandable={expandableProps}
                locale={{
                  emptyText: defaultEmptyTable({
                    emptyTableText,
                    searchValue,
                    handleReload,
                    prefixCls,
                  }),
                }}
                loading={{ ...spinProps }}
                columns={getColumns()}
                dataSource={getDataSource()}
                getPopupContainer={node => node}
                rowSelection={rowSelectionProps}
                {...restProps}
              />
            </>
          );

          return (
            <>
              {this.withOperations() ? (
                <div className={`${prefixCls}-with-operations`}>
                  <div
                    className={`${
                      optAbsolute ? `${prefixCls}-operations-absolute` : ''
                    } ${prefixCls}-operations`}
                  >
                    {operations.map(operation =>
                      getOperation({
                        operation,
                        columns,
                        prefixCls,
                        visible: optDropdownVisible,
                        onSelect: this.handleColFltChange,
                        onVisibleChange: this.handleColFltDropdownChange,
                        filteredColumnsKeys,
                      }),
                    )}
                  </div>
                  {getAntTable()}
                </div>
              ) : (
                getAntTable()
              )}
            </>
          );
        }}
      </ConfigConsumer>
    );
  }
}

export default Table;
