import React, { Component } from 'react';
import Button from '../button/Button';
import { ColumnProps } from './interface';
import SelectTrigger from '../rc-components/select/SelectTrigger';
import { Item as MenuItem } from '../rc-components/menu';
import { UNSELECTABLE_ATTRIBUTE, UNSELECTABLE_STYLE } from '../rc-components/select/util';
import { getColumnKey } from './util';
import { Size } from '../_util/enum';
import ConfigContext, { ConfigContextValue } from '../config-provider/ConfigContext';

export interface ColumnFilterProps<T> {
  prefixCls?: string;
  columns?: ColumnProps<T>[];
  onColumnFilterChange?: (item?: any) => void;
  getPopupContainer?: (triggerNode?: Element) => HTMLElement;
}

export interface ColumnFilterState {
  open: boolean;
}

export default class ColumnFilter<T> extends Component<ColumnFilterProps<T>, ColumnFilterState> {
  static get contextType(): typeof ConfigContext {
    return ConfigContext;
  }

  static displayName = 'ColumnFilter';

  context: ConfigContextValue;

  state = {
    open: false,
  };

  render() {
    const { prefixCls, getPopupContainer } = this.props;
    const { open } = this.state;
    const { getPrefixCls } = this.context;
    return (
      <div className={`${prefixCls}-columns-chooser`}>
        <SelectTrigger
          prefixCls={getPrefixCls('select')}
          showAction={['click']}
          options={this.getOptions()}
          value={this.getVisibleColumns()}
          getPopupContainer={getPopupContainer}
          multiple
          onDropdownVisibleChange={this.onDropdownVisibleChange}
          onMenuSelect={this.onMenuSelect}
          onMenuDeselect={this.onMenuDeselect}
          visible={open}
          popupPlacement="bottomRight"
          dropdownMatchSelectWidth={false}
          dropdownStyle={{ minWidth: 187 }}
        >
          <Button shape="circle" icon="view_column" size={Size.small} />
        </SelectTrigger>
      </div>
    );
  }

  onMenuSelect = (item: any) => {
    item.item.props.value.hidden = false;
    this.fireChange(item);
  };

  onMenuDeselect = (item: any) => {
    item.item.props.value.hidden = true;
    this.fireChange(item);
  };

  onDropdownVisibleChange = (open: boolean) => {
    const { state } = this;
    if (state.open !== open) {
      this.setState({
        open,
      });
    }
  };

  fireChange(item?: any) {
    const { onColumnFilterChange } = this.props;
    if (onColumnFilterChange) {
      onColumnFilterChange(item);
    }
  }

  getOptions() {
    const { columns } = this.props;
    const options: any = [];
    (columns || []).forEach((column, i) => {
      const { title, notDisplay, disableClick } = column;
      if (title && !notDisplay) {
        options.push(
          <MenuItem
            disabled={disableClick}
            style={UNSELECTABLE_STYLE}
            attribute={UNSELECTABLE_ATTRIBUTE}
            value={column}
            key={getColumnKey(column, i)}
          >
            {title}
          </MenuItem>,
        );
      }
    });
    return options;
  }

  getVisibleColumns() {
    const { columns } = this.props;
    return (columns || []).filter(column => !column.hidden);
  }
}