import React, { PureComponent } from "react";
import { Input, DatePicker, Radio, Select } from "antd";
import moment from "moment";
import styles from "./index.less";
const RadioGroup = Radio.Group;
const OPERATOR = {
  EQ: "EQ",
  LIKE: "LIKE",
  GT: "GT",
  LT: "LT",
  GTE: "GTE",
  LTE: "LTE",
  NOTEQ: "NOTEQ",
  IN: "IN",
  NOTIN: "NOTIN",
  LIKEORIN: "LIKEORIN",
  DELIMIT: "："
};

class Form extends PureComponent {
  constructor(props) {
    super(props);
    const { searchAttrs } = this.props;
    this.state = {};
    searchAttrs.forEach(attr => {
      if (attr.type == "comb" && attr.children) {
        attr.children.forEach(item => {
          this.getDefalutState(item);
        });
      } else {
        this.getDefalutState(attr);
      }
    });
  }
  componentDidMount() {
    this.search();
  }
  getDefalutState(option) {
    switch (option.type) {
      case "text":
        this.state[`${option.key}`] = option.defaultValue || "";
        break;
      case "select":
        this.state[`${option.key}`] = option.defaultValue || "";
        break;
      case "dropSelect":
        this.state[`${option.key}`] = option.defaultValue || "";
        break;
      case "radio":
        this.state[`${option.key}`] = option.defaultValue || "";
        break;
      case "daterange":
        this.state[`${option.key}Start`] = option.startValue || "";
        this.state[`${option.key}End`] = option.endValue || "";
        break;
      case "inputSearch":
        this.state[`${option.key}`] = option.defaultValue || "";
        break;
      default:
        break;
    }
  }
  getSearchParams(searchParams, option) {
    switch (option.type) {
      case "text":
        if (this.state[`${option.key}`]) {
          searchParams[`search_${OPERATOR.LIKE}_${option.key}`] = `%${this.state[`${option.key}`]}%`;
        }
        break;
      case "dropSelect":
        searchParams[`search_${OPERATOR.EQ}_${option.key}`] = this.state[`${option.key}`] || "";
        break;
      case "select":
        searchParams[`search_${OPERATOR.EQ}_${option.key}`] = this.state[`${option.key}`] || "";
        break;
      case "radio":
        searchParams[`search_${OPERATOR.EQ}_${option.key}`] = this.state[`${option.key}`] || "";
        break;
      case "daterange":
        searchParams[`search_${OPERATOR.GTE}_${option.key}_date`] = this.state[`${option.key}Start`];
        searchParams[`search_${OPERATOR.LT}_${option.key}_date`] = this.state[`${option.key}End`];
        break;
      case "inputSearch":
        if (this.state[`${option.key}`]) {
          searchParams[`search_${OPERATOR.LIKE}_${option.key}`] = `%${this.state[`${option.key}`]}%`;
        }
        break;
      default:
        break;
    }
  }
  search(noSeach) {
    const { searchAttrs, setSearchParams  } = this.props;
    const searchParams = {};
    searchAttrs.forEach(attr => {
      if (attr.type == "comb" && attr.children) {
        attr.children.forEach(item => {
          this.getSearchParams(searchParams, item);
        });
      } else {
        this.getSearchParams(searchParams, attr);
      }
    });
    setSearchParams(searchParams, !noSeach);
  }
  // select 值改变
  statusChange(field, status) {
    this.setState(
      {
        [`${field}`]: status
      },
      () => {
        this.search();
      }
    );
  }
  // rangeDate 值改变
  rangePickerChange(field, dates, dateStrings) {
    if (!dates[0]) return;
    this.setState({
      [`${field}`]: dateStrings,
      [`${field}Start`]: Date.parse(dates[0].format()),
      [`${field}End`]: Date.parse(dates[1].format())
    });
  }
  // input,inputSearch, radio 值改变
  fieldChange(field, e) {
    e.preventDefault();
    this.setState({
      [`${field}`]: e.target.value
    });
  }
  selectChange(field, value) {
    this.setState({
      [`${field}`]: value
    });
  }
  // 搜索
  searchHandle(field, value) {
    this.setState(
      {
        [`${field}`]: value
      },
      () => {
        this.search();
      }
    );
  }
  render() {
    const { searchAttrs } = this.props;
    const styleSelectOption = {
      background: "#E14C46",
      borderRadius: 2,
      color: "#fff"
    };
    // Select渲染
    const selectOptionHtml = (option) => {
      if (!(option && option.sourceData && option.sourceData.length > 0)) return null;
      const html = option.sourceData.map(item => {
        const keyValue = option.refId ? item.id : item.code;
        return (
          <span
            className={styles.btn}
            key={item.name}
            onClick={this.statusChange.bind(this, option.key, keyValue)}
            style={this.state[`${option.key}`] == keyValue ? styleSelectOption : null}
          >
            {item.name}
          </span>
        );
      });
      html.unshift(
        <span
          className={styles.btn}
          onClick={this.statusChange.bind(this,  option.key, "")}
          style={this.state[`${option.key}`] == "" ? styleSelectOption : null}
          key={1}
        >
          全部
        </span>
      );
      return html;
    };
    // 拼接下拉框选项
    const dropSelectOptionHtml = option => {
      if (!(option && option.sourceData && option.sourceData.length > 0)) return null;
      const optionHtmls = option.sourceData.map(item => {
        const keyValue = option.refId ? item.id : item.code;
        let keyName = item.name;
        if (option.refName && option.refName.length > 0) {
          keyName = option.refName.reduce((total, val) => total + item[`${val}`], "");
        }
        return (
          <Select.Option key={keyValue} value={keyValue}>
            {keyName}
          </Select.Option>
        );
      });
      return optionHtmls;
    };
    const dropSelectHtml = (option) => {
      return (
        <div className={styles.dropSelectBox}>
          <span className={styles.textLabel}>{option.label ? `${option.label}${OPERATOR.DELIMIT}` : ""}</span>
          <Select
            style={{ width: option.width ? `${option.width}px` : "200px" }}
            value={this.state[`${option.key}`]}
            onChange={this.selectChange.bind(this, option.key)}
          >
            {dropSelectOptionHtml(option)}
          </Select>
        </div>
      );
    };
    const radioOptionHtml = (option) => {
      if (!(option && option.sourceData && option.sourceData.length > 0)) return null;
      const html = option.sourceData.map(item => {
        const keyValue = option.refId ? item.id : item.code;
        return (
          <Radio value={keyValue}>{item.name}</Radio>
        );
      });
      return html;
    };
    const appendFormOptionHtml = (option) => {
      switch (option.type) {
        case "text":
          return (
            <div className={styles.textBox}>
              <span className={styles.textLabel}>{option.label ? `${option.label}${OPERATOR.DELIMIT}` : ""}</span>
              <div className={styles.textVal}>
                <Input
                  placeholder={option.placeholder}
                  style={{ width: option.width ? option.width : "200" }}
                  onChange={this.fieldChange.bind(this, option.key)}
                  value={this.state[`${option.key}`]}
                />
              </div>
            </div>
          );
        case "select":
          return (
            <div>{selectOptionHtml(option)}</div>
          );
        case "dropSelect":
          return (
            dropSelectHtml(option)
          );
        case "radio":
          const radioValue = this.state[`${option.key}`] || "";
          return (
            <RadioGroup onChange={this.fieldChange.bind(this, option.key)} value={radioValue}>
              {radioOptionHtml(option)}
            </RadioGroup>
          );
        case "daterange":
          const startDate = this.state[`${option.key}Start`] || "";
          const endDate = this.state[`${option.key}End`] || "";
          return (
            <DatePicker.RangePicker
              defaultValue={startDate && [moment(startDate), endDate && moment(endDate)]}
              className={styles.searchData}
              onChange={this.rangePickerChange.bind(this, option.key)}
            />
          );
        case "inputSearch":
          return (
            <div className={styles.searchBox}>
              <Input.Search
                placeholder={option.placeholder}
                enterButton={option.enterButton}
                style={{ width: 280 }}
                onChange={this.fieldChange.bind(this, option.key)}
                value={this.state[`${option.key}`]}
                onSearch={this.searchHandle.bind(this, option.key)}
              />
            </div>
          );
        default:
          return null;
      }
    };
    const appendFormHtml = (searchAttrs) => {
      const optionHtmls = searchAttrs.map(attr => {
        const style = {};
        if (attr.labelWidth) {
          style.width = attr.labelWidth;
        }
        if (attr.type == "comb" && attr.children) {
          return (
            <div className={styles.searchItem}>
              <span className={styles.searchName} style={style}>{attr.label}{OPERATOR.DELIMIT}</span>
              <div className={styles.searchVal}>
                {
                  attr.children.map(option => {
                    return appendFormOptionHtml(option);
                  })
                }
              </div>
            </div>
          );
        } else {
          return (
            <div className={styles.searchItem}>
              <span className={styles.searchName} style={style}>{attr.label}{OPERATOR.DELIMIT}</span>
              <div className={styles.searchVal}>
                {appendFormOptionHtml(attr)}
              </div>
            </div>
          );
        }
      });
      return optionHtmls;
    };
    return (
      <div className={styles.FromBox}>
        {appendFormHtml(searchAttrs)}
      </div>
    );
  }
}
export default Form;
