import Icons from '../icons';
import Menu from '../menu';
import Button from '../button';
import SubMenu from 'antd/es/menu/SubMenu';
import Checkbox from '../checkbox';

const { FilterIcon } = Icons;

const selectAll = (filters = []) => {
  return filters.reduce((prevList, filter) => {
    const { children } = filter;
    let current = [...prevList];
    if (children && children.length > 0)
      current.push(...children.map(ch => ch.value));
    else current.push(filter.value);
    return current;
  }, []);
};

const getFiltersLength = (filters = []) => {
  return filters.reduce((prevNum, filter) => {
    const { children } = filter;
    let currentNum = prevNum;
    if (children && children.length > 0) currentNum += children.length;
    else currentNum += 1;
    return currentNum;
  }, 0);
};

const handleSelect = (e, value, selectedKeys, onSelectCbFunc) => {
  const { checked } = e.target;
  if (checked) onSelectCbFunc([...selectedKeys, value]);
  else onSelectCbFunc(selectedKeys.filter(item => item !== value));
};

const handleConfirm = (confirm, selectedKeys, onConfirmCbFunc) => {
  confirm();
  onConfirmCbFunc(selectedKeys);
};

const handleClear = (clearFilters, onConfirmCbFunc) => {
  clearFilters();
  onConfirmCbFunc([]);
};

const handleSelectAll = (e, filters, onSelectCbFunc) => {
  const { checked } = e.target;
  if (checked) onSelectCbFunc(selectAll(filters));
  else onSelectCbFunc([]);
};

const allFilter = { text: '全部', value: 'all' };

export const customFilters = props => {
  const {
    onChange,
    value,
    prefixCls,
    onSelect,
    tempSelectedKeys,
    column,
  } = props;
  const { filterSize = 'middle' } = column;

  return {
    filterIcon: filtered => (
      <FilterIcon
        width={16}
        height={16}
        className={filtered ? `${prefixCls}-filter-icon-active` : ''}
      />
    ),
    filterDropdown: filterDropdownProps => {
      const {
        filters,
        clearFilters,
        confirm,
        selectedKeys,
        setSelectedKeys,
      } = filterDropdownProps;
      const filtersLen = getFiltersLength(filters);
      const isDisabled = filtersLen === 0;
      // 在回调当中调用 setSelectedKeys 会被组件直接再把值改回去，怀疑引用直接被修改了，先用暴力方法保存一份
      if (selectedKeys !== tempSelectedKeys) {
        setSelectedKeys(tempSelectedKeys);
      }
      const isChecked = key => selectedKeys.find(selected => selected === key);
      const onSelectCbFunc = keys => {
        setSelectedKeys(keys);
        onSelect(keys);
      };
      const onConfirmCbFunc = keys => {
        onSelect(keys);
        onChange(keys);
      };

      const item = (filterItem, props) => {
        const { text, value } = filterItem;
        return (
          <Menu.Item
            key={value}
            className={`${prefixCls}-filter-dropdown-menu-item-${filterSize}`}
          >
            <Checkbox
              onChange={e =>
                handleSelect(e, value, selectedKeys, onSelectCbFunc)
              }
              checked={isChecked(value)}
              {...props}
            >
              {text}
            </Checkbox>
          </Menu.Item>
        );
      };

      return (
        <div className={`${prefixCls}-filter-dropdown-menu-wrap`}>
          <Menu>
            {isDisabled && (
              <SubMenu disabled key="empty" title="暂无数据">
                暂无数据
              </SubMenu>
            )}
            {!isDisabled && (
              <>
                {item(allFilter, {
                  onChange: e => handleSelectAll(e, filters, onSelectCbFunc),
                  indeterminate:
                    filtersLen > selectedKeys.length && selectedKeys.length > 0,
                  checked: filtersLen === selectedKeys.length,
                })}
                {filters.map(f =>
                  f.children && f.children.length > 0 ? (
                    <SubMenu popupOffset={22} key={f.value} title={f.text}>
                      {f.children.map(ch => item(ch))}
                    </SubMenu>
                  ) : (
                    item(f)
                  ),
                )}
              </>
            )}
          </Menu>
          <div className={`${prefixCls}-filter-dropdown-menu-btn-wrap`}>
            <Button
              type="link"
              onClick={() => handleClear(clearFilters, onConfirmCbFunc)}
            >
              重置
            </Button>
            <Button
              type="primary"
              onClick={() =>
                handleConfirm(confirm, selectedKeys, onConfirmCbFunc)
              }
              size="small"
            >
              确定
            </Button>
          </div>
        </div>
      );
    },
    filteredValue: value,
  };
};
