import React, { Component } from 'react';
import moment from 'moment';
import { Form, Button, Switch, DatePicker, Input, InputNumber, Modal, Alert } from 'antd';
import Select from '../../components/Select';
import Multiple from '../../components/Multiple';
import Radio from '../../components/Radio';
import TreeSelect from '../../components/TreeSelect';
import './index.less';

const { TextArea } = Input;

class FormLayout extends Component {
  constructor(props) {
    super(props);
    this.state = { show: !!props.modal, loading: false, err: '' };
  }

  onConfirm() {
    this.props.form.validateFields((err, fieldsValue) => {
      if (err) {
        return;
      }
      if (this.props.onConfirm && this.props.modal) {
        this.setState({ loading: true });
        this.props
          .onConfirm(fieldsValue)
          .then(() => {
            this.setState({ loading: false });
            this.onCancel();
          })
          .catch(e => {
            this.setState({ loading: false, err: e.message });
          });
      } else {
        this.onCancel();
      }
    });
  }

  onCancel() {
    if (this.props.modal) this.setState({ show: false });
    if (this.props.onCancel) this.props.onCancel();
  }

  getItem(item) {
    switch (item.type) {
      case 'tree':
        return (
          <TreeSelect
            {...item}
            className={item.class}
            disabled={!!item.disabled}
            placeholder={item.placeholder}
            isNode={item.isNode}
            treeDefaultExpandAll
            treeData={item.tree}
            loadData={item.loadData}
            initData={item.initData}
            ignore={item.ignore}
          />
        );
      case 'radio':
        return <Radio {...item} className={item.class} select={item.select} disabled={!!item.disabled} />;
      case 'select':
        return (
          <Select
            {...item}
            className={item.class}
            select={item.select}
            placeholder={item.placeholder}
            disabled={!!item.disabled}
          />
        );
      case 'multiple':
        return (
          <Multiple
            {...item}
            className={item.class}
            select={item.select}
            placeholder={item.placeholder}
            disabled={!!item.disabled}
          />
        );
      case 'render':
        return item.render(item, this.props.data, this.props.form);
      case 'textarea':
        return <TextArea {...item} autosize className={item.class} placeholder={item.placeholder} disabled={!!item.disabled} />;
      case 'password':
      case 'input':
        return (
          <Input
            {...item}
            className={item.class}
            placeholder={item.placeholder}
            readOnly={!!item.readOnly}
            disabled={!!item.disabled}
          />
        );
      case 'number':
        return (
          <InputNumber
            {...item}
            className={item.class}
            placeholder={item.placeholder}
            readOnly={!!item.readOnly}
            disabled={!!item.disabled}
          />
        );
      case 'switch':
        return <Switch {...item} className={item.class} disabled={!!item.disabled} />;
      case 'date':
        return <DatePicker {...item} className={item.class} placeholder={item.placeholder} disabled={!!item.disabled} />;
      case 'hidden':
        return <Input type="hidden" />;
      // case 'image':
      // case 'logo':
      // case 'file':
      //   return (
      //     <FileUpload
      //       {...item}
      //       onUpload={this.props.onUpload}
      //       title={item.name}
      //       onError={err => {
      //         this.props.form.setFields({ [item.key]: { value: '', errors: [err] } });
      //       }}
      //     />
      //   );
      default:
        return <div />;
    }
  }

  formatData(data, item) {
    switch (item.type) {
      case 'date':
        return moment(data[item.key]);
      default:
        return data[item.key];
    }
  }

  getForm() {
    const {
      modal,
      itemList = [],
      confirmText = '确定',
      cancelText = '取消',
      data = {},
      layoutCol = { labelCol: { span: 4 }, wrapperCol: { span: 20 } },
    } = this.props;
    const { getFieldDecorator } = this.props.form;
    return (
      <Form>
        {itemList.map((item, index) => {
          if (item.hidden) return '';
          const defaultOption = { rules: [] };
          const option = item.option ? Object.assign(defaultOption, item.option) : defaultOption;
          if (data && data[item.key]) {
            option.initialValue = this.formatData(data, item);
          }
          if (item.required) {
            option.rules.push({ required: true, message: item.placeholder });
          }
          if (item.type === 'hidden') {
            return <div>{getFieldDecorator(item.key, option)(this.getItem(item, option))}</div>;
          }
          return (
            <Form.Item {...layoutCol} key={index} label={item.name}>
              {getFieldDecorator(item.key, option)(this.getItem(item, option))}
            </Form.Item>
          );
        })}
        {!modal && (
          <Form.Item wrapperCol={{ offset: 6 }}>
            <Button type="primary" onClick={() => this.onConfirm()} style={{ marginRight: 20 }}>
              {confirmText}
            </Button>
            <Button onClick={() => this.onCancel()}>{cancelText}</Button>
          </Form.Item>
        )}
      </Form>
    );
  }

  render() {
    const { modal, title, confirmText = '确定', cancelText = '取消' } = this.props;
    const { show, loading, err } = this.state;
    return modal ? (
      <Modal
        title={title}
        visible={show}
        className="form-layout"
        okText={confirmText}
        cancelText={cancelText}
        confirmLoading={loading}
        onOk={() => this.onConfirm()}
        onCancel={() => this.onCancel()}
      >
        {err && <Alert type="error" showIcon message={err} closable onClose={() => this.setState({ err: '' })} />}
        {this.getForm()}
      </Modal>
    ) : (<div className="form-layout">{this.getForm()}</div>);
  }
}

export default Form.create()(FormLayout);
