import fetch from 'dva/fetch';
import React from 'react';
import ReactDOM from 'react-dom';
import { Select, Button, Modal, Input, Transfer, Row, Col, Form, message, notification } from 'antd';
import { connect } from 'dva';
import { getToken } from '@/utils/authority';
import config from '@/config/config';
import QueryItem from './QueryItem';
import OrderItem from './OrderItem';

import FormdataWrapper from '@/utils/object-to-formdata-custom';

const Option = Select.Option;
let keyX = 1;
function swapArray(arr, index1, index2) {
  arr[index1] = arr.splice(index2, 1, arr[index1])[0];
  return arr;
}
const FormItem = Form.Item;

@connect(({ DataObj, loading }) => ({
  DataObj,
  loading: loading.models.DataObj,
}))
@Form.create()
export default class Index extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      visiable: false,

      queryVisiable: false,
      groupVisiable: false,
      sortVisiable: false,
      currentQueryKey: null,
      currentGroupKey: null,
      orderVisiable: false,
      currentOrderKey: null,
      querys: [],
      orders: [],
      groups: [],
      gs: [],
      os: [],
      qs: [],
      mockData: [],
      targetKeys: [],
      sourceSelectedKeys: [],
      targetSelectedKeys: [],
      infos: {},
      confirmLoading: false,
    };
  }

  onSelectChange = (sourceSelectedKeys, targetSelectedKeys) => {
    this.setState({ sourceSelectedKeys, targetSelectedKeys });
  };
  deleteQuery = (i) => {
    const querys = this.state.querys;
    querys.splice(i, 1);
    this.setState({ querys });
  };
  deleteOrder = (i) => {
    const orders = this.state.orders;
    orders.splice(i, 1);
    this.setState({ orders });
  };
  deleteGroup = (i) => {
    const groups = this.state.groups;
    groups.splice(i, 1);
    this.setState({ groups });
  };
  open = () => {
    const { dispatch } = this.props;
    dispatch({
      type: 'DataObj/getExportInfo',
      payload: {
        objId: this.props.objId,
      },
      callback: (infos) => {

        const mockData = [];
        const qs = [];
        const gs = [];
        const os = [];
        for (var key in infos) {
          const x = infos[key];
          mockData.push({
            key: x.field,
            title: x.name,
            chosen: false,
          });
          if (x.canQuery) {
            qs.push(x);
          }
          if (x.canGroup) {
            gs.push(x);
          }
          if (x.canOrder) {
            os.push(x);
          }
        }

        this.setState({
          mockData, infos, visiable: true, qs, gs, os,
        });

      },
    });
  };
  onCancle = () => {
    this.setState({ visiable: false });
  };
  handleChange = (targetKeys, direction, moveKeys) => {

    this.setState({ targetKeys });
  };

  up = () => {
    keyX = keyX + 1;
    var { targetKeys, targetSelectedKeys } = this.state;
    for (var i = 0; i < targetKeys.length; i++) {
      if (targetKeys[i] === targetSelectedKeys[0]) {
        if (i === 0) return;
        targetKeys = swapArray(targetKeys, i, i - 1);

        break;
      }
    }

    this.setState({ targetKeys });
  };
  down = () => {
    keyX = keyX + 1;
    var { targetKeys, targetSelectedKeys } = this.state;
    for (var i = 0; i < targetKeys.length; i++) {
      if (targetKeys[i] === targetSelectedKeys[0]) {
        if (i === targetKeys.length - 1) return;
        targetKeys = swapArray(targetKeys, i, i + 1);

        break;
      }
    }

    this.setState({ targetKeys });
  };
  bottom = () => {
    keyX = keyX + 1;
    const { targetKeys, targetSelectedKeys } = this.state;
    var x = [];
    for (var i = 0; i < targetKeys.length; i++) {
      if (!targetSelectedKeys.includes(targetKeys[i])) {
        x.push(targetKeys[i]);
      }
    }
    x = [...x, ...targetSelectedKeys];
    this.setState({ targetKeys: x });
  };
  top = () => {
    keyX = keyX + 1;
    const { targetKeys, targetSelectedKeys } = this.state;
    const x = [...targetSelectedKeys];
    for (var i = 0; i < targetKeys.length; i++) {
      if (!targetSelectedKeys.includes(targetKeys[i])) {
        x.push(targetKeys[i]);
      }
    }


    this.setState({ targetKeys: x });
  };
  renderItem = (item) => {
    if (this.state.targetKeys.includes(item.key)) {
      const customLabel = (
        <span className="custom-item" key={item.key}>
          {item.title}

        </span>
      );
      return {
        label: customLabel, // for displayed item
        value: item.title, // for title and filter matching
      };

    } else {
      const customLabel = (
        <span className="custom-item" key={item.key}>
          {item.title}
        </span>
      );
      return {
        label: customLabel, // for displayed item
        value: item.title, // for title and filter matching
      };
    }
  };
  addOrder = () => {

    this.setState({ orderVisiable: true });

  };
  okOrder = () => {
    const orders = this.state.orders;
    orders.push(this.state.infos[this.state.currentOrderKey]);
    this.setState({ orders, orderVisiable: false, currentOrderKey: null });

  };
  okGroup = () => {
    const groups = this.state.groups;
    groups.push(this.state.infos[this.state.currentGroupKey]);
    this.setState({ groups, groupVisiable: false, currentGroupKey: null });
  };
  addGroup = () => {
    this.setState({ groupVisiable: true });
  };

  addQuery = () => {
    this.setState({ queryVisiable: true });
  };
  okQuery = () => {
    const querys = this.state.querys;
    querys.push(this.state.infos[this.state.currentQueryKey]);
    this.setState({ querys, queryVisiable: false, currentQueryKey: null });

  };
  export = () => {
    this.props.form.validateFields((err, fieldsValue) => {
      if (err) return;
      //form.resetFields();
      var qqs;
      if (this.props.mustQuerys != null) {
        qqs = [...this.props.mustQuerys];
      } else {
        qqs = [];
      }

      const oos = [];
      const ggs = [];
      for (let key in fieldsValue) {
        var x = key.indexOf('__');
        let kk = key.substr(x + 2);
        if (key.indexOf('q__') > -1) {
          qqs.push({
            notes: this.state.infos[kk].notes,
            hql: this.state.infos[kk].hql,
            c: this.state.infos[kk].type,
            x: fieldsValue[key].stringX,
            v: fieldsValue[key].string,
          });

        } else if (key.indexOf('o__') > -1) {
          oos.push({ hql: this.state.infos[kk].hql, x: fieldsValue[key].stringX });
        } else if (key.indexOf('g__') > -1) {
          ggs.push({ hql: this.state.infos[kk].hql });
        }
      }

      if (this.props.voClass && ggs.length === 0) {
        message.error('请至少选择一个聚合条件');
        return;
      }
      if (this.state.targetKeys.length === 0) {
        message.error('请至少选择一个导出字段');
        return;
      }
      const names = [];
      for (let i = 0; i < this.state.targetKeys.length; i++) {
        names.push(this.state.infos[this.state.targetKeys[i]].name);
      }
      let divElement = document.getElementById('downloadDiv');
      console.log(config.sqlFormsServer);
      let downloadUrl = config.sqlFormsServer + '/DataObjApi/exportFormData?';
      const token = getToken() != null && getToken() != 'null' ? getToken() : '0000';
      downloadUrl = `${downloadUrl}token=${token}`;
      let param = {
        fields: this.state.targetKeys,
        names: names,
        beanName: this.props.beanName,
        querys: JSON.stringify(qqs),
        orders: JSON.stringify(oos),
        groups: JSON.stringify(ggs),
        voClass: this.props.voClass,
        objId:this.props.objId,
        modelClass: this.props.modelClass,
        preHandleClass: this.props.preHandleClass,
        hqlHandleClass: this.props.hqlHandleClass,

      };
      param = {...param, ...this.props.params || {}}
      this.downloadFile(downloadUrl, param);
    });

  };

  downloadFile(url, params) {
    this.setState({ confirmLoading: true });

    fetch(url, {
      method: 'POST',
      body: FormdataWrapper(params),
    }).then(res => {
      if (res.status != '200') {
        return res.json();
      } else {
        return res.blob();
      }
    }).then(data => {
      if (data instanceof Blob) {
        let a = document.createElement('a');
        let url = window.URL.createObjectURL(data);
        let filename = (this.props.fileName ? this.props.fileName : '导出文件') + '.xlsx';
        a.href = url;
        a.download = filename;
        a.click();
        window.URL.revokeObjectURL(url);
        a = null;
      } else {
        notification.error({
          message: `文件导出错误`,
          description: data.errMsg,
        });
      }

    }).catch(err => {
      notification.error({
        message: `网络请求超时`,
      });
    }).finally(() => {
      this.setState({ confirmLoading: false });
    });
  }

  cancelGroup = () => {
    this.setState({ currentGroupKey: null, groupVisiable: false });
  };
  cancelQuery = () => {
    this.setState({ currentQueryKey: null, queryVisiable: false });
  };
  cancelOrder = () => {
    this.setState({ currentOrderKey: null, orderVisiable: false });
  };
  selectOrder = (e) => {

    this.setState({ currentOrderKey: e });
  };
  selectQuery = (e) => {

    this.setState({ currentQueryKey: e });
  };
  selectGroup = (e) => {

    this.setState({ currentGroupKey: e });
  };

  render() {
    const { form } = this.props;
    const {
      visiable, targetKeys, sourceSelectedKeys, queryVisiable, querys, orders, groups, confirmLoading,
      targetSelectedKeys, mockData, qs, os, gs, currentQueryKey, currentOrderKey, orderVisiable, currentGroupKey, groupVisiable,
    } = this.state;
    return (
      <span>
        <Button shape='round' onClick={this.open}>自定义导出</Button>
        <div id='downloadDiv' style={{ display: 'none' }}></div>
        <Modal
          width={670}
          maskClosable={false}
          destroyOnClose
          title="自定义查询、排序、导出"
          style={{ textAlign: 'center' }}
          visible={visiable}

          onOk={this.export}
          onCancel={this.onCancle}
          confirmLoading={confirmLoading}
        >
          <div style={{ overflowY: 'auto', maxHeight: '500px', height: '500px' }}>
          <div style={{ textAlign: 'left' }}>
              <Button type="primary">新增查询条件</Button>


                <Select style={{ width: 200, paddingRight: '10px' }}
                        value={currentQueryKey}
                        onChange={this.selectQuery}>
                  {qs.map((r) => {
                      return <Option key={r.field}
                                     value={r.field}>
                        {r.name}
                      </Option>;
                    },
                  )}

                </Select>
            {currentQueryKey ?
              <span style={{ paddingLeft: '0' }}>
              <Button type="primary" onClick={this.okQuery}>确定</Button>
                </span>
              : ''}
            <div style={{ height: '12px' }}>

            </div>
            {querys.map((r, i) =>
              <FormItem key={r.name + i}
                        labelCol={{ span: 4 }}
                        wrapperCol={{ span: 20 }}
                        colon={false}
                        label={r.name}>
                {form.getFieldDecorator(i + 'q__' + r.field, {
                  initialValue: { stringX: '=' },
                  rules: [{
                    validator: (rule, value, callback) => {
                      var errors = [];
                      if (value == null) {
                        errors.push(new Error('请输入查询值!', rule.field));

                      } else {
                        if (value.stringX != 'IS NOT NULL' && value.stringX != 'IS NULL' && value.string == null) {
                          errors.push(new Error('请输入查询值!', rule.field));
                        }
                      }
                      callback(errors);

                    },
                  }],
                })(
                  <QueryItem obj={r}
                             key={r.name + i}
                             deleteQuery={this.deleteQuery.bind(this, i)}/>)}
              </FormItem>)
            }
          </div>
          <div style={{ textAlign: 'left', paddingTop: '15px' }}>
              <Button type="primary">新增排序条件</Button>
                <Select style={{ width: 200, paddingRight: '10px' }}
                        value={currentOrderKey}
                        onChange={this.selectOrder}>
                  {os.map((r) => {
                      for (let j = 0; j < orders.length; j++) {
                        if (orders[j].field === r.field) return;

                      }
                      return <Option key={r.field} value={r.field}>{r.name}</Option>;
                    },
                  )}

                </Select>
            {currentOrderKey ?
              <span style={{ paddingLeft: '0' }}>
                 <Button type="primary"  onClick={this.okOrder}>确定</Button>

                  </span>
              : ''}
            <div style={{ height: '12px' }}>

            </div>
            {orders.map((r, i) =>
              <FormItem key={r.name + i}
                        labelCol={{ span: 4 }}
                        wrapperCol={{ span: 20 }}
                        colon={false}
                        label={'按' + r.name}>
                {form.getFieldDecorator(i + 'o__' + r.field, {
                  initialValue: { stringX: 'desc' },
                })(
                  <OrderItem deleteOrder={this.deleteOrder.bind(this, i)}/>)}
              </FormItem>)}
          </div>
            {this.props.voClass ?
              <div style={{ textAlign: 'left', paddingTop: '15px' }}>
                <span style={{ paddingRight: '10px' }}>聚合条件:</span>
                {!groupVisiable ?
                  <Button type="primary"  onClick={this.addGroup}>新增</Button>

                  :
                  <span>
                <Select style={{ width: 100 }}
                        value={currentGroupKey}
                        onChange={this.selectGroup}>
                  {gs.map((r) => {
                      for (var j = 0; j < groups.length; j++) {
                        if (groups[j].field == r.field) return;

                      }
                      return <Option key={r.field}
                                     value={r.field}>
                        {r.name}
                      </Option>;
                    },
                  )}
                </Select>
                    {currentGroupKey ?
                          <Button type="primary"  onClick={this.okGroup}>确定</Button>


                      : ''}
                       <Button type="primary"  onClick={this.cancelGroup}>取消</Button>

              </span>}
                {groups.map((r, i) =>
                  <FormItem key={i + r.name}
                            labelCol={{ span: 5 }}
                            wrapperCol={{ span: 15 }}
                            label={'按' + r.name + '聚合'}>
                    {form.getFieldDecorator(i + 'g__' + r.field)(
                      <Input style={{ display: 'none' }}
                             value=""/>)}
                              <Button type="danger"  onClick={this.deleteGroup.bind(this, i)}>删除</Button>


                  </FormItem>)}
              </div> : ''}
            <Row>
            <Col span={24}
                 style={{ textAlign: 'left', paddingTop: '15px' }}>
              <span style={{ paddingRight: '10px' }}>导出项:</span>
            </Col>
            <Col span={18}>
              <Transfer key={keyX}
                        style={{ textAlign: 'left' }}
                        dataSource={mockData}
                        listStyle={{
                          width: 200,
                          height: 300,
                        }}
                        onSelectChange={this.onSelectChange}
                        selectedKeys={[...sourceSelectedKeys, ...targetSelectedKeys]}
                        rowKey={record => record.key}
                        targetKeys={targetKeys}
                        onChange={this.handleChange}
                        render={this.renderItem}
              />
            </Col>
            <Col span={2}>
              <div style={{ marginTop: 100 }}>
                <Button size="small"
                        disabled={targetSelectedKeys.length === 0}
                        onClick={this.top}>
                  批量置顶
                </Button>
                <Button size="small"
                        style={{ marginTop: 10 }}
                        disabled={targetSelectedKeys.length !== 1}
                        onClick={this.up}>
                  单项上移
                </Button>
                <Button size="small"
                        style={{ marginTop: 10 }}
                        disabled={targetSelectedKeys.length !== 1}
                        onClick={this.down}>
                  单项下移
                </Button>
                <Button size="small"
                        style={{ marginTop: 10 }}
                        disabled={targetSelectedKeys.length === 0}
                        onClick={this.bottom}>
                  批量置底
                </Button>
              </div>
            </Col>

          </Row>
            </div>
        </Modal>
      </span>
    );
  }
}