import React, { Component } from 'react';
import { Table, Icon, Button, Row, Col, Tabs, Input } from 'antd';
import PropTypes from 'prop-types';
import { difference } from 'lodash/array';
import 'whatwg-fetch';
import './admintable.less';

const TabPane = Tabs.TabPane;
// 扩展表格尾列功能
const actionText = { delete: '删除', edit: '编辑', userDefined: '自定义' };
// 对象转化为url参数
const urlEncode = function (param, key, encode) {
  if (param == null) return '';
  let paramStr = '';
  const t = typeof (param);
  if (t === 'string' || t === 'number' || t === 'boolean') {
    paramStr += `&${key}=${((encode === null || encode) ? encodeURIComponent(param) : param)}`;
  } else {
    for (let i in param) {
      const k = key == null ? i : key + (param instanceof Array ? `[${i}]` : `.${i}`);
      paramStr += urlEncode(param[i], k, encode);
    }
  }
  return paramStr;
};

class AdminTable extends Component {
  constructor(props) {
    super(props);
    this.state = {
      // 当前表格数据
      data: null,
      // [多选框] 选中的行
      selectedRow: [],
      // 数据是否接收完毕
      isDataBagged: false,
      total: 0,
      // 编辑表格数据
      isDataEditing: false,
      // 表格数据编辑面板
      editPanelNode: [],
      // 表格数据编辑面板数据值
      editPanelNodeValue: {},
      // 显示高级搜索
      showAdvancedSearch: false,
      searchNode: [],
      searchGroup: [],
      currentPage: 1
    };
    this.toggleTablePanel = this.toggleTablePanel.bind(this);
    this.lineOperate = this.lineOperate.bind(this);
    this.renderTable = this.renderTable.bind(this);
    this.tableEditPanel = this.tableEditPanel.bind(this);
    this.handleAdd = this.handleAdd.bind(this);
    this.handleChange = this.handleChange.bind(this);
    this.search = this.search.bind(this);
    this.handleSelected = this.handleSelected.bind(this);
  }
  componentWillMount() {
    const { url, method, param } = this.props.fetch;
    let object = {};
    object[param.start.name]=param.start.value;
    object[param.pageSize.name] = param.pageSize.value;
    this.renderTable(url, method, object);
  }
  // 渲染表格
  renderTable(url, method, parameters) {
    this.setState({
      isDataBagged: false
    })
    const { action } = this.props;
    const columns = [];
    const { column } = this.props;
    const param = urlEncode(parameters).replace('&', '?');
    url += method.toUpperCase() === 'GET' ? param : '';
    fetch(
      url,
      {
        credentials: 'include',
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded',

        },
        method: method,
        body: method === 'POST' ? JSON.stringify(parameters) : null, // 搜素方式待定
      })
    .then(response => response.json())
    .then((data) => {
      const dataSource = this.props.fetch.catchData(data);
      const dataTotal = this.props.fetch.catchTotal(data);
      // 获取后台数据数据
      if (!(dataSource.hasOwnProperty('key'))) {
        dataSource.map((item, index) => {
          dataSource[index].key = index;
        });
      }
      this.setState({
        data: dataSource,
        total: dataTotal,
        editPanelNodeValue: Object.assign(dataSource[0])
      });
      // 获取成功
      // 遍历用户定义的列,及其标题
      column.map((item, index) => {
        // 表格列排序
        let columnSort = item.dataIndex,
            // 列元素类型
          elementShape = item.shape && item.shape.model,
            // 列标题
          columnTitle = item.title,
            // 自定义转化数据
          conversion = item.shape && item.shape.conversion;
        const columnsItem = {
          title: columnTitle,
          dataIndex: columnSort,
          key: index, // 渲染指定类型,默认为文本
          render: ((text) => {
                if(!elementShape) {
                  return <span>{text}</span>;
                } else {
                  let innerProps = item.shape.innerProps || null;
                  // 属性对象
                  const object = new Object();
                  object[innerProps] = text;
                  return React.cloneElement(
                    elementShape,
                    item.shape.innerProps ? object : (conversion && conversion(text).props),
                    item.shape.innerProps ? null : ((conversion && conversion(text).value) || text),
                  );
                }
              }),
        };
        if (!!item.sorter) {
          columnsItem.sorter = item.sorter;
        }
        columns.push(columnsItem);
      });
      // 表格最后一列相关功能
      if (action) {
        columns.push({
          title: this.props.action.title,
          dataIndex: 'operation',
          key: action,
          render: ((text, record) =>
            {
              let operationNode = [];
              const _this = this;
                action.default.map(function(item, index) {
                  operationNode.push(
                    <a
                      key={`operation${index}`}
                      onClick={() => { _this.lineOperate(item, _this.props.fetch.url, record); }}
                    >
                      {actionText[item]}
                    </a>
                     );
                  operationNode.push(
                    !(index === action.default.length - 1) && <span key={item} className="ant-divider" />
                  );
               })
               // 自定义
               if (action.custom) {
                 operationNode.push(
                   <span key={'split'} className="ant-divider" />
                 );
                 operationNode.push(
                   <a
                     key={'operation-custom'}
                     onClick={() => { _this.lineOperate('custom', _this.props.fetch.url, record); }}
                   >
                     { this.props.action.custom.name }
                   </a>
                 );
               }
              return operationNode;
            })
        })
      }
      this.setState({
        data: dataSource,
        columns: columns,
        isDataBagged: true
      });
    })
    .catch((err) => {
      console.log(err);
    });
  }
  // 渲染数据编辑面板
  tableEditPanel(action, record, url) {
    const _this = this;
    // 数据编辑面板中填写项目
    let panelList = [];
    let panelListNode = []; // 根据数据生成DOM节点
    panelList.push(...Object.keys(record));
    panelList.map((item) => {
      const dom = (
        <div key={item}>
          {`请输入: ${_this.props.fetch.defineKeyValue[item].value}`}
          <Input
            // key 不可变更
            disabled={action === 'edit' && _this.props.fetch.defineKeyValue[item].editable}
            defaultValue={action === 'edit' ? record[item] : null}
            placeholder={action === 'edit' ? record[item] : null}
            onChange={(event, target) => _this.handleChange(event, item)}
          />
        </div>
      )
      panelListNode.push(dom);
    })
    panelListNode.push(
      <div key="submit">
        <Button
          // 渲染面板前需清空输入框原defaultValue值
          onClick={() => { panelListNode.length = 0; this.handleTransmit(action, url, record); }}
        >
          确定
        </Button>
        <Button
          onClick={() => { panelListNode.length = 0; this.toggleTablePanel(); }}
        >
          取消
        </Button>
      </div>)
    this.setState({
      editPanelNode: panelListNode
    });
  }
  // 表格和数据编辑面板切换
  toggleTablePanel() {
    this.setState({
      isDataEditing: !this.state.isDataEditing
    });
  }
  // 行内操作
  lineOperate(action, url, record) {
    if (!url) {
      url = this.props.fetch.url;
    }
    switch (action) {
      case 'edit':
        this.tableEditPanel('edit', record, url)
        this.setState({
          editPanelNodeValue: record
        })
        this.toggleTablePanel();
        break;
      case 'delete':
        console.log('准备执行删除', record);
        fetch(
          url,
          {
            credentials: 'include',
            headers: {
              'Content-Type': 'application/x-www-form-urlencoded',
            },
            method: 'POST',
            body: JSON.stringify(record), // 搜素方式待定
          })
          .then(response => response.json())
          .then((res) => {
            if (res.code === 0 ) {
              this.setState({
                total: --this.state.total,
                data: difference(this.state.data, [record, ...record])
              });
            } else {
              console.log('删除失败');
            }
          })
          .catch((err) => {
            console.log('post请求失败');
            console.log(err);
          });
        break;
      case 'custom':
        this.props.action.custom.func(record);
        break;
      default:
        break;
    }
  }
  handleSelected(){
    return this.state.selectedRow;
  }
  // 点击添加按钮
  handleAdd(url) {
    if (!url) {
      url = this.props.fetch.url;
    }
    this.toggleTablePanel();
    // 将值赋值为空
    // 获取数据的所有属性
    let dataProps = Object.keys(this.state.data[1]);
    let newData = {};
    dataProps.forEach( (item) => {
      newData[item] = '';
    })
    this.tableEditPanel('add', newData, url);
  }
  /**
   * 监听输入数据，将数据变更值存入state中
   */
  handleChange(event, key) {
    const editRow = Object.assign({}, this.state.editPanelNodeValue);
    editRow[key] = event.target.value;
    this.setState({
      editPanelNodeValue: editRow
    });
  }
  /**
   * 发送数据变更
   * @param
   */
  handleTransmit(action, url, record) {
    const newData = this.state.editPanelNodeValue;
    const preData = this.state.data;
    let { total } = this.state;
    if (!record) {
      record = this.state.selectedRow
    }
    switch (action) {
      case 'add':
        const newDataArr = [newData, ...preData];
        fetch(
          url,
          {
            method: 'POST',
            body: JSON.stringify(newData), // 搜素方式待定
          })
          .then(response => response.json())
          .then(data => {
            console.log(newData)
            this.setState({
              data: [newData, ...this.state.data],
              total: ++total
            })
            this.toggleTablePanel();
          })
        .catch((err) => {
        // 移动到then中
          console.log(err);
        })
        break;
      case 'delete':
        console.log(record)
        this.lineOperate(action, url, record);
        break;
      case 'edit':
        fetch(
          url,
          {
            method: 'POST',
            body: JSON.stringify(newData), // 搜素方式待定
          })
          .then(response => response.json())
          .then(data => {
            console.log(newData)
            let dataUpdate=[];
            preData.map((item)=>{
              if(item.key === newData.key) {
                dataUpdate.push(Object.assign(item,newData))
              }else {
                dataUpdate.push(Object.assign(item))
              }
            })
            this.toggleTablePanel();
            this.setState({
              data: newDataArr
            });
          })
          .catch((err) => {
            // 移动到then中
            console.log(err);
          })
        break;
      default:
        break;
    }
  }
  search(searchObj, method, url) {
    if(!url){
      url = this.props.fetch.url;
    }
    let param = this.props.fetch.param;
    let object = {};
    object[param.start.name] = param.start.value;
    object[param.pageSize.name] = param.pageSize.value;
    // 带搜索键值对的参数
    const paramWithSearch = Object.assign({}, object, searchObj);
    this.renderTable(url, method, paramWithSearch);
  }
  // 点击某行
 /*
  onRowClick(recode) {
    console.log(recode);
  }
  */
  render() {
    const { url, method } = this.props.fetch;
    // 定义选择框
    const rowSelection = {
      selections: 'checkbox',
      onChange: (selectedRowKeys, selectedRows) => {
        this.setState({
          selectedRow: selectedRows,
        });
      },
    };
    // 定义分页选项
    const pagination = {
      defaultPageSize: this.props.fetch.param.pageSize.value,
      total: this.state.total,
      current: this.state.currentPage,
      onChange: (page, pageSize) => {
        const { param } = this.props.fetch;
        let object = {};
        object[param.start.name]=page;
        object[param.pageSize.name] = pageSize;
        this.setState({
          currentPage: page
        });
        this.renderTable(url, method, object)
        console.log(page, pageSize);
      }
    };
    return (
      <div>
        {this.state.isDataBagged &&
        <Tabs
          defaultActiveKey={'table'}
          activeKey={this.state.isDataEditing ? 'edit' : 'table'}
          tabBarStyle={{ display: 'none' }}
        >
          <TabPane key="table" tab="table">
            {/* 显示表格 */}
            <Row type="flex" justify={`${this.state.showAdvancedSearch ? 'end' : 'space-between'}`}>
              {!this.state.showAdvancedSearch &&
                <Col span={8} type="flex" >
                  {(this.props.showAdd || this.props.showDel) &&
                    <Row>
                      { this.props.showAdd &&
                      <Col span={8}>
                        <Button type="primary" onClick={() => this.handleAdd(url)}>添加</Button>
                      </Col>
                      }
                      { this.props.showDel &&
                      <Col span={8}>
                        <Button
                          type={`${this.state.selectedRow.length === 0 ? 'default' : 'danger'}`}
                          onClick={() => this.handleTransmit('delete', url, this.state.selectedRow)}
                        >
                          删除
                        </Button>
                      </Col>
                      }
                    </Row>
                  }
                </Col>
              }
              { !!this.props.search &&
              <Col span={10}>
                <Row type="flex" justify={`${(this.props.search && this.props.search.type==="composite") ? "space-between" : "end"}`}>
                  {this.state.searchNode}
                </Row>
              </Col>
              }
            </Row>
            {
               this.state.showAdvancedSearch &&
               <Row type="flex" justify="end">
                 <Col span={10}>
                   {this.state.searchGroup}
                 </Col>
               </Row>
            }
            <Table
              rowSelection={this.props.showSelect ? rowSelection : null}
              bordered
              columns={this.state.columns}
              dataSource={this.state.data}
              pagination={this.props.pagination ? pagination : false }
              size={this.props.size || 'default'}
              onRowClick={this.onRowClick}
              // 根据record让用户自定义展开内容
              expandedRowRender={this.props.collapse ? (record) => {
                console.log(this.props.collapse.shape.conversion(record), record)
                if (!this.props.collapse.shape) {
                  return <div>{this.props.collapse.shape.conversion(record).value}</div>;
                }
                return React.cloneElement(
                  this.props.collapse.shape.model,
                  this.props.collapse.shape.conversion(record).props,
                  this.props.collapse.shape.conversion(record).value
                );
              } : null
              }
            />
          </TabPane>
          {/* 显示新增一项页面 */}
          <TabPane key="edit" tab="edit">
            {this.state.editPanelNode}
          </TabPane>
        </Tabs>
        }
      </div>
    );
  }
}
AdminTable.PropTypes = {
  showSelect: PropTypes.bool,
  showAdd: PropTypes.bool,
  showDel: PropTypes.bool,
  showCollapse: PropTypes.bool,
  pagination: PropTypes.bool,
  ref: PropTypes.string.isRequired,
  fetch: PropTypes.shape({
    url: PropTypes.string,
    method: PropTypes.string,
    dataKey: PropTypes.string,
    param: PropTypes.shape({
      start: PropTypes.number,
      pageSize: PropTypes.number,
    }),
    catchData: PropTypes.func,
    catchTotal: PropTypes.func,
    filter: PropTypes.array
  }),
  column: PropTypes.arrayOf({
    dataIndex: PropTypes.number,
    shape: PropTypes.shape({
      type: PropTypes.string,
      props: PropTypes.object
    }),
    title: PropTypes.string
  }).isRequired,
  action: PropTypes.shape({
    default: PropTypes.array,
    custom: PropTypes.shape({
      name: PropTypes.string,
      func: PropTypes.func
    })
  }),
  search: PropTypes.shape({
    type: PropTypes.string,
    searchKeys: PropTypes.arrayOf(PropTypes.string)
  })
};
  // 指定 props 的默认值：
AdminTable.defaultProps = {
  showSelect: false,
  showAdd: false,
  showDel: false,
  showCollapse: false,
  pagination: true,
  segment: {
    start: 0,
    pageSize: 6,
    filter: []
  }
};
export default AdminTable;
