
import React from 'react';
import { Button, Checkbox, Col, Dropdown, Menu, Popconfirm, Row, Table, Tooltip } from 'antd';
import styles from './DataTable.less';
import SearchBar from './SearchBar';
import { formUtils, numberUtils } from '@utils';

const getRowClassName = (record, index) => {
  return index % 2 === 0 ? 'table-stripe-odd' : '';
};

class DataTable extends React.Component {
  componentDidMount = () => {
    const { filter, withFetch } = this.props;
    const { fetchData } = this.state;

    let iniFilter = [];
    filter && filter.forEach((f) => {
      if (f.options && f.options.initialValue !== undefined) {
        iniFilter.push({
          [f.dataIndex]: f.options.initialValue,
        });
      }
    });

    // console.log('1', iniFilter);
    const newFetchData = Object.assign({}, fetchData, ...iniFilter);

    // console.log(newFetchData)

    this.setState({
      fetchData: newFetchData,
    }, () => {
      withFetch !== false && this.fetchList();
      // this.fetchList();
    });
  };

  componentWillReceiveProps = (nextProps) => {
    // console.log(nextProps.columns);
    // this.setState({
    //   columns: nextProps.columns,
    // });
  };

  onAddItem = () => {
    this.props.dispatch({
      type: `${this.props.domain}/getSingle`,
      payload: {
        mode: 'create',
      },
    });
    this.setState({
      selectedRowKeys: [],
      selectedRows: [],
    });
  };
  onDeleteItems = () => {
    this.props.dispatch({
      type: `${this.props.domain}/delete`,
      payload: {
        ids: this.state.selectedRowKeys,
      },
    });
    this.setState({
      selectedRowKeys: [],
      selectedRows: [],
    });
  };
  onEditItem = () => {
    this.props.dispatch({
      type: `${this.props.domain}/getSingle`,
      payload: {
        mode: 'update',
        id: this.state.selectedRowKeys[0],
      },
    });
    this.setState({
      selectedRowKeys: [],
      selectedRows: [],
    });
  };
  onViewItem = () => {
    // const { dataSource } = this.props
    this.props.dispatch({
      type: `${this.props.domain}/getSingle`,
      payload: {
        mode: 'view',
        id: this.state.selectedRowKeys[0],
        // item: dataSource.filter(d => d.buzId === this.state.selectedRowKeys[0])[0]
      },
    });
    // this.setState({
    //   selectedRowKeys: [],
    // })
  };
  handleRowDoubleClick = (record, index) => {
    const rowKey = this.props.rowKey || 'id';
    this.props.dispatch({
      type: `${this.props.domain}/getSingle`,
      payload: {
        mode: 'view',
        id: record[rowKey],
        // item: dataSource.filter(d => d.buzId === this.state.selectedRowKeys[0])[0]
      },
    });
  };

  fetchSearchBarForm = (formFields) => {
    this.setState({
      searchBarForm: Object.assign({}, this.state.searchBarForm, formFields),
    });
  };

  onFilterChange = (formFields) => {
    const { fetchData, pagination } = this.state;
    const { rowKey, sortBy, limit, offset, sortDirection } = this.props;
    const pager = Object.assign({}, pagination);
    pager.current = 1; // 回到第一页
    pager.pageSize = pagination.pageSize;

    const newFetchData = Object.assign({}, fetchData, {
      offset: 0, // 回到第一页
      limit: fetchData.limit || limit,
      sortBy: fetchData.sortBy || sortBy || rowKey,
      sortDirection: fetchData.sortDirection || sortDirection,
      ...formFields,
    });

    //console.log(formFields);

    this.setState({
      pagination: pager,
      fetchData: newFetchData,
      selectedRowKeys: [],
      selectedRows: [],
    }, () => {
      this.fetchList();
    });
  };

  handleTableChange = (pagination, filters, sorter) => {
    const pager = Object.assign({}, this.state.pagination);
    const { fetchData } = this.state;
    const { rowKey, sortBy, sortDirection } = this.props;

    pager.current = pagination.current;
    pager.pageSize = pagination.pageSize;

    const newFetchData = Object.assign({}, fetchData, {
      limit: pagination.pageSize,
      offset: (pagination.current - 1) * pagination.pageSize,
      sortBy: sorter.field || rowKey,
      sortDirection: sorter.order === 'descend' ? 'DESC' : (sorter.order === 'ascend' ? 'ASC' : 'DESC'),
      ...filters,
    });

    this.setState({
      pagination: pager,
      fetchData: newFetchData,
      selectedRowKeys: [],
      selectedRows: [],
    }, () => {
      this.fetchList();
    });
  };

  fetchList = () => {
    this.props.dispatch({
      type: `${this.props.domain}/query`,
      payload: formUtils.standardiseFormData(this.state.fetchData),
    });
  };

  handleVisibleChange = (flag) => {
    this.setState({ colsSwitchVisible: flag });
  };

  handleColsSwitch = (dataIndex) => {
    const { columns, scroll } = this.state;
    const { domain } = this.props;

    let newScrollX = scroll.x;

    if (scroll && scroll.x && typeof scroll.x === 'string') {
      newScrollX = parseInt(numberUtils.percentage2Number(scroll.x));
    }

    // console.log(newScrollX);

    const newColumns = columns.slice();
    newColumns.forEach((c) => {
      // console.log(c.width);

      // c.width = numberUtils.percentage2Number(c.width);
      if (c.dataIndex === dataIndex) {
        if (c.visible || c.visible === undefined) {
          if (c.width && typeof c.width === 'string') {
            newScrollX -= numberUtils.percentage2Number(c.width);
          }
          c.visible = false;
        } else {
          if (c.width && typeof c.width === 'string') {
            newScrollX += numberUtils.percentage2Number(c.width);
          }
          c.visible = true;
        }
        // console.log(c);
      }
    });

    // Save columns to local storage
    localStorage.setItem(`tbl_col_${domain}`, JSON.stringify(newColumns.map(m => {
      return { dataIndex: m.dataIndex, visible: m.visible, width: m.width };
    })));

    this.setState({
      columns: newColumns,
      scroll: {
        x: newScrollX + '%',
        y: scroll.y
      },
    });
  };

  renderColsSwitch = (cols) => {
    return cols.map((col) => {
      return (<Menu.Item key={col.dataIndex}>
        <Checkbox
          defaultChecked={col.visible}
          onChange={this.handleColsSwitch.bind(this, col.dataIndex)}
        >
          {col.title}
        </Checkbox>
      </Menu.Item>);
    });
  };

  showUploadModal = () => {
    this.props.dispatch({
      type: `${this.props.domain}/showUploadModal`,
      payload: true,
    });
  };

  handleDownload = (url) => {
    const a = document.createElement('a');
    // a.style = 'display: none';
    a.style.display = 'none';
    // a.download = fileName;
    a.href = url;
    a.target = '_blank';

    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
  };

  renderHeader = () => {
    const { selectedRowKeys, selectedRows, searchBarForm, colsSwitchVisible, fetchData, columns } = this.state;
    const {
      loading, showColumn, showAdd, showEdit, showView, showDelete, buttons,
      handleMail, handlePrint, showUpload, handleDownload
    } = this.props;
    const menu = columns.length && <Menu>{this.renderColsSwitch(columns)}</Menu>;

    return (
      <Row>
        <Col span={18}>
          {(showAdd !== false) &&
          <Button
            key="add"
            type="primary"
            onClick={this.onAddItem}
          >新增
          </Button>}
          {
            selectedRowKeys.length > 0 && [
              selectedRowKeys.length === 1 && [
                (showEdit !== false) && <Button
                  key="edit"
                  type="primary"
                  style={{ marginLeft: 8 }}
                  onClick={this.onEditItem}
                >修改</Button>,
                (showView !== false) && <Button
                  key="view"
                  type="primary"
                  style={{ marginLeft: 8 }}
                  onClick={this.onViewItem}
                >查看</Button>,
              ],
              <Popconfirm
                key="pop"
                title={'确定要删除这些记录么?'}
                placement="left"
                onConfirm={this.onDeleteItems}
              >
                {(showDelete !== false) &&
                <Button
                  key="delete"
                  type="primary"
                  style={{ marginLeft: 8 }}
                  loading={loading.effects[`${this.props.domain}/delete`]}
                >删除</Button>}
              </Popconfirm>,
            ]
          }
          {
            buttons && buttons.map(b => {
              if (b.hidden) return null;
              if (b.requiredSelected === 1 && selectedRowKeys.length === 1) {
                return (<Button
                  key={b.key}
                  disabled={b.disabled}
                  type={b.type}
                  onClick={() => {
                    b.cb(selectedRowKeys, searchBarForm, selectedRows);
                    this.setState({
                      selectedRowKeys: [],
                      selectedRows: [],
                    });
                  }}
                  style={{ marginLeft: 8 }}
                  loading={b.loading}
                >{b.name}</Button>);
              } else if (b.requiredSelected === 2 && selectedRowKeys.length >= 1) {
                return (<Button
                  key={b.key}
                  disabled={b.disabled}
                  type={b.type}
                  onClick={() => {
                    b.cb(selectedRowKeys, searchBarForm, selectedRows);
                    this.setState({
                      selectedRowKeys: [],
                      selectedRows: [],
                    });
                  }}
                  style={{ marginLeft: 8 }}
                  loading={b.loading}
                >{b.name}</Button>);
              } else if (b.requiredSelected === 0) {
                return (<Button
                  key={b.key}
                  disabled={b.disabled}
                  type={b.type}
                  onClick={() => b.cb(selectedRowKeys, searchBarForm, selectedRows)}
                  style={{ marginLeft: 8 }}
                  loading={b.loading}
                >{b.name}</Button>);
                // return (<Upload {...b.uploadProps}>
                //   <Button
                //     key={b.key}
                //     type={b.type}
                //     style={{ marginLeft: 8 }}
                //     loading={b.loading}
                //   >{b.name}</Button>
                // </Upload>);
              } else {
                // return (<Button
                //   key={b.key}
                //   type={b.type}
                //   onClick={() => b.cb(selectedRowKeys)}
                //   style={{ marginLeft: 8 }}
                //   loading={b.loading}
                // >{b.name}</Button>);
              }
            })
          }
          {
            selectedRowKeys.length > 0 &&
            <span key="total" style={{ fontSize: 13, marginLeft: 10 }}>
              选择了 {selectedRowKeys.length} 条记录
          </span>
          }
        </Col>
        {(showColumn !== false) &&
        <Col span={6} style={{ textAlign: 'right' }}>
          {/* 邮件 */}
          {
            handleMail &&
            <Tooltip placement="top" title={'发送'}>
              <Button
                icon={'mail'}
                style={{ marginRight: 5 }}
                onClick={handleMail.bind(this, selectedRowKeys, selectedRows)}
              />
            </Tooltip>
          }
          {/* 打印 */}
          {
            handlePrint &&
            <Tooltip placement="top" title={'打印'}>
              <Button
                icon={'printer'}
                style={{ marginRight: 5 }}
                onClick={handlePrint.bind(this, selectedRowKeys, selectedRows)}
              />
            </Tooltip>
          }
          {/* 上传 */}
          {
            showUpload &&
            <Tooltip placement="top" title={'导入'}>
              <Button
                icon={'upload'}
                style={{ marginRight: 5 }}
                onClick={this.showUploadModal}
              />
            </Tooltip>
          }
          {/* 下载 */}
          {
            handleDownload &&
            <Tooltip placement="top" title={'导出'}>
              {/* <a href={`${handleDownload.requestUrl}${handleDownload.requestParam}`}> */}
              <Button
                icon={'download'}
                style={{ marginRight: 5 }}
                onClick={() => this.handleDownload(`${handleDownload.requestUrl}${handleDownload.requestParam}&rownum=2000`)}
              />
              {/* </a> */}
            </Tooltip>
          }
          <Dropdown
            // getPopupContainer={() => document.getElementById('main')}
            overlay={menu}
            onVisibleChange={this.handleVisibleChange}
            visible={colsSwitchVisible}
            trigger={['click']}
            placement="bottomRight"
          >
            <Tooltip placement="top" title={'显示列'}>
              <Button icon={'table'}/>
            </Tooltip>
          </Dropdown>
        </Col>}
      </Row>
    );
  };

  handleOnRow = (record, index) => {
    return {
      onClick: () => {  // 点击行
        // console.log(record);
      },
      onMouseEnter: () => {  // 鼠标移入行
      },
      onDoubleClick: () => {
        this.props.enableDoubleClick !== false && this.handleRowDoubleClick(record, index);
      },
    };
  };

  constructor(props) {
    super(props);

    const {
      sortBy,
      sortDirection,
      columns,
      rowKey,
      limit,
      offset,
      domain,
      scroll,
    } = props;

    let newColumns = columns.slice();
    // console.log('limit', limit);

    // Load column config
    const storedCol = JSON.parse(localStorage.getItem(`tbl_col_${domain}`));

    newColumns = newColumns.map(c => {
      const visible = storedCol ? storedCol.find(m => m.dataIndex === c.dataIndex).visible : true;
      const width = storedCol ? storedCol.find(m => m.dataIndex === c.dataIndex).newWidth : c.width;
      if (c.dataIndex === sortBy) {
        // console.log(c.dataIndex, sortDirection);
        return {
          ...c,
          visible,
          width,
          defaultSortOrder: sortDirection === 'DESC' ? 'descend' : 'ASC',
        };
      } else {
        return {
          ...c,
          visible,
        };
      }
    });

    this.state = {
      searchBarForm: {},
      fetchData: {
        offset: parseInt(offset, 10) || 0,
        limit: parseInt(limit, 10) || 10,
        sortBy: sortBy || rowKey,
        sortDirection: sortDirection || 'ASC',
      },
      selectedRowKeys: [],
      selectedRows: [],
      pagination: {
        showSizeChanger: true,
        showQuickJumper: true,
        pageSizeOptions: ['10', '20', '30', '50', '100'],
        showTotal: total => `共 ${total} 条`,
        defaultPageSize: 10,
        defaultCurrent: 1,
        pageSize: parseInt(limit, 10) || 10,
        current: (parseInt(offset, 10) / limit) + 1 || 1,
        total: this.props.total,
      },
      scroll: { x: scroll.x || `${100 + columns.length * 5}%`, y: scroll.y || 350 },
      columns: newColumns,
      colsSwitchVisible: false,
    };
  }

  render() {
    const { rowSelection, dataSource, loading, domain, filter, rowKey, enableSelection, enablePagination, showReset, ...tableProps } = this.props;
    const { pagination, selectedRowKeys, columns, scroll } = this.state;

    let total = 0;

    columns.forEach(c => {
      // console.log(c.width);
      if (c.width && typeof c.width === 'string') {
        total += numberUtils.percentage2Number(c.width);
      }
    });

    // console.log(total, scroll);

    let visibleColumns = columns.filter(c => c.visible !== false);

    pagination.total = this.props.total;
    const elRowSelection = {
      // fixed: true,
      type: 'radio',
      selectedRowKeys, // 不要覆盖
      onChange: (selectedRowKeys, selectedRows) => { // 不要覆盖
        this.setState({
          selectedRowKeys,
          selectedRows,
        });
      },
    };
    return (
      <div>
        {filter && <SearchBar
          showReset={showReset}
          domain={domain}
          onFetchForm={this.fetchSearchBarForm}
          onFilterChange={this.onFilterChange}
          onFilterChanged={this.props.onFilterChanged}
          filter={filter}
        />}
        <Table
          title={this.renderHeader}
          className={styles.table}
          bordered={true}
          rowKey={rowKey || 'id'}
          size="small"
          onChange={this.handleTableChange}
          loading={loading.effects[`${this.props.domain}/query`]}
          dataSource={dataSource}
          pagination={enablePagination === false ? false : pagination}
          rowSelection={enableSelection === false ? null : { ...elRowSelection, ...rowSelection }}
          onRow={this.handleOnRow}
          rowClassName={getRowClassName}
          {...tableProps}
          scroll={scroll}
          columns={visibleColumns}
        />
      </div>
    );
  }
}

export default DataTable;
